[ccan] [PATCH 6/9] bytestring: Implement bytestring_spn()

David Gibson david at gibson.dropbear.id.au
Mon Jul 28 19:59:54 EST 2014


Add bytestring_spn() and bytestring_cspn() functions which, in analogy to
strspn() and strcspn() return the lengths of initial sub-bytestrings which
either contain only a given set of bytes, or anything except a given set
of bytes.

Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
 ccan/bytestring/bytestring.c | 26 ++++++++++++++++++++++++++
 ccan/bytestring/bytestring.h | 20 ++++++++++++++++++++
 ccan/bytestring/test/run.c   | 14 +++++++++++++-
 3 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 ccan/bytestring/bytestring.c

diff --git a/ccan/bytestring/bytestring.c b/ccan/bytestring/bytestring.c
new file mode 100644
index 0000000..2e205b7
--- /dev/null
+++ b/ccan/bytestring/bytestring.c
@@ -0,0 +1,26 @@
+/* Licensed under LGPLv2+ - see LICENSE file for details */
+#include "config.h"
+
+#include <ccan/bytestring/bytestring.h>
+
+size_t bytestring_spn(struct bytestring s, struct bytestring accept)
+{
+	size_t i;
+
+	for (i = 0; i < s.len; i++)
+		if (bytestring_chr(accept, s.ptr[i]) == NULL)
+			return i;
+
+	return s.len;
+}
+
+size_t bytestring_cspn(struct bytestring s, struct bytestring reject)
+{
+	size_t i;
+
+	for (i = 0; i < s.len; i++)
+		if (bytestring_chr(reject, s.ptr[i]) != NULL)
+			return i;
+
+	return s.len;
+}
diff --git a/ccan/bytestring/bytestring.h b/ccan/bytestring/bytestring.h
index d74666a..e93c634 100644
--- a/ccan/bytestring/bytestring.h
+++ b/ccan/bytestring/bytestring.h
@@ -181,4 +181,24 @@ static inline struct bytestring bytestring_bytestring(struct bytestring haystack
 		return bytestring_NULL;
 }
 
+/**
+ * bytestring_spn - search a bytestring for a set of bytes
+ * @s: a bytestring
+ * @accept: a bytestring containing a set of bytes to accept
+ *
+ * Returns the length, in bytes, of the initial segment of @s which
+ * consists entirely of characters in @accept.
+ */
+size_t bytestring_spn(struct bytestring s, struct bytestring accept);
+
+/**
+ * bytestring_cspn - search a bytestring for a set of bytes (complemented)
+ * @s: a bytestring
+ * @reject: a bytestring containing a set of bytes to reject
+ *
+ * Returns the length, in bytes, of the initial segment of @s which
+ * consists entirely of characters not in @reject.
+ */
+size_t bytestring_cspn(struct bytestring s, struct bytestring reject);
+
 #endif /* CCAN_BYTESTRING_H_ */
diff --git a/ccan/bytestring/test/run.c b/ccan/bytestring/test/run.c
index 5ae99f8..7e7b2f0 100644
--- a/ccan/bytestring/test/run.c
+++ b/ccan/bytestring/test/run.c
@@ -3,6 +3,8 @@
 #include <ccan/bytestring/bytestring.h>
 #include <ccan/tap/tap.h>
 
+#include <ccan/bytestring/bytestring.c>
+
 #define TEST_STRING	"test string"
 #define TEST_STRING_2	"abc\0def"
 
@@ -14,7 +16,7 @@ int main(void)
 	struct bytestring bs, bs1, bs2, bs3, bs4, bs5, bs6;
 
 	/* This is how many tests you plan to run */
-	plan_tests(40);
+	plan_tests(46);
 
 	bs = bytestring(str1, sizeof(str1) - 1);
 	ok1(bs.ptr == str1);
@@ -80,6 +82,16 @@ int main(void)
 	ok1(bytestring_eq(bytestring_bytestring(bs2, bytestring_NULL),
 			  bytestring(bs2.ptr, 0)));
 
+
+	ok1(bytestring_spn(bs1, BYTESTRING("est")) == 4);
+	ok1(bytestring_cspn(bs1, BYTESTRING(" ")) == 4);
+
+	ok1(bytestring_spn(bs2, BYTESTRING("z")) == 0);
+	ok1(bytestring_cspn(bs2, BYTESTRING("\0")) == 3);
+
+	ok1(bytestring_spn(bs1, BYTESTRING("eginrst ")) == bs1.len);
+	ok1(bytestring_cspn(bs2, BYTESTRING("z")) == bs2.len);
+
 	/* This exits depending on whether all tests passed */
 	return exit_status();
 }
-- 
1.9.3



More information about the ccan mailing list