[ccan] [PATCH 5/9] bytestring: Implement bytestring_bytestring()

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


Add a bytestring_bytestring() function which, in analogy with strstr() and
memmem() finds one bytestring within another.

Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
 ccan/bytestring/_info                            |  1 +
 ccan/bytestring/bytestring.h                     | 22 ++++++++++++++++++++++
 ccan/bytestring/test/compile_fail-BYTESTRING-2.c |  2 ++
 ccan/bytestring/test/compile_fail-BYTESTRING.c   |  2 ++
 ccan/bytestring/test/run.c                       | 19 +++++++++++++++++--
 5 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/ccan/bytestring/_info b/ccan/bytestring/_info
index c2aab2d..24d2fad 100644
--- a/ccan/bytestring/_info
+++ b/ccan/bytestring/_info
@@ -35,6 +35,7 @@ int main(int argc, char *argv[])
 
 	if (strcmp(argv[1], "depends") == 0) {
 		printf("ccan/array_size\n");
+		printf("ccan/memmem\n");
 		return 0;
 	}
 
diff --git a/ccan/bytestring/bytestring.h b/ccan/bytestring/bytestring.h
index ca5afd9..d74666a 100644
--- a/ccan/bytestring/bytestring.h
+++ b/ccan/bytestring/bytestring.h
@@ -2,12 +2,15 @@
 #ifndef CCAN_BYTESTRING_H_
 #define CCAN_BYTESTRING_H_
 
+#include "config.h"
+
 #include <stdlib.h>
 #include <string.h>
 #include <stdbool.h>
 #include <assert.h>
 
 #include <ccan/array_size/array_size.h>
+#include <ccan/memmem/memmem.h>
 
 struct bytestring {
 	const char *ptr;
@@ -159,4 +162,23 @@ static inline const char *bytestring_chr(struct bytestring haystack,
 	return memchr(haystack.ptr, needle, haystack.len);
 }
 
+/**
+ * bytestring_bytestring - search for a bytestring in another bytestring
+ * @haystack, @needle: bytestrings
+ *
+ * Returns a bytestring corresponding to the first occurrence of
+ * @needle in @haystack, or bytestring_NULL if @needle is not found
+ * within @haystack.
+ */
+static inline struct bytestring bytestring_bytestring(struct bytestring haystack,
+						      struct bytestring needle)
+{
+	const char *p = memmem(haystack.ptr, haystack.len,
+			       needle.ptr, needle.len);
+	if (p)
+		return bytestring(p, needle.len);
+	else
+		return bytestring_NULL;
+}
+
 #endif /* CCAN_BYTESTRING_H_ */
diff --git a/ccan/bytestring/test/compile_fail-BYTESTRING-2.c b/ccan/bytestring/test/compile_fail-BYTESTRING-2.c
index 7ab06f8..3c62f94 100644
--- a/ccan/bytestring/test/compile_fail-BYTESTRING-2.c
+++ b/ccan/bytestring/test/compile_fail-BYTESTRING-2.c
@@ -1,3 +1,5 @@
+#include "config.h"
+
 #include <stdio.h>
 
 #include <ccan/bytestring/bytestring.h>
diff --git a/ccan/bytestring/test/compile_fail-BYTESTRING.c b/ccan/bytestring/test/compile_fail-BYTESTRING.c
index f3fcb20..1e88575 100644
--- a/ccan/bytestring/test/compile_fail-BYTESTRING.c
+++ b/ccan/bytestring/test/compile_fail-BYTESTRING.c
@@ -1,3 +1,5 @@
+#include "config.h"
+
 #include <stdio.h>
 
 #include <ccan/bytestring/bytestring.h>
diff --git a/ccan/bytestring/test/run.c b/ccan/bytestring/test/run.c
index b0d2ce6..5ae99f8 100644
--- a/ccan/bytestring/test/run.c
+++ b/ccan/bytestring/test/run.c
@@ -1,3 +1,5 @@
+#include "config.h"
+
 #include <ccan/bytestring/bytestring.h>
 #include <ccan/tap/tap.h>
 
@@ -9,10 +11,10 @@ const char *str2 = TEST_STRING;
 
 int main(void)
 {
-	struct bytestring bs, bs1, bs2, bs3, bs4, bs5;
+	struct bytestring bs, bs1, bs2, bs3, bs4, bs5, bs6;
 
 	/* This is how many tests you plan to run */
-	plan_tests(35);
+	plan_tests(40);
 
 	bs = bytestring(str1, sizeof(str1) - 1);
 	ok1(bs.ptr == str1);
@@ -65,6 +67,19 @@ int main(void)
 	ok1(bytestring_chr(bs2, 'f') == (bs2.ptr + 6));
 	ok1(bytestring_chr(bs2, 'q') == NULL);
 
+	bs6 = BYTESTRING("string");
+	ok1(bytestring_eq(bytestring_bytestring(bs1, bs6),
+			  bytestring(bs1.ptr + 5, 6)));
+	bs6 = BYTESTRING("c\0d");
+	ok1(bytestring_eq(bytestring_bytestring(bs2, bs6),
+			  bytestring(bs2.ptr + 2, 3)));
+	bs6 = BYTESTRING("c\0e");
+	ok1(bytestring_bytestring(bs2, bs6).ptr == NULL);
+	ok1(bytestring_eq(bytestring_bytestring(bs1, bytestring_NULL),
+			  bytestring(bs1.ptr, 0)));
+	ok1(bytestring_eq(bytestring_bytestring(bs2, bytestring_NULL),
+			  bytestring(bs2.ptr, 0)));
+
 	/* This exits depending on whether all tests passed */
 	return exit_status();
 }
-- 
1.9.3



More information about the ccan mailing list