]> git.ozlabs.org Git - ccan/blob - ccan/bytestring/bytestring.c
bytestring: Split bytestrings by a character delimiter
[ccan] / ccan / bytestring / bytestring.c
1 /* Licensed under LGPLv2+ - see LICENSE file for details */
2 #include "config.h"
3
4 #include <ccan/bytestring/bytestring.h>
5
6 size_t bytestring_spn(struct bytestring s, struct bytestring accept)
7 {
8         size_t i;
9
10         for (i = 0; i < s.len; i++)
11                 if (bytestring_index(accept, s.ptr[i]) == NULL)
12                         return i;
13
14         return s.len;
15 }
16
17 size_t bytestring_cspn(struct bytestring s, struct bytestring reject)
18 {
19         size_t i;
20
21         for (i = 0; i < s.len; i++)
22                 if (bytestring_index(reject, s.ptr[i]) != NULL)
23                         return i;
24
25         return s.len;
26 }
27
28 static struct bytestring _splitchr(struct bytestring whole, char delim,
29                                    size_t start)
30 {
31         const char *p;
32
33         assert(start <= whole.len);
34
35         /* Check this first, in case memchr() is not safe with zero length */
36         if (start == whole.len)
37                 return bytestring(whole.ptr + start, 0);
38
39         p = memchr(whole.ptr + start, delim, whole.len - start);
40         if (p)
41                 return bytestring_slice(whole, start, p - whole.ptr);
42         else
43                 return bytestring_slice(whole, start, whole.len);
44 }
45
46 struct bytestring bytestring_splitchr_first(struct bytestring whole,
47                                             char delim)
48 {
49         if (whole.len == 0)
50                 return bytestring_NULL;
51
52         return _splitchr(whole, delim, 0);
53 }
54
55 struct bytestring bytestring_splitchr_next(struct bytestring whole,
56                                            char delim, struct bytestring prev)
57 {
58         if (!prev.ptr)
59                 return bytestring_NULL;
60
61         /* prev has to be a substring of whole */
62         assert(prev.ptr >= whole.ptr);
63
64         if ((prev.ptr + prev.len) == (whole.ptr + whole.len))
65                 return bytestring_NULL;
66
67         return _splitchr(whole, delim, (prev.ptr - whole.ptr) + prev.len + 1);
68 }