Commit b529270b authored by David Gibson's avatar David Gibson

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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent f1e31c66
/* 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_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;
}
...@@ -200,4 +200,24 @@ static inline struct bytestring bytestring_bytestring(struct bytestring haystack ...@@ -200,4 +200,24 @@ static inline struct bytestring bytestring_bytestring(struct bytestring haystack
return bytestring_NULL; 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_ */ #endif /* CCAN_BYTESTRING_H_ */
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <ccan/bytestring/bytestring.h> #include <ccan/bytestring/bytestring.h>
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
#include <ccan/bytestring/bytestring.c>
#define TEST_STRING "test string" #define TEST_STRING "test string"
#define TEST_STRING_2 "abc\0def" #define TEST_STRING_2 "abc\0def"
...@@ -14,7 +16,7 @@ int main(void) ...@@ -14,7 +16,7 @@ int main(void)
struct bytestring bs, bs1, bs2, bs3, bs4, bs5, bs6; struct bytestring bs, bs1, bs2, bs3, bs4, bs5, bs6;
/* This is how many tests you plan to run */ /* This is how many tests you plan to run */
plan_tests(47); plan_tests(53);
bs = bytestring(str1, sizeof(str1) - 1); bs = bytestring(str1, sizeof(str1) - 1);
ok1(bs.ptr == str1); ok1(bs.ptr == str1);
...@@ -88,6 +90,16 @@ int main(void) ...@@ -88,6 +90,16 @@ int main(void)
ok1(bytestring_eq(bytestring_bytestring(bs2, bytestring_NULL), ok1(bytestring_eq(bytestring_bytestring(bs2, bytestring_NULL),
bytestring(bs2.ptr, 0))); 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 */ /* This exits depending on whether all tests passed */
return exit_status(); return exit_status();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment