From b529270bf1ce198a310046d83c8e5d9356dcfe15 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 22 Oct 2014 15:37:22 +0200 Subject: [PATCH] bytestring: Implement bytestring_spn() and bytestring_cspn() 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 --- 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 00000000..69e2b32b --- /dev/null +++ b/ccan/bytestring/bytestring.c @@ -0,0 +1,26 @@ +/* Licensed under LGPLv2+ - see LICENSE file for details */ +#include "config.h" + +#include + +size_t bytestring_spn(struct bytestring s, struct bytestring accept) +{ + size_t i; + + for (i = 0; i < s.len; i++) + if (bytestring_index(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_index(reject, s.ptr[i]) != NULL) + return i; + + return s.len; +} diff --git a/ccan/bytestring/bytestring.h b/ccan/bytestring/bytestring.h index 62141bea..34d81af2 100644 --- a/ccan/bytestring/bytestring.h +++ b/ccan/bytestring/bytestring.h @@ -200,4 +200,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 ef149c56..23415df5 100644 --- a/ccan/bytestring/test/run.c +++ b/ccan/bytestring/test/run.c @@ -3,6 +3,8 @@ #include #include +#include + #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(47); + plan_tests(53); bs = bytestring(str1, sizeof(str1) - 1); ok1(bs.ptr == str1); @@ -88,6 +90,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(); } -- 2.39.2