]> git.ozlabs.org Git - ccan/blob - ccan/bytestring/bytestring.c
ccanlint: Move ccanlint test options from _info comments to code
[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 }
69
70 static struct bytestring _splitchrs(struct bytestring whole,
71                                     struct bytestring delim, size_t start)
72 {
73         struct bytestring remainder;
74         size_t n;
75
76         assert(start <= whole.len);
77
78         remainder = bytestring_slice(whole, start, whole.len);
79         n = bytestring_cspn(remainder, delim);
80         return bytestring_slice(whole, start, start + n);
81 }
82
83 struct bytestring bytestring_splitchrs_first(struct bytestring whole,
84                                              struct bytestring delim)
85 {
86         if (whole.len == 0)
87                 return bytestring_NULL;
88
89         return _splitchrs(whole, delim, 0);
90 }
91
92 struct bytestring bytestring_splitchrs_next(struct bytestring whole,
93                                             struct bytestring delim,
94                                             struct bytestring prev)
95 {
96         if (!prev.ptr)
97                 return bytestring_NULL;
98
99         /* prev has to be a substring of whole */
100         assert(prev.ptr >= whole.ptr);
101
102         if ((prev.ptr + prev.len) == (whole.ptr + whole.len))
103                 return bytestring_NULL;
104
105         return _splitchrs(whole, delim, (prev.ptr - whole.ptr) + prev.len + 1);
106 }
107
108 static struct bytestring _splitstr(struct bytestring whole,
109                                    struct bytestring delim, size_t start)
110 {
111         struct bytestring remainder, nextdelim;
112
113         assert(start <= whole.len);
114
115         remainder = bytestring_slice(whole, start, whole.len);
116         nextdelim = bytestring_bytestring(remainder, delim);
117         if (nextdelim.ptr)
118                 return bytestring_slice(whole, start,
119                                         nextdelim.ptr - whole.ptr);
120         else
121                 return remainder;
122 }
123
124 struct bytestring bytestring_splitstr_first(struct bytestring whole,
125                                              struct bytestring delim)
126 {
127         if (whole.len == 0)
128                 return bytestring_NULL;
129
130         return _splitstr(whole, delim, 0);
131 }
132
133 struct bytestring bytestring_splitstr_next(struct bytestring whole,
134                                            struct bytestring delim,
135                                            struct bytestring prev)
136 {
137         if (!prev.ptr)
138                 return bytestring_NULL;
139
140         /* prev has to be a substring of whole */
141         assert(prev.ptr >= whole.ptr);
142
143         if ((prev.ptr + prev.len) == (whole.ptr + whole.len))
144                 return bytestring_NULL;
145
146         return _splitstr(whole, delim,
147                          (prev.ptr - whole.ptr) + prev.len + delim.len);
148 }