GCC Code Coverage Report


Directory: src/gate/
File: src/gate/strings.c
Date: 2026-02-03 22:06:38
Exec Total Coverage
Lines: 1381 1862 74.2%
Functions: 194 250 77.6%
Branches: 709 1438 49.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/strings.h"
30 #include "gate/memalloc.h"
31 #include "gate/mathematics.h"
32 #include "gate/results.h"
33 #include "gate/debugging.h"
34
35
36 #define U8_TERM ((gate_char8_t)(0x80))
37 #define U8_2B ((gate_char8_t)(0xC0))
38 #define U8_3B ((gate_char8_t)(0xE0))
39 #define U8_4B ((gate_char8_t)(0xF0))
40
41 #define U32_07 ((gate_char32_t)(0x07))
42 #define U32_0F ((gate_char32_t)(0x0F))
43 #define U32_3F ((gate_char32_t)(0x3F))
44
45 #define U16_1 ((gate_char16_t)(0xD800))
46 #define U16_2 ((gate_char16_t)(0xDC00))
47 #define U16_M ((gate_char16_t)(0x03FF))
48
49
50 1189 gate_size_t gate_char_read_utf8(gate_char8_t const* src, gate_size_t srclen, gate_char32_t* dst)
51 {
52
1/2
✓ Branch 0 taken 1189 times.
✗ Branch 1 not taken.
1189 if (srclen > 0)
53 {
54
1/2
✓ Branch 0 taken 1189 times.
✗ Branch 1 not taken.
1189 if ((*src & 0x80) == 0)
55 {
56 1189 *dst = (gate_char32_t)*src;
57 1189 return 1;
58 }
59 else if (((src[0] & 0xE0) == 0xC0) && (srclen > 1) && ((src[1] & 0xC0) == 0x80))
60 {
61 *dst = (gate_char32_t)((gate_char32_t)(src[0] & 0x1F) << 6) | (gate_char32_t)(src[1] & 0x3F);
62 return 2;
63 }
64 else if (((src[0] & 0xF0) == 0xE0) && (srclen > 2) && ((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80))
65 {
66 *dst = (gate_char32_t)((gate_char32_t)(src[0] & 0x0F) << 12) | (gate_char32_t)((gate_char32_t)(src[1] & 0x3F) << 6) | (gate_char32_t)(src[2] & 0x3F);
67 return 3;
68 }
69 else if (((src[0] & 0xF8) == 0xF0) && (srclen > 3) && ((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80) && ((src[3] & 0xC0) == 0x80))
70 {
71 *dst = (gate_char32_t)((gate_char32_t)(src[0] & 0x07) << 18) | (gate_char32_t)((gate_char32_t)(src[1] & 0x3F) << 12) | (gate_char32_t)((gate_char32_t)(src[2] & 0x3F) << 6) | (gate_char32_t)(src[3] & 0x3F);
72 return 4;
73 }
74 }
75 return 0;
76 }
77 64 gate_size_t gate_char_read_utf16(gate_char16_t const* src, gate_size_t srclen, gate_char32_t* dst)
78 {
79
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 if (srclen > 0)
80 {
81
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
64 if (((src[0] & U16_1) == U16_1) && (srclen > 1) && ((src[1] & U16_2) == U16_2))
82 {
83 *dst = ((gate_char32_t)(src[0] & U16_M) << 10) | (gate_char32_t)(src[1] & U16_M);
84 *dst += 0x10000;
85 return 2;
86 }
87 else
88 {
89 64 *dst = (gate_char32_t)(src[0]);
90 64 return 1;
91 }
92 }
93 return 0;
94 }
95 47 gate_size_t gate_char_read_utf32(gate_char32_t const* src, gate_size_t srclen, gate_char32_t* dst)
96 {
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
47 if (srclen < 1)
98 {
99 return 0;
100 }
101 47 *dst = *src;
102 47 return 1;
103 }
104 184 gate_size_t gate_char_write_utf8(gate_char32_t src, gate_char8_t* dst, gate_size_t dstlen)
105 {
106
1/2
✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
184 if (src < 0x80)
107 {
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 if (dstlen == 0)
109 {
110 return 0;
111 }
112 184 dst[0] = (gate_char8_t)src;
113 184 return 1;
114 }
115 else if (src < 0x800)
116 {
117 if (dstlen < 2)
118 {
119 return 0;
120 }
121 dst[0] = U8_2B | (gate_char8_t)(src >> 6);
122 dst[1] = U8_TERM | (gate_char8_t)(src & U32_3F);
123 return 2;
124 }
125 else if (src < 0x010000)
126 {
127 if (dstlen < 3)
128 {
129 return 0;
130 }
131 dst[0] = U8_3B | (gate_char8_t)((src >> 12) & U32_0F);
132 dst[1] = U8_TERM | (gate_char8_t)((src >> 6) & U32_3F);
133 dst[2] = U8_TERM | (gate_char8_t)(src & U32_3F);
134 return 3;
135 }
136 else if (src < 0x0110000)
137 {
138 if (dstlen < 4)
139 {
140 return 0;
141 }
142 dst[0] = U8_4B | (gate_char8_t)(((src >> 18) & U32_07));
143 dst[1] = U8_TERM | (gate_char8_t)(((src >> 12) & U32_3F));
144 dst[2] = U8_TERM | (gate_char8_t)(((src >> 6) & U32_3F));
145 dst[3] = U8_TERM | (gate_char8_t)((src & U32_3F));
146 return 4;
147 }
148 return 0;
149 }
150 1098 gate_size_t gate_char_write_utf16(gate_char32_t src, gate_char16_t* dst, gate_size_t dstlen)
151 {
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1098 times.
1098 if (src > 0x10000)
153 {
154 if (dstlen < 2)
155 {
156 return 0;
157 }
158 src -= 0x10000;
159 dst[0] = (gate_char16_t)(src >> 10) | U16_1;
160 dst[1] = (gate_char16_t)(src & (gate_char32_t)(U16_M)) | U16_2;
161 return 2;
162 }
163 else
164 {
165 1098 dst[0] = (gate_char16_t)src;
166 1098 return 1;
167 }
168
169 }
170 6 gate_size_t gate_char_write_utf32(gate_char32_t src, gate_char32_t* dst, gate_size_t dstlen)
171 {
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (dstlen < 1)
173 {
174 return 0;
175 }
176 6 *dst = src;
177 6 return 1;
178 }
179
180
181
182
183 #define UTF_CONVERT(reader, writer, src, srclen, dst, dstlen) \
184 gate_size_t ret = 0; \
185 gate_size_t decoded; \
186 gate_size_t encoded; \
187 gate_char32_t u32; \
188 while((srclen != 0) && (dstlen != 0)) \
189 { \
190 decoded = reader(src, srclen, &u32); \
191 if(decoded == 0) \
192 { \
193 break; \
194 } \
195 src += decoded; \
196 srclen -= decoded; \
197 encoded = writer(u32, dst, dstlen); \
198 if(encoded == 0) \
199 { \
200 break; \
201 } \
202 dst += encoded; \
203 dstlen -= encoded; \
204 ret += encoded; \
205 } \
206 if(dstlen != 0) \
207 { \
208 *dst = 0; \
209 } \
210 return ret;
211
212 3 gate_size_t gate_str_utf8_2_utf16(gate_char8_t const* src, gate_size_t srclen, gate_char16_t* dst, gate_size_t dstlen)
213 {
214
7/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1045 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1045 times.
✓ Branch 6 taken 1045 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 1045 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 1 times.
1048 UTF_CONVERT(gate_char_read_utf8, gate_char_write_utf16, src, srclen, dst, dstlen);
215 }
216 1 gate_size_t gate_str_utf8_2_utf32(gate_char8_t const* src, gate_size_t srclen, gate_char32_t* dst, gate_size_t dstlen)
217 {
218
6/10
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
6 UTF_CONVERT(gate_char_read_utf8, gate_char_write_utf32, src, srclen, dst, dstlen);
219 }
220 gate_size_t gate_str_utf16_2_utf8(gate_char16_t const* src, gate_size_t srclen, gate_char8_t* dst, gate_size_t dstlen)
221 {
222 UTF_CONVERT(gate_char_read_utf16, gate_char_write_utf8, src, srclen, dst, dstlen);
223 }
224 gate_size_t gate_str_utf16_2_utf32(gate_char16_t const* src, gate_size_t srclen, gate_char32_t* dst, gate_size_t dstlen)
225 {
226 UTF_CONVERT(gate_char_read_utf16, gate_char_write_utf32, src, srclen, dst, dstlen);
227 }
228 11 gate_size_t gate_str_utf32_2_utf8(gate_char32_t const* src, gate_size_t srclen, gate_char8_t* dst, gate_size_t dstlen)
229 {
230
6/10
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 45 times.
✓ Branch 7 taken 11 times.
✓ Branch 8 taken 45 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
56 UTF_CONVERT(gate_char_read_utf32, gate_char_write_utf8, src, srclen, dst, dstlen);
231 }
232 gate_size_t gate_str_utf32_2_utf16(gate_char32_t const* src, gate_size_t srclen, gate_char16_t* dst, gate_size_t dstlen)
233 {
234 UTF_CONVERT(gate_char_read_utf32, gate_char_write_utf16, src, srclen, dst, dstlen);
235 }
236
237
238 8129 int gate_char_lowercase(int chr)
239 {
240
4/4
✓ Branch 0 taken 7459 times.
✓ Branch 1 taken 670 times.
✓ Branch 2 taken 134 times.
✓ Branch 3 taken 7325 times.
8129 if ((chr >= 'A') && (chr <= 'Z'))
241 {
242 134 return chr + ('a' - 'A');
243 }
244 7995 return chr;
245 }
246 7 int gate_char_uppercase(int chr)
247 {
248
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 if ((chr >= 'a') && (chr <= 'z'))
249 {
250 7 return chr - ('a' - 'A');
251 }
252 return chr;
253 }
254 28 gate_bool_t gate_char_is_digit(int chr)
255 {
256
4/4
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 3 times.
28 if ((chr >= '0') && (chr <= '9'))
257 {
258 22 return true;
259 }
260 else
261 {
262 6 return false;
263 }
264 }
265 140 gate_bool_t gate_char_is_whitespace(int chr)
266 {
267 static char const ws[] = GATE_STR_WHITESPACES;
268 gate_size_t ndx;
269
2/2
✓ Branch 0 taken 482 times.
✓ Branch 1 taken 114 times.
596 for (ndx = 0; ndx != GATE_STR_WHITESPACES_LENGTH; ++ndx)
270 {
271
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 456 times.
482 if (chr == ws[ndx])
272 {
273 26 return true;
274 }
275 }
276 114 return false;
277 }
278
279 #define GATE_STR_CHAR_POS(str, len, find, startat) \
280 gate_size_t ret; \
281 if((str == NULL) || (len == 0) || (startat >= len)) \
282 { \
283 return GATE_STR_NPOS; \
284 } \
285 ret = startat; \
286 str += startat; \
287 len -= startat; \
288 while(len-- > 0) \
289 { \
290 if(*str == find) \
291 { \
292 return ret; \
293 } \
294 ++str; \
295 ++ret; \
296 } \
297 return GATE_STR_NPOS;
298
299 3203 gate_size_t gate_str_char_pos(gate_char8_t const* str, gate_size_t len, gate_char8_t find, gate_size_t startat)
300 {
301
10/10
✓ Branch 0 taken 3201 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3197 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3195 times.
✓ Branch 6 taken 2341 times.
✓ Branch 7 taken 84761 times.
✓ Branch 8 taken 87102 times.
✓ Branch 9 taken 854 times.
87964 GATE_STR_CHAR_POS(str, len, find, startat);
302 }
303 gate_size_t gate_str16_char_pos(gate_char16_t const* str, gate_size_t len, gate_char16_t find, gate_size_t startat)
304 {
305 GATE_STR_CHAR_POS(str, len, find, startat);
306 }
307 gate_size_t gate_str32_char_pos(gate_char32_t const* str, gate_size_t len, gate_char32_t find, gate_size_t startat)
308 {
309 GATE_STR_CHAR_POS(str, len, find, startat);
310 }
311
312 #define GATE_STR_CHAR_POS_LAST(str, len, find) \
313 gate_size_t ret; \
314 if((str == NULL) || (len == 0)) \
315 { \
316 return GATE_STR_NPOS; \
317 } \
318 ret = len; \
319 str += len; \
320 while(len-- != 0) \
321 { \
322 --ret; \
323 --str; \
324 if(*str == find) \
325 { \
326 return ret; \
327 } \
328 } \
329 return GATE_STR_NPOS;
330
331 687 gate_size_t gate_str_char_pos_last(gate_char8_t const* str, gate_size_t len, gate_char8_t find)
332 {
333
6/8
✓ Branch 0 taken 687 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 687 times.
✓ Branch 4 taken 549 times.
✓ Branch 5 taken 3495 times.
✓ Branch 6 taken 4044 times.
✓ Branch 7 taken 138 times.
4182 GATE_STR_CHAR_POS_LAST(str, len, find);
334 }
335 gate_size_t gate_str16_char_pos_last(gate_char16_t const* str, gate_size_t len, gate_char16_t find)
336 {
337 GATE_STR_CHAR_POS_LAST(str, len, find);
338 }
339 gate_size_t gate_str32_char_pos_last(gate_char32_t const* str, gate_size_t len, gate_char32_t find)
340 {
341 GATE_STR_CHAR_POS_LAST(str, len, find);
342 }
343
344
345
346
347
348 #define GATE_STR_POS(charfinder, rangecomparer, str, len, find, findlen, startat) \
349 gate_size_t ret = startat; \
350 if((str == NULL) || (len == 0) || (find == NULL) || (findlen == 0) || (findlen > len) || (startat > len - findlen)) \
351 { \
352 return GATE_STR_NPOS; \
353 } \
354 str += startat; \
355 len -= startat; \
356 for(;;) \
357 { \
358 gate_size_t pos = charfinder(str, len, *find, 0); \
359 if(pos == GATE_STR_NPOS) \
360 { \
361 return pos; \
362 } \
363 ret += pos; \
364 str += pos; \
365 len -= pos; \
366 if(rangecomparer(str, find, findlen) == 0) \
367 { \
368 break; \
369 } \
370 ++str; \
371 --len; \
372 ++ret; \
373 } \
374 return ret;
375
376
377 606 gate_size_t gate_str_pos(gate_char8_t const* str, gate_size_t len, gate_char8_t const* find, gate_size_t findlen, gate_size_t startat)
378 {
379
13/16
✓ Branch 0 taken 606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 574 times.
✓ Branch 3 taken 32 times.
✓ Branch 4 taken 574 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 574 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 305 times.
✓ Branch 9 taken 269 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 303 times.
✓ Branch 13 taken 227 times.
✓ Branch 14 taken 279 times.
✓ Branch 16 taken 76 times.
✓ Branch 17 taken 203 times.
809 GATE_STR_POS(gate_str_char_pos, gate_str_comp_range, str, len, find, findlen, startat);
380 }
381 gate_size_t gate_str16_pos(gate_char16_t const* str, gate_size_t len, gate_char16_t const* find, gate_size_t findlen, gate_size_t startat)
382 {
383 GATE_STR_POS(gate_str16_char_pos, gate_str16_comp_range, str, len, find, findlen, startat);
384 }
385 gate_size_t gate_str32_pos(gate_char32_t const* str, gate_size_t len, gate_char32_t const* find, gate_size_t findlen, gate_size_t startat)
386 {
387 GATE_STR_POS(gate_str32_char_pos, gate_str32_comp_range, str, len, find, findlen, startat);
388 }
389
390
391 #define GATE_STR_POS_LAST(rangecomparer, str, len, find, findlen) \
392 if((str == NULL) || (len == 0) || (find == NULL) || (findlen == 0) || (findlen > len)) \
393 { \
394 return GATE_STR_NPOS; \
395 } \
396 str += (len - findlen); \
397 len -= (findlen - 1); \
398 while(len-- > 0) \
399 { \
400 if(rangecomparer(str, find, findlen) == 0) \
401 { \
402 return len; \
403 } \
404 --str; \
405 } \
406 return GATE_STR_NPOS;
407
408
409 2 gate_size_t gate_str_pos_last(gate_char8_t const* str, gate_size_t len, gate_char8_t const* find, gate_size_t findlen)
410 {
411
9/14
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 9 times.
✓ Branch 13 taken 10 times.
✓ Branch 14 taken 1 times.
11 GATE_STR_POS_LAST(gate_str_comp_range, str, len, find, findlen);
412 }
413 gate_size_t gate_str16_pos_last(gate_char16_t const* str, gate_size_t len, gate_char16_t const* find, gate_size_t findlen)
414 {
415 GATE_STR_POS_LAST(gate_str16_comp_range, str, len, find, findlen);
416 }
417 gate_size_t gate_str32_pos_last(gate_char32_t const* str, gate_size_t len, gate_char32_t const* find, gate_size_t findlen)
418 {
419 GATE_STR_POS_LAST(gate_str32_comp_range, str, len, find, findlen);
420 }
421
422
423
424
425 #define GATE_STR_LEN(src) \
426 gate_size_t ret = 0; \
427 if(src != NULL) \
428 { \
429 while(*src != 0) \
430 { \
431 ++src; \
432 ++ret; \
433 } \
434 } \
435 return ret;
436
437 812109 gate_size_t gate_str_length(gate_char8_t const* src)
438 {
439
4/4
✓ Branch 0 taken 812019 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 32968232 times.
✓ Branch 3 taken 812019 times.
33780341 GATE_STR_LEN(src);
440 }
441 gate_size_t gate_str16_length(gate_char16_t const* src)
442 {
443 GATE_STR_LEN(src);
444 }
445 19 gate_size_t gate_str32_length(gate_char32_t const* src)
446 {
447
3/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 19 times.
79 GATE_STR_LEN(src);
448 }
449
450 #define GATE_STR_LEN_MAX(src, capacity) \
451 gate_size_t ret = 0; \
452 if(src != NULL) \
453 { \
454 while((*src != 0) && (capacity-- != 0)) \
455 { \
456 ++src; \
457 ++ret; \
458 } \
459 } \
460 return ret;
461
462 49 gate_size_t gate_str_length_max(gate_char8_t const* src, gate_size_t capacity)
463 {
464
4/6
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 410 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 410 times.
✗ Branch 5 not taken.
459 GATE_STR_LEN_MAX(src, capacity);
465 }
466
467 gate_size_t gate_str16_length_max(gate_char16_t const* src, gate_size_t capacity)
468 {
469 GATE_STR_LEN_MAX(src, capacity);
470 }
471
472 gate_size_t gate_str32_length_max(gate_char32_t const* src, gate_size_t capacity)
473 {
474 GATE_STR_LEN_MAX(src, capacity);
475 }
476
477 #define GATE_STR_IS_EMPTY(src) \
478 if(src == NULL) return true; \
479 return *src == 0
480
481
482 3144 gate_bool_t gate_str_is_empty(gate_char8_t const* src)
483 {
484
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 3127 times.
3144 GATE_STR_IS_EMPTY(src);
485 }
486 gate_bool_t gate_str16_is_empty(gate_char16_t const* src)
487 {
488 GATE_STR_IS_EMPTY(src);
489 }
490 gate_bool_t gate_str32_is_empty(gate_char32_t const* src)
491 {
492 GATE_STR_IS_EMPTY(src);
493 }
494
495
496 #define GATE_STR_COMP_RANGE(str1, str2, len) \
497 if(str1 != str2) \
498 { \
499 while(len-- > 0) \
500 { \
501 if(*str1 < *str2) return -1; \
502 if(*str1 > *str2) return +1; \
503 ++str1; \
504 ++str2; \
505 } \
506 } \
507 return 0;
508
509
510 28552 int gate_str_comp_range(gate_char8_t const* str1, gate_char8_t const* str2, gate_size_t len)
511 {
512
8/8
✓ Branch 0 taken 28265 times.
✓ Branch 1 taken 287 times.
✓ Branch 2 taken 15118 times.
✓ Branch 3 taken 57059 times.
✓ Branch 4 taken 8905 times.
✓ Branch 5 taken 48154 times.
✓ Branch 6 taken 72177 times.
✓ Branch 7 taken 4242 times.
76706 GATE_STR_COMP_RANGE(str1, str2, len);
513 }
514 1 int gate_str16_comp_range(gate_char16_t const* str1, gate_char16_t const* str2, gate_size_t len)
515 {
516
5/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 1 times.
7 GATE_STR_COMP_RANGE(str1, str2, len);
517 }
518 3 int gate_str32_comp_range(gate_char32_t const* str1, gate_char32_t const* str2, gate_size_t len)
519 {
520
6/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
5 GATE_STR_COMP_RANGE(str1, str2, len);
521 }
522
523
524
525
526 #define GATE_STR_COMP_RANGE_IC(str1, str2, len) \
527 if(str1 != str2) \
528 { \
529 while(len-- > 0) \
530 { \
531 gate_char8_t c1 = gate_char_lowercase(*str1); \
532 gate_char8_t c2 = gate_char_lowercase(*str2); \
533 if(c1 < c2) return -1; \
534 if(c1 > c2) return +1; \
535 ++str1; \
536 ++str2; \
537 } \
538 } \
539 return 0;
540
541 2925 int gate_str_comp_range_ic(gate_char8_t const* str1, gate_char8_t const* str2, gate_size_t len)
542 {
543
8/8
✓ Branch 0 taken 2924 times.
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1980 times.
✓ Branch 5 taken 2081 times.
✓ Branch 6 taken 768 times.
✓ Branch 7 taken 1313 times.
✓ Branch 8 taken 4061 times.
✓ Branch 9 taken 176 times.
4238 GATE_STR_COMP_RANGE_IC(str1, str2, len);
544 }
545 int gate_str16_comp_range_ic(gate_char16_t const* str1, gate_char16_t const* str2, gate_size_t len)
546 {
547 GATE_STR_COMP_RANGE_IC(str1, str2, len);
548 }
549 int gate_str32_comp_range_ic(gate_char32_t const* str1, gate_char32_t const* str2, gate_size_t len)
550 {
551 GATE_STR_COMP_RANGE_IC(str1, str2, len);
552 }
553
554 #define GATE_STR_TO_LOWER(str, len) \
555 while(len-- > 0) \
556 { \
557 *str = gate_char_lowercase(*str); \
558 ++str; \
559 }
560
561 1 void gate_str_to_lower(gate_char8_t* str, gate_size_t len)
562 {
563
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
7 GATE_STR_TO_LOWER(str, len);
564 1 }
565 void gate_str16_to_lower(gate_char16_t* str, gate_size_t len)
566 {
567 GATE_STR_TO_LOWER(str, len);
568 }
569 void gate_str32_to_lower(gate_char32_t* str, gate_size_t len)
570 {
571 GATE_STR_TO_LOWER(str, len);
572 }
573
574
575
576
577 #define GATE_STR_TO_UPPER(str, len) \
578 while(len-- > 0) \
579 { \
580 *str = gate_char_uppercase(*str); \
581 ++str; \
582 }
583
584 1 void gate_str_to_upper(gate_char8_t* str, gate_size_t len)
585 {
586
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
7 GATE_STR_TO_UPPER(str, len);
587 1 }
588 void gate_str16_to_upper(gate_char16_t* str, gate_size_t len)
589 {
590 GATE_STR_TO_UPPER(str, len);
591 }
592 void gate_str32_to_upper(gate_char32_t* str, gate_size_t len)
593 {
594 GATE_STR_TO_UPPER(str, len);
595 }
596
597
598
599 #define GATE_STR_REVERSE(type, src, len) \
600 if(len > 1) \
601 {\
602 type* dst = src + len - 1; \
603 len /= 2; \
604 while(len != 0) \
605 { \
606 type chr = *src; \
607 *src = *dst; \
608 *dst = chr; \
609 ++src; \
610 --dst; \
611 --len; \
612 } \
613 }
614
615
616 133920 void gate_str_reverse(gate_char8_t* src, gate_size_t len)
617 {
618
3/4
✓ Branch 0 taken 133920 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 134422 times.
✓ Branch 3 taken 133920 times.
268342 GATE_STR_REVERSE(gate_char8_t, src, len);
619 133920 }
620 void gate_str16_reverse(gate_char16_t* src, gate_size_t len)
621 {
622 GATE_STR_REVERSE(gate_char16_t, src, len);
623 }
624 void gate_str32_reverse(gate_char32_t* src, gate_size_t len)
625 {
626 GATE_STR_REVERSE(gate_char32_t, src, len);
627 }
628
629 #define GATE_STR_IS_NUMERIC(str, len) \
630 gate_size_t ret = 0; \
631 for(; len != 0; --len, ++str) \
632 { \
633 if(gate_char_is_digit((int)*str)) \
634 { \
635 ++ret; \
636 } \
637 else \
638 { \
639 break; \
640 } \
641 } \
642 return ret;
643
644 gate_size_t gate_str_is_numeric(gate_char8_t const* str, gate_size_t len)
645 {
646 GATE_STR_IS_NUMERIC(str, len)
647 }
648 gate_size_t gate_str16_is_numeric(gate_char16_t const* str, gate_size_t len)
649 {
650 GATE_STR_IS_NUMERIC(str, len)
651 }
652 gate_size_t gate_str32_is_numeric(gate_char32_t const* str, gate_size_t len)
653 {
654 GATE_STR_IS_NUMERIC(str, len)
655 }
656
657
658
659 180 gate_size_t gate_str_count_chars(gate_char8_t const* str, gate_size_t len, gate_char8_t chr)
660 {
661 180 gate_size_t count = 0;
662
2/2
✓ Branch 0 taken 1740 times.
✓ Branch 1 taken 180 times.
1920 while (len-- != 0)
663 {
664
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1738 times.
1740 if (*str == chr)
665 {
666 2 ++count;
667 }
668 1740 ++str;
669 }
670 180 return count;
671 }
672 345 int gate_str_comp(gate_char8_t const* str1, gate_char8_t const* str2)
673 {
674 345 return gate_str_compare(str1, gate_str_length(str1), str2, gate_str_length(str2));
675 }
676 24903 int gate_str_compare(gate_char8_t const* str1, gate_size_t len1, gate_char8_t const* str2, gate_size_t len2)
677 {
678 24903 gate_size_t len = len1 < len2 ? len1 : len2;
679 24903 int ret = gate_str_comp_range(str1, str2, len);
680
2/2
✓ Branch 0 taken 3238 times.
✓ Branch 1 taken 21665 times.
24903 if (ret == 0)
681 {
682
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 3063 times.
3238 if (len1 < len2) ret = -1;
683
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 3179 times.
3238 if (len1 > len2) ret = 1;
684 }
685 24903 return ret;
686 }
687 14 int gate_str_comp_ic(gate_char8_t const* str1, gate_char8_t const* str2)
688 {
689 14 return gate_str_compare_ic(str1, gate_str_length(str1), str2, gate_str_length(str2));
690 }
691 2534 int gate_str_compare_ic(gate_char8_t const* str1, gate_size_t len1, gate_char8_t const* str2, gate_size_t len2)
692 {
693 2534 gate_size_t len = len1 < len2 ? len1 : len2;
694 2534 int ret = gate_str_comp_range_ic(str1, str2, len);
695
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 2385 times.
2534 if (ret == 0)
696 {
697
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 142 times.
149 if (len1 < len2) ret = -1;
698
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 131 times.
149 if (len1 > len2) ret = 1;
699 }
700 2534 return ret;
701 }
702
703 51 gate_bool_t gate_str_wildcard_match(gate_char8_t const* str, gate_size_t len, gate_char8_t const* like, gate_size_t likelen)
704 {
705
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 1 times.
66 while ((len != 0) && (likelen != 0))
706 {
707
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
62 if (*like == '*')
708 {
709 31 ++like;
710 31 --likelen;
711
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 4 times.
31 if (likelen == 0)
712 {
713 /* like ends with '*' -> this is always a match */
714 27 return true;
715 }
716
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 2 times.
19 while (len != 0)
717 {
718 /* start a new match attempt at each position in str */
719
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 15 times.
17 if (gate_str_wildcard_match(str, len, like, likelen))
720 {
721 2 return true;
722 }
723 15 ++str;
724 15 --len;
725 }
726 2 return false;
727 }
728
729
3/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 16 times.
31 if ((*like == '?') || (*str == *like))
730 {
731 15 ++str;
732 15 --len;
733 15 ++like;
734 15 --likelen;
735 }
736 else
737 {
738 16 return false;
739 }
740 }
741 4 return (len == likelen);
742 }
743
744 34 gate_bool_t gate_str_like(gate_char8_t const* str, gate_size_t len, gate_char8_t const* like, gate_size_t likelen)
745 {
746
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
34 if ((len == 0) && (likelen == 1))
747 {
748 /* empty is like anything -> OK */
749 return *like == '*';
750 }
751
752 34 return gate_str_wildcard_match(str, len, like, likelen);
753 }
754
755 28 gate_bool_t gate_str_like_one_of(gate_char8_t const* str, gate_size_t len, gate_char8_t const* like, gate_size_t likelen, gate_char8_t like_separator)
756 {
757 28 gate_size_t startat = 0;
758 gate_size_t pos;
759 gate_size_t token_len;
760
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 while (startat < likelen)
761 {
762 30 pos = gate_str_char_pos(like, likelen, like_separator, startat);
763
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2 times.
30 if (pos == GATE_STR_NPOS)
764 {
765 28 pos = likelen;
766 }
767 //a;b;c
768 30 token_len = (pos - startat);
769
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (token_len != 0)
770 {
771
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 2 times.
30 if (gate_str_like(str, len, like + startat, token_len))
772 {
773 28 return true;
774 }
775 }
776 2 startat = pos + 1;
777 }
778 return false;
779 }
780
781
782 513 gate_size_t gate_str_find_first_of(gate_char8_t const* str, gate_size_t len, gate_char8_t const* chars, gate_size_t charcount, gate_size_t startat)
783 {
784 gate_size_t ret;
785 gate_size_t ndx;
786
5/10
✓ Branch 0 taken 513 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 513 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 513 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 513 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 513 times.
513 if ((str == NULL) || (len == 0) || (startat >= len) || (chars == NULL) || (charcount == 0))
787 {
788 return GATE_STR_NPOS;
789 }
790 513 ret = startat;
791 513 str += startat;
792 513 len -= startat;
793
2/2
✓ Branch 0 taken 3662 times.
✓ Branch 1 taken 395 times.
4057 while (len-- > 0)
794 {
795
2/2
✓ Branch 0 taken 14236 times.
✓ Branch 1 taken 3544 times.
17780 for (ndx = 0; ndx != charcount; ++ndx)
796 {
797
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 14118 times.
14236 if (*str == chars[ndx])
798 {
799 /* first character found, that is included in 'chars' */
800 118 return ret;
801 }
802 }
803 3544 ++str;
804 3544 ++ret;
805 }
806 395 return GATE_STR_NPOS;
807 }
808
809 5697 gate_size_t gate_str_find_first_not_of(gate_char8_t const* str, gate_size_t len, gate_char8_t const* chars, gate_size_t charcount, gate_size_t startat)
810 {
811 gate_size_t ret;
812 gate_size_t ndx;
813
7/10
✓ Branch 0 taken 5612 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 5608 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5608 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5608 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 5608 times.
5697 if ((str == NULL) || (len == 0) || (startat >= len) || (chars == NULL) || (charcount == 0))
814 {
815 89 return GATE_STR_NPOS;
816 }
817 5608 ret = startat;
818 5608 str += startat;
819 5608 len -= startat;
820
2/2
✓ Branch 0 taken 13053 times.
✓ Branch 1 taken 1 times.
13054 while (len-- > 0)
821 {
822
2/2
✓ Branch 0 taken 31045 times.
✓ Branch 1 taken 5607 times.
36652 for (ndx = 0; ndx != charcount; ++ndx)
823 {
824
2/2
✓ Branch 0 taken 7446 times.
✓ Branch 1 taken 23599 times.
31045 if (*str == chars[ndx])
825 {
826 7446 break;
827 }
828 }
829
2/2
✓ Branch 0 taken 5607 times.
✓ Branch 1 taken 7446 times.
13053 if (ndx == charcount)
830 {
831 /* first character found, that is not included in 'chars' */
832 5607 return ret;
833 }
834 7446 ++str;
835 7446 ++ret;
836 }
837 1 return GATE_STR_NPOS;
838 }
839 24 gate_size_t gate_str_find_last_of(gate_char8_t const* str, gate_size_t len, gate_char8_t const* chars, gate_size_t charcount)
840 {
841 gate_size_t ret;
842 gate_size_t ndx;
843
4/8
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
24 if ((str == NULL) || (len == 0) || (chars == NULL) || (charcount == 0))
844 {
845 return GATE_STR_NPOS;
846 }
847 24 ret = len;
848 24 str += len;
849
2/2
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 1 times.
419 while (len-- > 0)
850 {
851 418 --str;
852 418 --ret;
853
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 395 times.
817 for (ndx = 0; ndx != charcount; ++ndx)
854 {
855
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 399 times.
422 if (*str == chars[ndx])
856 {
857 /* last character found, that is included in 'chars' */
858 23 return ret;
859 }
860 }
861 }
862 1 return GATE_STR_NPOS;
863 }
864 3765 gate_size_t gate_str_find_last_not_of(gate_char8_t const* str, gate_size_t len, gate_char8_t const* chars, gate_size_t charcount)
865 {
866 gate_size_t ret;
867 gate_size_t ndx;
868
5/8
✓ Branch 0 taken 3765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3761 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3761 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3761 times.
3765 if ((str == NULL) || (len == 0) || (chars == NULL) || (charcount == 0))
869 {
870 4 return GATE_STR_NPOS;
871 }
872 3761 ret = len;
873 3761 str += len;
874
2/2
✓ Branch 0 taken 5851 times.
✓ Branch 1 taken 164 times.
6015 while (len-- > 0)
875 {
876 5851 --str;
877 5851 --ret;
878
2/2
✓ Branch 0 taken 23012 times.
✓ Branch 1 taken 3597 times.
26609 for (ndx = 0; ndx != charcount; ++ndx)
879 {
880
2/2
✓ Branch 0 taken 2254 times.
✓ Branch 1 taken 20758 times.
23012 if (*str == chars[ndx])
881 {
882 2254 break;
883 }
884 }
885
2/2
✓ Branch 0 taken 3597 times.
✓ Branch 1 taken 2254 times.
5851 if (ndx == charcount)
886 {
887 /* last character found, that is not included in 'chars' */
888 3597 return ret;
889 }
890 }
891 164 return GATE_STR_NPOS;
892
893 }
894 1 gate_uint32_t gate_str_hash(gate_char8_t const* str, gate_size_t len)
895 {
896 1 gate_uint32_t hash = 5381;
897
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 while (len-- != 0)
898 {
899 4 hash += (hash << 5) + (gate_uint32_t)(gate_uint8_t) * (str++);
900 }
901 1 return hash;
902 }
903
904 gate_size_t gate_str_replace(gate_char8_t* str, gate_size_t len, gate_char8_t find, gate_char8_t replace)
905 {
906 gate_size_t counter = 0;
907 for (; len != 0; --len, ++str)
908 {
909 if (*str == find)
910 {
911 *str = replace;
912 ++counter;
913 }
914 }
915 return counter;
916 }
917
918
919
920
921 3334 gate_bool_t gate_str_starts_with(gate_char8_t const* str, gate_size_t len, gate_char8_t const* starttoken, gate_size_t startlen)
922 {
923
4/4
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 1180 times.
✓ Branch 4 taken 2146 times.
3334 return (startlen > len) ? false : (0 == gate_str_comp_range(str, starttoken, startlen));
924 }
925 34 gate_bool_t gate_str_ends_with(gate_char8_t const* str, gate_size_t len, gate_char8_t const* endtoken, gate_size_t endlen)
926 {
927
2/4
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 34 times.
✗ Branch 4 not taken.
34 return (endlen > len) ? false : (0 == gate_str_comp_range(str + len - endlen, endtoken, endlen));
928 }
929
930 473 gate_bool_t gate_str_starts_with_ic(gate_char8_t const* str, gate_size_t len, gate_char8_t const* starttoken, gate_size_t startlen)
931 {
932
4/4
✓ Branch 0 taken 391 times.
✓ Branch 1 taken 82 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 363 times.
473 return (startlen > len) ? false : (0 == gate_str_comp_range_ic(str, starttoken, startlen));
933 }
934 gate_bool_t gate_str_ends_with_ic(gate_char8_t const* str, gate_size_t len, gate_char8_t const* endtoken, gate_size_t endlen)
935 {
936 return (endlen > len) ? false : (0 == gate_str_comp_range_ic(str + len - endlen, endtoken, endlen));
937 }
938
939
940 gate_bool_t gate_str16_starts_with(gate_char16_t const* str, gate_size_t len, gate_char16_t const* starttoken, gate_size_t startlen)
941 {
942 return (startlen > len) ? false : (0 == gate_str16_comp_range(str, starttoken, startlen));
943 }
944 gate_bool_t gate_str16_ends_with(gate_char16_t const* str, gate_size_t len, gate_char16_t const* endtoken, gate_size_t endlen)
945 {
946 return (endlen > len) ? false : (0 == gate_str16_comp_range(str + len - endlen, endtoken, endlen));
947 }
948 gate_bool_t gate_str32_starts_with(gate_char32_t const* str, gate_size_t len, gate_char32_t const* starttoken, gate_size_t startlen)
949 {
950 return (startlen > len) ? false : (0 == gate_str32_comp_range(str, starttoken, startlen));
951 }
952 gate_bool_t gate_str32_ends_with(gate_char32_t const* str, gate_size_t len, gate_char32_t const* endtoken, gate_size_t endlen)
953 {
954 return (endlen > len) ? false : (0 == gate_str32_comp_range(str + len - endlen, endtoken, endlen));
955 }
956
957
958
959 int gate_str16_comp(gate_char16_t const* str1, gate_char16_t const* str2)
960 {
961 return gate_str16_compare(str1, gate_str16_length(str1), str2, gate_str16_length(str2));
962 }
963 1 int gate_str16_compare(gate_char16_t const* str1, gate_size_t len1, gate_char16_t const* str2, gate_size_t len2)
964 {
965 1 gate_size_t len = len1 < len2 ? len1 : len2;
966 1 int ret = gate_str16_comp_range(str1, str2, len);
967
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ret == 0)
968 {
969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (len1 < len2) ret = -1;
970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (len1 > len2) ret = 1;
971 }
972 1 return ret;
973 }
974 int gate_str16_comp_ic(gate_char16_t const* str1, gate_char16_t const* str2)
975 {
976 return gate_str16_compare_ic(str1, gate_str16_length(str1), str2, gate_str16_length(str2));
977 }
978 int gate_str16_compare_ic(gate_char16_t const* str1, gate_size_t len1, gate_char16_t const* str2, gate_size_t len2)
979 {
980 gate_size_t len = len1 < len2 ? len1 : len2;
981 int ret = gate_str16_comp_range_ic(str1, str2, len);
982 if (ret == 0)
983 {
984 if (len1 < len2) ret = -1;
985 if (len1 > len2) ret = 1;
986 }
987 return ret;
988 }
989
990
991 3 int gate_str32_comp(gate_char32_t const* str1, gate_char32_t const* str2)
992 {
993 3 return gate_str32_compare(str1, gate_str32_length(str1), str2, gate_str32_length(str2));
994 }
995 3 int gate_str32_compare(gate_char32_t const* str1, gate_size_t len1, gate_char32_t const* str2, gate_size_t len2)
996 {
997 3 gate_size_t len = len1 < len2 ? len1 : len2;
998 3 int ret = gate_str32_comp_range(str1, str2, len);
999
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ret == 0)
1000 {
1001
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (len1 < len2) ret = -1;
1002
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (len1 > len2) ret = 1;
1003 }
1004 3 return ret;
1005 }
1006 int gate_str32_comp_ic(gate_char32_t const* str1, gate_char32_t const* str2)
1007 {
1008 return gate_str32_compare_ic(str1, gate_str32_length(str1), str2, gate_str32_length(str2));
1009 }
1010 int gate_str32_compare_ic(gate_char32_t const* str1, gate_size_t len1, gate_char32_t const* str2, gate_size_t len2)
1011 {
1012 gate_size_t len = len1 < len2 ? len1 : len2;
1013 int ret = gate_str32_comp_range_ic(str1, str2, len);
1014 if (ret == 0)
1015 {
1016 if (len1 < len2) ret = -1;
1017 if (len1 > len2) ret = 1;
1018 }
1019 return ret;
1020 }
1021
1022
1023
1024
1025 /********************************
1026 * StringBuilder implementation *
1027 ********************************/
1028
1029 4306 static gate_stringbuffer_t* gate_strbuilder_resize_heap(gate_stringbuffer_t* src, gate_size_t srclength, gate_size_t newcapacity)
1030 {
1031 gate_stringbuffer_t* ret;
1032
2/2
✓ Branch 0 taken 933 times.
✓ Branch 1 taken 3373 times.
4306 if (newcapacity == 0)
1033 {
1034
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 812 times.
933 if (src != NULL)
1035 {
1036 121 gate_mem_dealloc(src);
1037 }
1038 933 ret = NULL;
1039 }
1040 else
1041 {
1042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3373 times.
3373 if (newcapacity <= srclength)
1043 {
1044 ret = src;
1045 }
1046 else
1047 {
1048 3373 ++newcapacity;
1049 3373 ret = (gate_stringbuffer_t*)gate_mem_realloc(src, sizeof(gate_stringbuffer_t) + newcapacity);
1050
1/2
✓ Branch 0 taken 3373 times.
✗ Branch 1 not taken.
3373 if (ret != NULL)
1051 {
1052 3373 ret->data[newcapacity] = 0;
1053 3373 ret->refcount = 0;
1054 }
1055 }
1056 }
1057 4306 return ret;
1058 }
1059
1060 42 static gate_stringbuffer_t* gate_strbuilder_resize_disabled(gate_stringbuffer_t* src, gate_size_t srclength, gate_size_t newcapacity)
1061 {
1062 (void)src;
1063 (void)srclength;
1064 (void)newcapacity;
1065 42 return NULL;
1066 }
1067
1068 929 void gate_strbuilder_create(gate_strbuilder_t* builder, gate_size_t capacity)
1069 {
1070 929 builder->ptr_data = NULL;
1071 929 builder->length = 0;
1072 929 builder->capacity = 0;
1073 929 builder->resize = &gate_strbuilder_resize_heap;
1074 929 builder->buffer = NULL;
1075
2/2
✓ Branch 0 taken 794 times.
✓ Branch 1 taken 135 times.
929 if (capacity != 0)
1076 {
1077 794 builder->buffer = builder->resize(NULL, 0, capacity);
1078
1/2
✓ Branch 0 taken 794 times.
✗ Branch 1 not taken.
794 if (builder->buffer != NULL)
1079 {
1080 794 builder->ptr_data = builder->buffer->data;
1081 }
1082 }
1083 929 }
1084 98 void gate_strbuilder_create_static(gate_strbuilder_t* builder, char* buffer, gate_size_t capacity, gate_size_t length_used)
1085 {
1086 98 builder->ptr_data = buffer;
1087 98 builder->length = length_used;
1088 98 builder->capacity = capacity;
1089 98 builder->resize = &gate_strbuilder_resize_disabled;
1090 98 builder->buffer = NULL;
1091 98 builder->ptr_data[length_used] = 0;
1092 98 }
1093
1094
1095 999 void gate_strbuilder_release(gate_strbuilder_t* builder)
1096 {
1097
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 26 times.
999 if ((builder->resize != NULL))
1098 {
1099 973 builder->buffer = builder->resize(builder->buffer, builder->length, 0);
1100 973 builder->capacity = 0;
1101 }
1102 999 builder->ptr_data = NULL;
1103 999 builder->length = 0;
1104 999 }
1105 1607 gate_size_t gate_strbuilder_length(gate_strbuilder_t const* builder)
1106 {
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1607 times.
1607 if (builder == NULL)
1108 {
1109 return 0;
1110 }
1111 else
1112 {
1113 1607 return builder->length;
1114 }
1115 }
1116 1088 gate_char8_t const* gate_strbuilder_ptr(gate_strbuilder_t const* builder, gate_size_t charpos)
1117 {
1118
2/4
✓ Branch 0 taken 1088 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1088 times.
1088 if ((builder == NULL) || (builder->ptr_data == NULL))
1119 {
1120 return NULL;
1121 }
1122 else
1123 {
1124
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 1037 times.
1088 if (charpos >= builder->length)
1125 {
1126 51 return NULL;
1127 }
1128 else
1129 {
1130 1037 return &builder->ptr_data[charpos];
1131 }
1132 }
1133 }
1134 2581 gate_size_t gate_strbuilder_resize(gate_strbuilder_t* builder, gate_size_t sz)
1135 {
1136 gate_stringbuffer_t* newbuffer;
1137
2/4
✓ Branch 0 taken 2581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2581 times.
✗ Branch 3 not taken.
2581 if ((builder->resize != NULL) && (sz != 0))
1138 {
1139 2581 newbuffer = builder->resize(builder->buffer, builder->length, sz + 1);
1140
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2579 times.
2581 if (newbuffer == NULL)
1141 {
1142 /* allocation failed */
1143 2 return 0;
1144 }
1145 2579 builder->buffer = newbuffer;
1146 2579 builder->ptr_data = newbuffer->data;
1147 2579 builder->capacity = sz;
1148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2579 times.
2579 if (builder->length > builder->capacity)
1149 {
1150 builder->length = builder->capacity;
1151 }
1152 2579 return builder->capacity;
1153 }
1154 else
1155 {
1156 return 0;
1157 }
1158 }
1159
1160 2571 gate_size_t gate_strbuilder_increase(gate_strbuilder_t* builder, gate_size_t sz)
1161 {
1162 2571 return gate_strbuilder_resize(builder, builder->capacity + sz + 1);
1163 }
1164
1165
1166 819674 gate_size_t gate_strbuilder_append_text(gate_strbuilder_t* builder, gate_char8_t const* txt, gate_size_t txtlen)
1167 {
1168
3/4
✓ Branch 0 taken 819651 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 819651 times.
✗ Branch 3 not taken.
819674 if ((txtlen != 0) && (txt != NULL))
1169 {
1170 819651 gate_size_t const free_chars = builder->capacity - builder->length;
1171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 819651 times.
819651 GATE_DEBUG_ASSERT(builder->capacity >= builder->length);
1172
2/2
✓ Branch 0 taken 2545 times.
✓ Branch 1 taken 817106 times.
819651 if (txtlen >= free_chars)
1173 {
1174
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2545 times.
2545 if (gate_strbuilder_increase(builder, txtlen + (builder->length + 1) / 2) == 0)
1175 {
1176 return 0;
1177 }
1178 }
1179 819651 gate_mem_copy(&builder->ptr_data[builder->length], txt, txtlen);
1180 819651 builder->length += txtlen;
1181 819651 builder->ptr_data[builder->length] = 0;
1182 819651 return txtlen;
1183 }
1184 else
1185 {
1186 23 return 0;
1187 }
1188 }
1189 220 gate_size_t gate_strbuilder_append_chars(gate_strbuilder_t* builder, gate_size_t char_count, char chr)
1190 {
1191
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 15 times.
220 if (char_count != 0)
1192 {
1193 gate_size_t cnt;
1194 char* ptr;
1195
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 181 times.
205 if (char_count >= builder->capacity - builder->length)
1196 {
1197
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 if (gate_strbuilder_increase(builder, char_count + builder->length / 2) == 0)
1198 {
1199 return 0;
1200 }
1201 }
1202 205 ptr = &builder->ptr_data[builder->length];
1203 205 cnt = char_count;
1204
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 205 times.
514 while (cnt-- != 0)
1205 {
1206 309 *ptr = chr;
1207 309 ++ptr;
1208 }
1209 205 builder->length += char_count;
1210 205 builder->ptr_data[builder->length] = 0;
1211 205 return char_count;
1212 }
1213 else
1214 {
1215 15 return 0;
1216 }
1217 }
1218
1219 661237 gate_size_t gate_strbuilder_append_cstr(gate_strbuilder_t* builder, char const* txt)
1220 {
1221
1/2
✓ Branch 0 taken 661237 times.
✗ Branch 1 not taken.
661237 if (txt)
1222 {
1223 661237 return gate_strbuilder_append_text(builder, txt, gate_str_length(txt));
1224 }
1225 return 0;
1226 }
1227
1228 380 gate_size_t gate_strbuilder_append_string(gate_strbuilder_t* builder, gate_string_t const* txt)
1229 {
1230
1/2
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
380 if (txt)
1231 {
1232 380 return gate_strbuilder_append_text(builder, txt->str, txt->length);
1233 }
1234 return 0;
1235 }
1236
1237 1 gate_size_t gate_strbuilder_append_text16(gate_strbuilder_t* builder, gate_char16_t const* txt, gate_size_t txtlen)
1238 {
1239 1 gate_size_t ret = 0;
1240 gate_char32_t chr;
1241 gate_size_t len_decoded, len_encoded;
1242 gate_char8_t utf8[16];
1243 1 gate_strbuilder_increase(builder, txtlen);
1244
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 while (txtlen != 0)
1245 {
1246 1 len_decoded = gate_char_read_utf16(txt, txtlen, &chr);
1247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (len_decoded == 0)
1248 {
1249 break;
1250 }
1251 1 txt += len_decoded;
1252 1 txtlen -= len_decoded;
1253 1 len_encoded = gate_char_write_utf8(chr, utf8, sizeof(utf8));
1254 1 gate_strbuilder_append_text(builder, utf8, len_encoded);
1255 1 ret += len_encoded;
1256 }
1257 1 return ret;
1258 }
1259 1 gate_size_t gate_strbuilder_append_text32(gate_strbuilder_t* builder, gate_char32_t const* txt, gate_size_t txtlen)
1260 {
1261 1 gate_size_t ret = 0;
1262 gate_char32_t chr;
1263 gate_size_t len_decoded, len_encoded;
1264 gate_char8_t utf8[16];
1265 1 gate_strbuilder_increase(builder, txtlen);
1266
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 while (txtlen != 0)
1267 {
1268 1 len_decoded = gate_char_read_utf32(txt, txtlen, &chr);
1269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (len_decoded == 0)
1270 {
1271 break;
1272 }
1273 1 txt += len_decoded;
1274 1 txtlen -= len_decoded;
1275 1 len_encoded = gate_char_write_utf8(chr, utf8, sizeof(utf8));
1276 1 gate_strbuilder_append_text(builder, utf8, len_encoded);
1277 1 ret += len_encoded;
1278 }
1279 1 return ret;
1280 }
1281
1282
1283 1 gate_size_t gate_strbuilder_append_int16(gate_strbuilder_t* builder, gate_int16_t num)
1284 {
1285 gate_char8_t buffer[12];
1286 1 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1287 1 gate_size_t bufferused = gate_str_print_int16(&buffer[0], bufferlen, num);
1288 1 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1289 }
1290 24 gate_size_t gate_strbuilder_append_uint16(gate_strbuilder_t* builder, gate_uint16_t num)
1291 {
1292 gate_char8_t buffer[12];
1293 24 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1294 24 gate_size_t bufferused = gate_str_print_uint16(&buffer[0], bufferlen, num);
1295 24 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1296 }
1297 29 gate_size_t gate_strbuilder_append_int32(gate_strbuilder_t* builder, gate_int32_t num)
1298 {
1299 gate_char8_t buffer[16];
1300 29 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1301 29 gate_size_t bufferused = gate_str_print_int32(&buffer[0], bufferlen, num);
1302 29 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1303 }
1304 132213 gate_size_t gate_strbuilder_append_uint32(gate_strbuilder_t* builder, gate_uint32_t num)
1305 {
1306 gate_char8_t buffer[16];
1307 132213 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1308 132213 gate_size_t bufferused = gate_str_print_uint32(&buffer[0], bufferlen, num);
1309 132213 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1310 }
1311 48 gate_size_t gate_strbuilder_append_int64(gate_strbuilder_t* builder, gate_int64_t num)
1312 {
1313 gate_char8_t buffer[24];
1314 48 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1315 48 gate_size_t bufferused = gate_str_print_int64(&buffer[0], bufferlen, num);
1316 48 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1317 }
1318 9 gate_size_t gate_strbuilder_append_uint64(gate_strbuilder_t* builder, gate_uint64_t num)
1319 {
1320 gate_char8_t buffer[24];
1321 9 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1322 9 gate_size_t bufferused = gate_str_print_int64(&buffer[0], bufferlen, num);
1323 9 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1324 }
1325 15 gate_size_t gate_strbuilder_append_real(gate_strbuilder_t* builder, gate_real64_t num, unsigned intlen, unsigned decimallen, unsigned grouplen)
1326 {
1327 gate_char8_t buffer[64];
1328 15 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1329 15 gate_size_t bufferused = gate_str_print_real(&buffer[0], bufferlen, num, intlen, decimallen, grouplen);
1330 15 return gate_strbuilder_append_text(builder, &buffer[0], bufferused);
1331 }
1332 6 gate_size_t gate_strbuilder_append_hex(gate_strbuilder_t* builder, gate_uint8_t const* bytes, gate_size_t byte_count, gate_bool_t uppercase)
1333 {
1334 6 gate_size_t ret = 0;
1335 gate_char8_t chr[4];
1336
1337
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 while (byte_count-- != 0)
1338 {
1339 6 chr[0] = gate_str_print_hex_nibble((gate_uint8_t)((*bytes >> 4) & 0x0f), uppercase);
1340 6 chr[1] = gate_str_print_hex_nibble((gate_uint8_t)((*bytes) & 0x0f), uppercase);
1341 6 ret += gate_strbuilder_append_text(builder, chr, 2);
1342 6 ++bytes;
1343 }
1344 6 return ret;
1345 }
1346
1347
1348 523 static gate_size_t gate_strbuilder_printer_callback(void* printer_param, gate_char8_t const* data, gate_size_t datalen)
1349 {
1350 523 gate_strbuilder_t* builder = (gate_strbuilder_t*)printer_param;
1351 523 return gate_strbuilder_append_text(builder, data, datalen);
1352 }
1353
1354 68 gate_size_t gate_strbuilder_append(gate_strbuilder_t* builder, ...)
1355 {
1356 gate_size_t ret;
1357 va_list vl;
1358
1359 68 va_start(vl, builder);
1360
1361 68 ret = gate_str_print_to(&gate_strbuilder_printer_callback, builder, vl);
1362
1363 68 va_end(vl);
1364
1365 68 return ret;
1366 }
1367
1368 1 gate_size_t gate_strbuilder_insert(gate_strbuilder_t* builder, gate_size_t pos, char const* txt, gate_size_t txtlen)
1369 {
1370 1 gate_size_t ret = 0;
1371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pos >= builder->length)
1372 {
1373 ret = gate_strbuilder_append_text(builder, txt, txtlen);
1374 }
1375 else
1376 {
1377 1 ret = gate_strbuilder_resize(builder, builder->length + txtlen + 2);
1378
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ret != 0)
1379 {
1380 1 gate_mem_move(&builder->buffer->data[pos + txtlen], &builder->buffer->data[pos], builder->length - pos);
1381 1 gate_mem_copy(&builder->buffer->data[pos], txt, txtlen);
1382 1 builder->length += txtlen;
1383 1 builder->buffer->data[builder->length] = 0;
1384 1 ret = txtlen;
1385 }
1386 }
1387 1 return ret;
1388 }
1389
1390 1 gate_size_t gate_strbuilder_remove(gate_strbuilder_t* builder, gate_size_t pos, gate_size_t length)
1391 {
1392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pos >= builder->length)
1393 {
1394 return 0;
1395 }
1396
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ((length == GATE_STR_NPOS) || (pos + length > builder->length) )
1397 {
1398 1 length = builder->length - pos;
1399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length == 0)
1400 {
1401 return 0;
1402 }
1403 }
1404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pos + length < builder->length)
1405 {
1406 gate_mem_move(&builder->buffer->data[pos], &builder->buffer->data[pos + length], builder->length - pos - length);
1407 }
1408
1409 1 builder->length -= length;
1410 1 builder->buffer->data[builder->length] = 0;
1411
1412 1 return length;
1413 }
1414
1415 34 gate_size_t gate_strbuilder_replace(gate_strbuilder_t* builder, gate_size_t pos, gate_size_t len, char const* txt, gate_size_t txtlen)
1416 {
1417 34 gate_size_t ret = 0; /* default result: no replacement applied */
1418 gate_size_t diff;
1419 gate_size_t movelen;
1420 do
1421 {
1422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (pos + len > builder->length)
1423 {
1424 /* out of bounds */
1425 break;
1426 }
1427
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 24 times.
34 if (txtlen > len)
1428 {
1429 /* replacement requires string expansion */
1430 10 diff = txtlen - len;
1431
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if (builder->length + diff + 1 > builder->capacity)
1432 {
1433
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (0 == gate_strbuilder_resize(builder, builder->length + diff + 1))
1434 {
1435 /* allocation failed */
1436 break;
1437 }
1438 }
1439 10 movelen = builder->length - (pos + len);
1440
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3 times.
10 if (movelen > 0)
1441 {
1442 7 gate_mem_move(&builder->ptr_data[pos + txtlen], &builder->ptr_data[pos + len], movelen);
1443 }
1444 10 gate_mem_copy(&builder->ptr_data[pos], txt, txtlen);
1445 10 builder->length += diff;
1446 10 builder->ptr_data[builder->length] = 0;
1447 }
1448 else
1449 {
1450 /* inline replacement */
1451
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
24 if (txtlen > 0)
1452 {
1453 23 gate_mem_copy(&builder->ptr_data[pos], txt, txtlen);
1454 }
1455
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
24 if (len > txtlen)
1456 {
1457 /* discard characters */
1458 20 diff = len - txtlen;
1459 20 movelen = builder->length - (pos + len);
1460
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 if (movelen > 0)
1461 {
1462 12 gate_mem_move(&builder->ptr_data[pos + txtlen], &builder->ptr_data[pos + len], movelen);
1463 }
1464 20 builder->length -= diff;
1465 20 builder->ptr_data[builder->length] = 0;
1466 }
1467 }
1468 34 ret = 1; /* one replacement applied */
1469 } while (0);
1470 34 return ret;
1471
1472 }
1473
1474 1 gate_size_t gate_strbuilder_replace_str(gate_strbuilder_t* builder, char const* find, gate_size_t find_len, char const* replace_with, gate_size_t replace_with_len, gate_size_t start_pos, gate_size_t max_replace)
1475 {
1476 1 gate_size_t replaced_count = 0;
1477 1 gate_size_t find_pos = 0;
1478
1479
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 while (max_replace-- > 0)
1480 {
1481 4 find_pos = gate_strbuilder_str_pos(builder, find, find_len, start_pos);
1482
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (find_pos == GATE_STR_NPOS)
1483 {
1484 /* nothing more found */
1485 1 break;
1486 }
1487
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (0 == gate_strbuilder_replace(builder, find_pos, find_len, replace_with, replace_with_len))
1488 {
1489 /* native replace operation failed */
1490 break;
1491 }
1492 3 start_pos = find_pos;
1493 3 ++replaced_count;
1494 }
1495 1 return replaced_count;
1496 }
1497
1498 1 gate_size_t gate_strbuilder_replace_string(gate_strbuilder_t* builder, gate_string_t const* find, gate_string_t const* replace_with, gate_size_t start_pos, gate_size_t max_replace)
1499 {
1500 3 return gate_strbuilder_replace_str(builder,
1501 1 gate_string_ptr(find, 0), gate_string_length(find),
1502 1 gate_string_ptr(replace_with, 0), gate_string_length(replace_with),
1503 start_pos, max_replace);
1504 }
1505
1506
1507
1508 892 gate_size_t gate_strbuilder_discard(gate_strbuilder_t* builder, gate_size_t charcount)
1509 {
1510
2/2
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 322 times.
892 if (charcount >= builder->length)
1511 {
1512 570 charcount = builder->length;
1513 570 builder->length = 0;
1514 }
1515 else
1516 {
1517
1/2
✓ Branch 0 taken 322 times.
✗ Branch 1 not taken.
322 if (charcount > 0)
1518 {
1519 322 gate_mem_move(&builder->ptr_data[0], &builder->ptr_data[charcount], builder->length - charcount);
1520 322 builder->length -= charcount;
1521 322 builder->ptr_data[builder->length] = 0;
1522 }
1523 }
1524 892 return charcount;
1525 }
1526 1 gate_size_t gate_strbuilder_discard_back(gate_strbuilder_t* builder, gate_size_t charcount)
1527 {
1528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (charcount > builder->length)
1529 {
1530 charcount = builder->length;
1531 }
1532
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (charcount > 0)
1533 {
1534 1 builder->length -= charcount;
1535 1 builder->ptr_data[builder->length] = 0;
1536 }
1537 1 return charcount;
1538 }
1539
1540 532 gate_size_t gate_strbuilder_str_pos(gate_strbuilder_t const* builder, gate_char8_t const* str, gate_size_t strlength, gate_size_t start_at)
1541 {
1542
3/6
✓ Branch 0 taken 532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 532 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 532 times.
532 if (!builder || !str || (strlength == 0))
1543 {
1544 return GATE_STR_NPOS;
1545 }
1546 532 return gate_str_pos(builder->ptr_data, builder->length, str, strlength, start_at);
1547 }
1548
1549 1 gate_size_t gate_strbuilder_pos(gate_strbuilder_t const* builder, gate_string_t const* token, gate_size_t start_at)
1550 {
1551
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 if (!builder || (gate_string_length(token) == 0))
1552 {
1553 return GATE_STR_NPOS;
1554 }
1555 1 return gate_str_pos(builder->ptr_data, builder->length, token->str, token->length, start_at);
1556 }
1557 1 gate_size_t gate_strbuilder_char_pos(gate_strbuilder_t const* builder, gate_char8_t chr, gate_size_t start_at)
1558 {
1559 1 return gate_str_char_pos(builder->ptr_data, builder->length, chr, start_at);
1560 }
1561
1562
1563 824 gate_string_t* gate_strbuilder_to_string(gate_strbuilder_t* builder, gate_string_t* str)
1564 {
1565
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 804 times.
824 if (builder->length == 0)
1566 {
1567 20 gate_string_create_empty(str);
1568 20 gate_strbuilder_release(builder);
1569 }
1570 else
1571 {
1572 804 str->buffer = builder->buffer;
1573 804 str->str = builder->ptr_data;
1574 804 str->length = builder->length;
1575
2/2
✓ Branch 0 taken 796 times.
✓ Branch 1 taken 8 times.
804 if (str->buffer != NULL)
1576 {
1577 796 gate_atomic_int_init(&str->buffer->refcount, 1);
1578 }
1579
1580 804 builder->buffer = NULL;
1581 804 builder->ptr_data = NULL;
1582 804 builder->capacity = 0;
1583 804 builder->length = 0;
1584 }
1585 824 return str;
1586 }
1587 5 gate_string_t* gate_strbuilder_copy_to_string(gate_strbuilder_t const* builder, gate_string_t* str)
1588 {
1589 5 return gate_string_create(str, &builder->ptr_data[0], builder->length);
1590 }
1591 1 gate_result_t gate_strbuilder_copy_constructor(void* destMem, void const* srcMem)
1592 {
1593 1 gate_strbuilder_t* const dst = (gate_strbuilder_t*)destMem;
1594 1 gate_strbuilder_create(dst, 0);
1595
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (srcMem)
1596 {
1597 1 gate_strbuilder_t const* const src = (gate_strbuilder_t const*)srcMem;
1598 1 gate_size_t const len = gate_strbuilder_length(src);
1599
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (len > 0)
1600 {
1601
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (0 == gate_strbuilder_append_text(dst, gate_strbuilder_ptr(src, 0), len))
1602 {
1603 gate_strbuilder_release(dst);
1604 return GATE_RESULT_OUTOFMEMORY;
1605 }
1606 }
1607 }
1608 1 return GATE_RESULT_OK;
1609 }
1610 1 void gate_strbuilder_destructor(void* dest)
1611 {
1612 1 gate_strbuilder_t* dst = (gate_strbuilder_t*)dest;
1613 1 gate_strbuilder_release(dst);
1614 1 }
1615
1616
1617
1618
1619
1620
1621
1622 #define GATE_STR_PRINT_TXT(dst, dstlen, txt, txtlen) \
1623 if((dstlen) == 0) \
1624 { \
1625 return 0; \
1626 } \
1627 if((txtlen) >= (dstlen)) \
1628 { \
1629 txtlen = dstlen - 1; \
1630 } \
1631 if((txtlen) != 0) \
1632 { \
1633 gate_mem_copy((dst), (txt), (txtlen) * sizeof( (dst)[0] )); \
1634 } \
1635 dst[txtlen] = 0; \
1636 return txtlen;
1637
1638 138351 gate_size_t gate_str_print_text(gate_char8_t* dst, gate_size_t dstlen, gate_char8_t const* txt, gate_size_t txtlen)
1639 {
1640
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 138351 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 138346 times.
✓ Branch 4 taken 138239 times.
✓ Branch 5 taken 112 times.
138351 GATE_STR_PRINT_TXT(dst, dstlen, txt, txtlen);
1641 }
1642 gate_size_t gate_str16_print_text(gate_char16_t* dst, gate_size_t dstlen, gate_char16_t const* txt, gate_size_t txtlen)
1643 {
1644 GATE_STR_PRINT_TXT(dst, dstlen, txt, txtlen);
1645 }
1646 gate_size_t gate_str32_print_text(gate_char32_t* dst, gate_size_t dstlen, gate_char32_t const* txt, gate_size_t txtlen)
1647 {
1648 GATE_STR_PRINT_TXT(dst, dstlen, txt, txtlen);
1649 }
1650
1651 9 gate_size_t gate_str_print_wtext(gate_char8_t* dst, gate_size_t dstlen, wchar_t const* txt, gate_size_t txtlen)
1652 {
1653 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
1654 return gate_str_utf16_2_utf8((gate_char16_t const*)txt, txtlen, dst, dstlen);
1655 #else
1656 9 return gate_str_utf32_2_utf8((gate_char32_t const*)txt, txtlen, dst, dstlen);
1657 #endif
1658 }
1659 gate_size_t gate_str16_print_wtext(gate_char16_t* dst, gate_size_t dstlen, wchar_t const* txt, gate_size_t txtlen)
1660 {
1661 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
1662 return gate_str16_print_text(dst, dstlen, txt, txtlen);
1663 #else
1664 return gate_str_utf32_2_utf16((gate_char32_t const*)txt, txtlen, dst, dstlen);
1665 #endif
1666 }
1667 gate_size_t gate_str32_print_wtext(gate_char32_t* dst, gate_size_t dstlen, wchar_t const* txt, gate_size_t txtlen)
1668 {
1669 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
1670 return gate_str_utf16_2_utf32((gate_char16_t const*)txt, txtlen, dst, dstlen);
1671 #else
1672 return gate_str32_print_text(dst, dstlen, txt, txtlen);
1673 #endif
1674
1675 }
1676
1677
1678
1679
1680 #define GATE_STR_PRINT_NUM(buffer, bufferlen, ptr, bufferused, numtype, num, reverter) \
1681 { \
1682 ptr = &buffer[0]; \
1683 bufferused = 0; \
1684 while(bufferlen != 0) \
1685 { \
1686 *ptr = ('0' + (gate_char8_t)(num % (numtype)10)); \
1687 num /= (numtype)10; \
1688 ++bufferused; \
1689 ++ptr; \
1690 --bufferlen; \
1691 if(num == 0) break; \
1692 } \
1693 if(bufferused >= 2) \
1694 { \
1695 reverter(&buffer[0], bufferused); \
1696 } \
1697 if(bufferlen != 0) \
1698 { \
1699 *ptr = 0; \
1700 } \
1701 }
1702
1703
1704 #define GATE_STR_PRINT_INUM(retvar, buffer, bufferlen, unum, num, uint_type, uint_func) \
1705 { \
1706 retvar = 0; \
1707 if(num < 0) \
1708 { \
1709 *buffer = '-'; \
1710 ++buffer; \
1711 --bufferlen; \
1712 ++retvar; \
1713 unum = (uint_type)-num; \
1714 } \
1715 else \
1716 { \
1717 unum = (uint_type)num; \
1718 } \
1719 retvar += uint_func(buffer, bufferlen, unum) ; \
1720 }
1721
1722
1723 331 gate_size_t gate_str_print_uint16(gate_char8_t* dst, gate_size_t dstlen, gate_uint16_t num)
1724 {
1725 331 gate_size_t ret = 0;
1726
2/4
✓ Branch 0 taken 331 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 331 times.
✗ Branch 3 not taken.
331 if ((dst != NULL) && (dstlen != 0))
1727 {
1728 gate_char8_t* ptr;
1729
6/8
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 227 times.
✓ Branch 2 taken 558 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 161 times.
✓ Branch 5 taken 170 times.
✓ Branch 7 taken 331 times.
✗ Branch 8 not taken.
558 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint16_t, num, gate_str_reverse);
1730 }
1731 331 return ret;
1732 }
1733 5 gate_size_t gate_str_print_int16(gate_char8_t* dst, gate_size_t dstlen, gate_int16_t num)
1734 {
1735 5 gate_size_t ret = 0;
1736
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if ((dst != NULL) && (dstlen != 0))
1737 {
1738 gate_uint16_t unum;
1739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint16_t, gate_str_print_uint16);
1740 }
1741 5 return ret;
1742 }
1743 133436 gate_size_t gate_str_print_uint32(gate_char8_t* dst, gate_size_t dstlen, gate_uint32_t num)
1744 {
1745 133436 gate_size_t ret = 0;
1746
2/4
✓ Branch 0 taken 133436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 133436 times.
✗ Branch 3 not taken.
133436 if ((dst != NULL) && (dstlen != 0))
1747 {
1748 gate_char8_t* ptr;
1749
6/8
✓ Branch 0 taken 133436 times.
✓ Branch 1 taken 255672 times.
✓ Branch 2 taken 389108 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 133094 times.
✓ Branch 5 taken 342 times.
✓ Branch 7 taken 133436 times.
✗ Branch 8 not taken.
389108 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint32_t, num, gate_str_reverse);
1750 }
1751 133436 return ret;
1752 }
1753 341 gate_size_t gate_str_print_int32(gate_char8_t* dst, gate_size_t dstlen, gate_int32_t num)
1754 {
1755 341 gate_size_t ret = 0;
1756
2/4
✓ Branch 0 taken 341 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 341 times.
✗ Branch 3 not taken.
341 if ((dst != NULL) && (dstlen != 0))
1757 {
1758 gate_uint32_t unum;
1759
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 340 times.
341 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint32_t, gate_str_print_uint32);
1760 }
1761 341 return ret;
1762 }
1763 1195 gate_size_t gate_str_print_uint64(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num)
1764 {
1765 1195 gate_size_t ret = 0;
1766
2/4
✓ Branch 0 taken 1195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1195 times.
✗ Branch 3 not taken.
1195 if ((dst != NULL) && (dstlen != 0))
1767 {
1768 gate_char8_t* ptr;
1769
8/8
✓ Branch 0 taken 1194 times.
✓ Branch 1 taken 1579 times.
✓ Branch 2 taken 2773 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 665 times.
✓ Branch 5 taken 530 times.
✓ Branch 7 taken 1194 times.
✓ Branch 8 taken 1 times.
2774 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint64_t, num, gate_str_reverse);
1770 }
1771 1195 return ret;
1772 }
1773 291 gate_size_t gate_str_print_int64(gate_char8_t* dst, gate_size_t dstlen, gate_int64_t num)
1774 {
1775 291 gate_size_t ret = 0;
1776
2/4
✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 291 times.
✗ Branch 3 not taken.
291 if ((dst != NULL) && (dstlen != 0))
1777 {
1778 gate_uint64_t unum;
1779
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 253 times.
291 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint64_t, gate_str_print_uint64);
1780 }
1781 291 return ret;
1782 }
1783
1784
1785 gate_size_t gate_str16_print_uint16(gate_char16_t* dst, gate_size_t dstlen, gate_uint16_t num)
1786 {
1787 gate_size_t ret = 0;
1788 if ((dst != NULL) && (dstlen != 0))
1789 {
1790 gate_char16_t* ptr;
1791 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint16_t, num, gate_str16_reverse);
1792 }
1793 return ret;
1794 }
1795 gate_size_t gate_str16_print_int16(gate_char16_t* dst, gate_size_t dstlen, gate_int16_t num)
1796 {
1797 gate_size_t ret = 0;
1798 if ((dst != NULL) && (dstlen != 0))
1799 {
1800 gate_uint16_t unum;
1801 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint16_t, gate_str16_print_uint16);
1802 }
1803 return ret;
1804 }
1805 gate_size_t gate_str16_print_uint32(gate_char16_t* dst, gate_size_t dstlen, gate_uint32_t num)
1806 {
1807 gate_size_t ret = 0;
1808 if ((dst != NULL) && (dstlen != 0))
1809 {
1810 gate_char16_t* ptr;
1811 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint32_t, num, gate_str16_reverse);
1812 }
1813 return ret;
1814 }
1815 gate_size_t gate_str16_print_int32(gate_char16_t* dst, gate_size_t dstlen, gate_int32_t num)
1816 {
1817 gate_size_t ret = 0;
1818 if ((dst != NULL) && (dstlen != 0))
1819 {
1820 gate_uint32_t unum;
1821 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint32_t, gate_str16_print_uint32);
1822 }
1823 return ret;
1824 }
1825 gate_size_t gate_str16_print_uint64(gate_char16_t* dst, gate_size_t dstlen, gate_uint64_t num)
1826 {
1827 gate_size_t ret = 0;
1828 if ((dst != NULL) && (dstlen != 0))
1829 {
1830 gate_char16_t* ptr;
1831 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint64_t, num, gate_str16_reverse);
1832 }
1833 return ret;
1834 }
1835 gate_size_t gate_str16_print_int64(gate_char16_t* dst, gate_size_t dstlen, gate_int64_t num)
1836 {
1837 gate_size_t ret = 0;
1838 if ((dst != NULL) && (dstlen != 0))
1839 {
1840 gate_uint64_t unum;
1841 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint64_t, gate_str16_print_uint64);
1842 }
1843 return ret;
1844 }
1845
1846
1847 gate_size_t gate_str32_print_uint16(gate_char32_t* dst, gate_size_t dstlen, gate_uint16_t num)
1848 {
1849 gate_size_t ret = 0;
1850 if ((dst != NULL) && (dstlen != 0))
1851 {
1852 gate_char32_t* ptr;
1853 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint16_t, num, gate_str32_reverse);
1854 }
1855 return ret;
1856 }
1857 gate_size_t gate_str32_print_int16(gate_char32_t* dst, gate_size_t dstlen, gate_int16_t num)
1858 {
1859 gate_size_t ret = 0;
1860 if ((dst != NULL) && (dstlen != 0))
1861 {
1862 gate_uint16_t unum;
1863 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint16_t, gate_str32_print_uint16);
1864 }
1865 return ret;
1866 }
1867 gate_size_t gate_str32_print_uint32(gate_char32_t* dst, gate_size_t dstlen, gate_uint32_t num)
1868 {
1869 gate_size_t ret = 0;
1870 if ((dst != NULL) && (dstlen != 0))
1871 {
1872 gate_char32_t* ptr;
1873 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint32_t, num, gate_str32_reverse);
1874 }
1875 return ret;
1876 }
1877 gate_size_t gate_str32_print_int32(gate_char32_t* dst, gate_size_t dstlen, gate_int32_t num)
1878 {
1879 gate_size_t ret = 0;
1880 if ((dst != NULL) && (dstlen != 0))
1881 {
1882 gate_uint32_t unum;
1883 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint32_t, gate_str32_print_uint32);
1884 }
1885 return ret;
1886 }
1887 gate_size_t gate_str32_print_uint64(gate_char32_t* dst, gate_size_t dstlen, gate_uint64_t num)
1888 {
1889 gate_size_t ret = 0;
1890 if ((dst != NULL) && (dstlen != 0))
1891 {
1892 gate_char32_t* ptr;
1893 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint64_t, num, gate_str32_reverse);
1894 }
1895 return ret;
1896 }
1897 gate_size_t gate_str32_print_int64(gate_char32_t* dst, gate_size_t dstlen, gate_int64_t num)
1898 {
1899 gate_size_t ret = 0;
1900 if ((dst != NULL) && (dstlen != 0))
1901 {
1902 gate_uint64_t unum;
1903 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint64_t, gate_str32_print_uint64);
1904 }
1905 return ret;
1906 }
1907
1908
1909
1910
1911 504 gate_size_t gate_str_print_uint(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num, gate_size_t intlen)
1912 {
1913 504 gate_size_t ret = 0;
1914 gate_char8_t buffer[24];
1915 504 gate_char8_t* ptr = &buffer[0];
1916 504 gate_size_t bytesused = gate_str_print_uint64(ptr, sizeof(buffer), num);
1917
1918
2/2
✓ Branch 0 taken 314 times.
✓ Branch 1 taken 190 times.
504 if (intlen > 0)
1919 {
1920
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 124 times.
314 if (intlen > bytesused)
1921 {
1922 gate_size_t ndx;
1923
3/4
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
390 for (ndx = bytesused; (ndx < intlen) && (dstlen != 0); ++ndx)
1924 {
1925 200 *dst = '0';
1926 200 ++dst;
1927 200 --dstlen;
1928 200 ++ret;
1929 }
1930 }
1931
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 120 times.
124 else if (bytesused > intlen)
1932 {
1933 4 ptr += (bytesused - intlen);
1934 4 bytesused -= intlen;
1935 }
1936 }
1937
1938
2/2
✓ Branch 0 taken 502 times.
✓ Branch 1 taken 2 times.
504 if (dstlen >= bytesused)
1939 {
1940 502 gate_mem_copy(dst, ptr, bytesused);
1941 502 ret += bytesused;
1942 502 dst += bytesused;
1943 502 dstlen -= bytesused;
1944 }
1945
1946
2/2
✓ Branch 0 taken 447 times.
✓ Branch 1 taken 57 times.
504 if (dstlen != 0)
1947 {
1948 447 *dst = '\0';
1949 }
1950 504 return ret;
1951
1952 }
1953
1954 11 static gate_size_t gate_str_print_grouped(char* bufferptr, gate_size_t bufferlen, char const* src, gate_size_t srclen, gate_size_t grouplen)
1955 {
1956 11 gate_size_t ret = 0;
1957 11 gate_size_t count = 0;
1958 11 gate_size_t mod = 0;
1959 gate_size_t len;
1960 gate_size_t ndx;
1961
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (grouplen != 0)
1962 {
1963 11 count = srclen / grouplen;
1964 11 mod = srclen % grouplen;
1965 }
1966
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 if (mod != 0)
1967 {
1968 8 len = gate_str_print_text(&bufferptr[ret], bufferlen - ret, src, mod);
1969 8 ret += len;
1970
1971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (count != 0)
1972 {
1973 bufferptr[ret] = ' ';
1974 ++ret;
1975 }
1976
1977 8 src += mod;
1978 8 srclen -= mod;
1979 }
1980
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 11 times.
15 for (ndx = 0; ndx != count; )
1981 {
1982 4 ++ndx;
1983 4 len = gate_str_print_text(&bufferptr[ret], bufferlen - ret, src, grouplen);
1984 4 ret += len;
1985
1986
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (ndx != count)
1987 {
1988 1 bufferptr[ret] = ' ';
1989 1 ++ret;
1990 }
1991
1992 4 src += mod;
1993 4 srclen -= mod;
1994 }
1995 11 return ret;
1996 }
1997
1998 305 gate_size_t gate_str_print_real(gate_char8_t* dst, gate_size_t dstlen, gate_real64_t num,
1999 unsigned intlen, unsigned decimallen, unsigned grouplen)
2000 {
2001 305 gate_size_t ret = 0;
2002 gate_real64_t decimalnum;
2003 gate_real64_t factor;
2004 int infini;
2005 gate_char8_t intbuffer[64];
2006 gate_char8_t decimalbuffer[64];
2007 gate_char8_t buffer[64];
2008 305 gate_char8_t* bufferptr = &buffer[0];
2009 305 gate_size_t bufferlen = sizeof(buffer) - 1;
2010
2011 305 gate_size_t intcount = 0;
2012 305 gate_size_t decimalcount = 0;
2013 305 gate_size_t bufferused = 0;
2014 gate_size_t ndx;
2015
2016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 305 times.
305 if (dstlen < 3)
2017 {
2018 return 0;
2019 }
2020
2021
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 305 times.
305 if (gate_math_isnan(num))
2022 {
2023 return gate_str_print_text(dst, dstlen, "NaN", 3);
2024 }
2025 305 infini = gate_math_isinfinite(num);
2026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 305 times.
305 if (infini > 0)
2027 {
2028 return gate_str_print_text(dst, dstlen, "Inf+", 4);
2029 }
2030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 305 times.
305 else if (infini < 0)
2031 {
2032 return gate_str_print_text(dst, dstlen, "Inf-", 4);
2033 }
2034
2035
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 305 times.
305 if (gate_math_iszero(num))
2036 {
2037 intbuffer[0] = '0';
2038 intcount = 1;
2039 }
2040 else
2041 {
2042
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 303 times.
305 if (num < 0.0)
2043 {
2044 2 *bufferptr = '-';
2045 2 ++bufferptr;
2046 2 --bufferlen;
2047 2 num = -num;
2048 }
2049
2050 305 intcount = gate_str_print_uint64(intbuffer, sizeof(intbuffer) - 1, (gate_uint64_t)num);
2051 305 decimalnum = num - (gate_real64_t)(gate_int64_t)num;
2052 305 factor = 1.0;
2053
3/4
✓ Branch 1 taken 1450 times.
✓ Branch 2 taken 305 times.
✓ Branch 3 taken 1450 times.
✗ Branch 4 not taken.
1755 while (!gate_math_iszerof((gate_real32_t)(decimalnum * factor)) && (decimalcount < sizeof(decimalbuffer) - 1))
2054 {
2055 1450 factor *= 0.1;
2056 1450 decimalnum *= 10.0;
2057 1450 decimalbuffer[decimalcount] = '0' + (gate_char8_t)(gate_uint64_t)decimalnum;
2058 1450 ++decimalcount;
2059 1450 decimalnum -= (gate_real64_t)(gate_int64_t)decimalnum;
2060 }
2061 }
2062
2063
2064
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 304 times.
305 if (intlen > 0)
2065 {
2066 1 ret = 0;
2067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (intlen > intcount)
2068 {
2069 for (ndx = 0; ndx < (intlen - intcount); ++ndx)
2070 {
2071 *dst = '0';
2072 ++dst;
2073 --dstlen;
2074 ++ret;
2075 }
2076 ndx = gate_str_print_text(bufferptr, bufferlen, intbuffer, intcount);
2077 }
2078 else
2079 {
2080
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (grouplen != 0)
2081 {
2082 1 ndx = gate_str_print_grouped(bufferptr, bufferlen, &intbuffer[intcount - intlen], intlen, grouplen);
2083 }
2084 else
2085 {
2086 ndx = gate_str_print_text(bufferptr, bufferlen, &intbuffer[intcount - intlen], intlen);
2087 }
2088 }
2089 }
2090 else
2091 {
2092
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 294 times.
304 if (grouplen != 0)
2093 {
2094 10 ndx = gate_str_print_grouped(bufferptr, bufferlen, &intbuffer[0], intcount, grouplen);
2095 }
2096 else
2097 {
2098 294 ndx = gate_str_print_text(bufferptr, bufferlen, &intbuffer[0], intcount);
2099 }
2100 }
2101 305 bufferptr += ndx;
2102 305 bufferlen -= ndx;
2103 305 bufferused += ndx;
2104
2105
2106
2107
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
305 if ((decimallen > 0) || (decimalcount > 0))
2108 {
2109 301 *bufferptr = '.';
2110 301 ++bufferptr;
2111 301 --bufferlen;
2112 301 ++bufferused;
2113
2114
2/2
✓ Branch 0 taken 297 times.
✓ Branch 1 taken 4 times.
301 if (decimallen > 0)
2115 {
2116
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 200 times.
297 if (decimallen > decimalcount)
2117 {
2118 97 ndx = gate_str_print_text(bufferptr, bufferlen, &decimalbuffer[0], decimalcount);
2119
2/2
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 97 times.
578 for (; ndx < decimallen; ++ndx)
2120 {
2121 481 bufferptr[ndx] = '0';
2122 }
2123 }
2124 else
2125 {
2126 200 ndx = gate_str_print_text(bufferptr, bufferlen, &decimalbuffer[0], decimallen);
2127 }
2128 }
2129 else
2130 {
2131 4 ndx = gate_str_print_text(bufferptr, bufferlen, &decimalbuffer[0], decimalcount);
2132 }
2133 301 bufferptr += ndx;
2134 301 bufferlen -= ndx;
2135 301 bufferused += ndx;
2136 }
2137
2138 305 return gate_str_print_text(dst, dstlen, &buffer[0], bufferused);
2139 }
2140
2141 468 gate_char8_t gate_str_print_hex_nibble(gate_uint8_t nibble, gate_bool_t uppercase)
2142 {
2143
2/2
✓ Branch 0 taken 402 times.
✓ Branch 1 taken 66 times.
468 if (nibble < 10)
2144 {
2145 402 return '0' + nibble;
2146 }
2147 else
2148 {
2149
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 42 times.
66 if (uppercase)
2150 {
2151 24 return 'A' + (nibble - 10);
2152 }
2153 else
2154 {
2155 42 return 'a' + (nibble - 10);
2156 }
2157 }
2158 }
2159
2160 228 gate_size_t gate_str_print_hex_byte(gate_char8_t* dst, gate_size_t dstlen, gate_uint8_t num, gate_bool_t uppercase)
2161 {
2162
2/4
✓ Branch 0 taken 228 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
228 if ((dst == NULL) || (dstlen < 2))
2163 {
2164 return 0;
2165 }
2166 228 dst[0] = gate_str_print_hex_nibble((gate_uint8_t)((num >> 4) & 0x0f), uppercase);
2167 228 dst[1] = gate_str_print_hex_nibble((gate_uint8_t)((num) & 0x0f), uppercase);
2168
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 208 times.
228 if (dstlen > 2)
2169 {
2170 20 dst[2] = '\0';
2171 }
2172 228 return 2;
2173 }
2174 71 gate_size_t gate_str_print_hex(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num, gate_size_t numlen, gate_bool_t uppercase)
2175 {
2176 71 gate_size_t cnt = 8;
2177 gate_uint8_t bytes[8];
2178 71 gate_uint8_t* ptr = &bytes[0];
2179
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 if (numlen < 8)
2180 {
2181 71 ptr += 8 - numlen;
2182 71 cnt -= 8 - numlen;
2183 }
2184 71 bytes[0] = (gate_uint8_t)((num >> 56) & 0xff);
2185 71 bytes[1] = (gate_uint8_t)((num >> 48) & 0xff);
2186 71 bytes[2] = (gate_uint8_t)((num >> 40) & 0xff);
2187 71 bytes[3] = (gate_uint8_t)((num >> 32) & 0xff);
2188 71 bytes[4] = (gate_uint8_t)((num >> 24) & 0xff);
2189 71 bytes[5] = (gate_uint8_t)((num >> 16) & 0xff);
2190 71 bytes[6] = (gate_uint8_t)((num >> 8) & 0xff);
2191 71 bytes[7] = (gate_uint8_t)((num) & 0xff);
2192
2/4
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
71 if ((dst == NULL) || (dstlen < cnt * 2))
2193 {
2194 return 0;
2195 }
2196
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 18 times.
71 if (dstlen > cnt * 2)
2197 {
2198 53 dst[cnt * 2] = 0;
2199 }
2200 71 dstlen = cnt * 2;
2201
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 71 times.
203 while (cnt != 0)
2202 {
2203 132 gate_str_print_hex_byte(dst, 2, *ptr, uppercase);
2204 132 dst += 2;
2205 132 ++ptr;
2206 132 --cnt;
2207 }
2208 71 return dstlen;
2209 }
2210 5 gate_size_t gate_str_print_hex_num(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num, gate_bool_t uppercase)
2211 {
2212 5 gate_size_t numlen = 8;
2213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (num < 256) { numlen = 1; }
2214
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 else if (num < 65536) { numlen = 2; }
2215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 else if (num < 16777216) { numlen = 3; }
2216
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if (num < 4294967296) { numlen = 4; }
2217 else if (num < 4294967296 * 256) { numlen = 5; }
2218 else if (num < 4294967296 * 256 * 256) { numlen = 6; }
2219 else if (num < 4294967296 * 256 * 256 * 256) { numlen = 7; }
2220
2221 5 return gate_str_print_hex(dst, dstlen, num, numlen, uppercase);
2222 }
2223 36 gate_size_t gate_str_print_hex_uint16(gate_char8_t* dst, gate_size_t dstlen, gate_uint16_t num, gate_bool_t uppercase)
2224 {
2225 36 return gate_str_print_hex(dst, dstlen, num, 2, uppercase);
2226 }
2227 6 gate_size_t gate_str_print_hex_uint32(gate_char8_t* dst, gate_size_t dstlen, gate_uint32_t num, gate_bool_t uppercase)
2228 {
2229 6 return gate_str_print_hex(dst, dstlen, num, 4, uppercase);
2230 }
2231 gate_size_t gate_str_print_hex_uint64(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num, gate_bool_t uppercase)
2232 {
2233 return gate_str_print_hex(dst, dstlen, num, 8, uppercase);
2234 }
2235
2236 gate_size_t gate_str_print_hex_buffer(gate_char8_t* dst, gate_size_t dstlen, void const* buffer, gate_size_t bufferlen, gate_bool_t uppercase)
2237 {
2238 gate_size_t ret = 0;
2239 gate_uint8_t const* ptr = (gate_uint8_t const*)buffer;
2240 while ((dstlen > 1) && (bufferlen != 0))
2241 {
2242 gate_str_print_hex_byte(dst, dstlen, *ptr, uppercase);
2243 dst += 2;
2244 dstlen -= 2;
2245 ret += 2;
2246 ++ptr;
2247 --bufferlen;
2248 }
2249 if (dstlen != 0)
2250 {
2251 *dst = 0;
2252 }
2253 return ret;
2254 }
2255
2256 110 gate_size_t gate_str_print_to(gate_str_printer_t printer, void* printer_param, va_list vl)
2257 {
2258 110 gate_size_t used = 0;
2259 110 gate_bool_t continue_loop = true;
2260 char buffer[512];
2261
2262 /* INFO: types small than [int] are converted to [int]
2263 https://stackoverflow.com/questions/23983471/char-is-promoted-to-int-when-passed-through-in-c
2264 */
2265
2/2
✓ Branch 0 taken 755 times.
✓ Branch 1 taken 110 times.
865 while (continue_loop)
2266 {
2267 755 int print_type = va_arg(vl, int);
2268 755 char const* ptr_text = NULL;
2269 755 gate_size_t text_len = 0;
2270
2271
11/25
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
✓ Branch 6 taken 340 times.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 36 times.
✓ Branch 14 taken 6 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 76 times.
✓ Branch 17 taken 16 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
755 switch (print_type)
2272 {
2273 110 case GATE_PRINT_END:
2274 {
2275 110 text_len = 0;
2276 110 continue_loop = false;
2277 110 break;
2278 }
2279 3 case GATE_PRINT_CHAR:
2280 {
2281 3 buffer[0] = (char)va_arg(vl, int);
2282 3 ptr_text = &buffer[0];
2283 3 text_len = 1;
2284 3 break;
2285 }
2286 18 case GATE_PRINT_NEWLINE:
2287 {
2288 18 ptr_text = GATE_STR_NEWLINE;
2289 18 text_len = GATE_STR_NEWLINE_LENGTH;
2290 18 break;
2291 }
2292 case GATE_PRINT_CR:
2293 {
2294 ptr_text = GATE_STR_CR;
2295 text_len = 1;
2296 break;
2297 }
2298 case GATE_PRINT_LF:
2299 {
2300 ptr_text = GATE_STR_LF;
2301 text_len = 1;
2302 break;
2303 }
2304 18 case GATE_PRINT_CRLF:
2305 {
2306 18 ptr_text = GATE_STR_CRLF;
2307 18 text_len = 2;
2308 18 break;
2309 }
2310 340 case GATE_PRINT_CSTR:
2311 {
2312 340 char const* val_cstr = va_arg(vl, char const*);
2313 340 ptr_text = val_cstr;
2314 340 text_len = gate_str_length(val_cstr);
2315 340 break;
2316 }
2317 116 case GATE_PRINT_STRING:
2318 {
2319 116 gate_string_t const* val_str = va_arg(vl, gate_string_t const*);
2320 116 ptr_text = gate_string_ptr(val_str, 0);
2321 116 text_len = gate_string_length(val_str);
2322 116 break;
2323 }
2324 case GATE_PRINT_BOOL:
2325 {
2326 gate_bool_t val_bool = (gate_bool_t)va_arg(vl, int);
2327 ptr_text = val_bool ? "true" : "false";
2328 text_len = val_bool ? 4 : 5;
2329 break;
2330 }
2331 case GATE_PRINT_I8:
2332 {
2333 gate_int8_t val_i8 = (gate_int8_t)va_arg(vl, int);
2334 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i8);
2335 ptr_text = buffer;
2336 break;
2337 }
2338 16 case GATE_PRINT_UI8:
2339 {
2340 16 gate_uint8_t val_ui8 = (gate_uint8_t)va_arg(vl, int);
2341 16 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui8);
2342 16 ptr_text = buffer;
2343 16 break;
2344 }
2345 case GATE_PRINT_I16:
2346 {
2347 gate_int16_t val_i16 = (gate_int16_t)va_arg(vl, int);
2348 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i16);
2349 ptr_text = buffer;
2350 break;
2351 }
2352 case GATE_PRINT_UI16:
2353 {
2354 gate_uint16_t val_ui16 = (gate_uint16_t)va_arg(vl, int);
2355 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui16);
2356 ptr_text = buffer;
2357 break;
2358 }
2359 36 case GATE_PRINT_I32:
2360 {
2361 36 gate_int32_t val_i32 = va_arg(vl, gate_int32_t);
2362 36 text_len = gate_str_print_int32(buffer, sizeof(buffer), val_i32);
2363 36 ptr_text = buffer;
2364 36 break;
2365 }
2366 6 case GATE_PRINT_UI32:
2367 {
2368 6 gate_uint32_t val_ui32 = va_arg(vl, gate_uint32_t);
2369 6 text_len = gate_str_print_uint32(buffer, sizeof(buffer), val_ui32);
2370 6 ptr_text = buffer;
2371 6 break;
2372 }
2373 case GATE_PRINT_I64:
2374 {
2375 gate_int64_t val_i64 = va_arg(vl, gate_int64_t);
2376 text_len = gate_str_print_int64(buffer, sizeof(buffer), val_i64);
2377 ptr_text = buffer;
2378 break;
2379 }
2380 76 case GATE_PRINT_UI64:
2381 {
2382 76 gate_uint64_t val_ui64 = va_arg(vl, gate_uint64_t);
2383 76 text_len = gate_str_print_uint64(buffer, sizeof(buffer), val_ui64);
2384 76 ptr_text = buffer;
2385 76 break;
2386 }
2387 16 case GATE_PRINT_H8:
2388 {
2389 16 gate_uint8_t val_ui8 = (gate_uint8_t)va_arg(vl, unsigned);
2390 16 text_len = gate_str_print_hex_byte(buffer, sizeof(buffer), val_ui8, false);
2391 16 ptr_text = buffer;
2392 16 break;
2393 }
2394 case GATE_PRINT_H16:
2395 {
2396 gate_uint16_t val_ui16 = (gate_uint16_t)va_arg(vl, unsigned);
2397 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui16, 2, false);
2398 ptr_text = buffer;
2399 break;
2400 }
2401 case GATE_PRINT_H32:
2402 {
2403 gate_uint32_t val_ui32 = va_arg(vl, gate_uint32_t);
2404 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui32, 4, false);
2405 ptr_text = buffer;
2406 break;
2407 }
2408 case GATE_PRINT_H64:
2409 {
2410 gate_uint64_t val_ui64 = va_arg(vl, gate_uint64_t);
2411 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui64, 8, false);
2412 ptr_text = buffer;
2413 break;
2414 }
2415 case GATE_PRINT_R32:
2416 {
2417 gate_real32_t val_r32 = (gate_real32_t)va_arg(vl, double);
2418 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r32, 0, 6, 0);
2419 ptr_text = buffer;
2420 break;
2421 }
2422 case GATE_PRINT_R64:
2423 {
2424 gate_real64_t val_r64 = va_arg(vl, gate_real64_t);
2425 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r64, 0, 6, 0);
2426 ptr_text = buffer;
2427 break;
2428 }
2429 case GATE_PRINT_ADDRESS:
2430 {
2431 void* val_ptr = va_arg(vl, void*);
2432 text_len = gate_str_print_hex(buffer, sizeof(buffer), (gate_uint64_t)(gate_uintptr_t)val_ptr, sizeof(val_ptr) * 2, true);
2433 ptr_text = buffer;
2434 break;
2435 }
2436 default:
2437 {
2438 text_len = 0;
2439 continue_loop = false;
2440 break;
2441 }
2442 }
2443
2/2
✓ Branch 0 taken 642 times.
✓ Branch 1 taken 113 times.
755 if (text_len > 0)
2444 {
2445 642 gate_size_t chars_printed = printer(printer_param, ptr_text, text_len);
2446 642 used += chars_printed;
2447 }
2448 }
2449 110 return used;
2450 }
2451
2452 struct gate_str_printer_param
2453 {
2454 gate_char8_t* dst;
2455 gate_size_t dstlen;
2456 };
2457
2458 119 static gate_size_t gate_str_printer_callback(void* printer_param, gate_char8_t const* data, gate_size_t data_len)
2459 {
2460 119 struct gate_str_printer_param* param = (struct gate_str_printer_param*)printer_param;
2461 119 gate_size_t len_printed = gate_str_print_text(param->dst, param->dstlen, data, data_len);
2462 119 param->dst += len_printed;
2463 119 param->dstlen -= len_printed;
2464 119 return len_printed;
2465 }
2466
2467 42 gate_size_t gate_str_print(gate_char8_t* dst, gate_size_t dstlen, ...)
2468 {
2469 struct gate_str_printer_param param;
2470 42 gate_size_t ret = 0;
2471 va_list vl;
2472
2473 42 va_start(vl, dstlen);
2474
2475 42 param.dst = dst;
2476 42 param.dstlen = dstlen;
2477 42 ret = gate_str_print_to(&gate_str_printer_callback, &param, vl);
2478
2479 42 va_end(vl);
2480 42 return ret;
2481 }
2482
2483 9 gate_size_t gate_str_print_values(gate_char8_t* dst, gate_size_t dstlen, gate_print_value_t const* values, gate_size_t values_count)
2484 {
2485 9 gate_size_t used = 0;
2486 9 gate_bool_t continue_loop = true;
2487 gate_bool_t val_bool;
2488 gate_string_t const* val_str;
2489 gate_int8_t val_i8;
2490 gate_uint8_t val_ui8;
2491 gate_int16_t val_i16;
2492 gate_uint16_t val_ui16;
2493 gate_int32_t val_i32;
2494 gate_uint32_t val_ui32;
2495 gate_int64_t val_i64;
2496 gate_uint64_t val_ui64;
2497 gate_real32_t val_r32;
2498 gate_real64_t val_r64;
2499 9 char const* ptr_text = NULL;
2500 char buffer[512];
2501 gate_size_t text_len;
2502 gate_size_t chars_printed;
2503
2504
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 while ((values_count-- != 0) && continue_loop)
2505 {
2506 9 ptr_text = NULL;
2507 9 text_len = 0;
2508
9/25
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
9 switch (values->value_type)
2509 {
2510 case GATE_PRINT_END:
2511 {
2512 text_len = 0;
2513 continue_loop = false;
2514 break;
2515 }
2516 case GATE_PRINT_CHAR:
2517 {
2518 ptr_text = (char const*)values->value_ptr;
2519 text_len = 1;
2520 break;
2521 }
2522 case GATE_PRINT_NEWLINE:
2523 {
2524 ptr_text = GATE_STR_NEWLINE;
2525 text_len = GATE_STR_NEWLINE_LENGTH;
2526 break;
2527 }
2528 case GATE_PRINT_CR:
2529 {
2530 ptr_text = GATE_STR_CR;
2531 text_len = 1;
2532 break;
2533 }
2534 case GATE_PRINT_LF:
2535 {
2536 ptr_text = GATE_STR_LF;
2537 text_len = 1;
2538 break;
2539 }
2540 case GATE_PRINT_CRLF:
2541 {
2542 ptr_text = GATE_STR_CRLF;
2543 text_len = 2;
2544 break;
2545 }
2546 case GATE_PRINT_CSTR:
2547 {
2548 ptr_text = (char const*)values->value_ptr;
2549 text_len = gate_str_length(ptr_text);
2550 break;
2551 }
2552 case GATE_PRINT_STRING:
2553 {
2554 val_str = (gate_string_t const*)values->value_ptr;
2555 ptr_text = val_str->str;
2556 text_len = val_str->length;
2557 break;
2558 }
2559 1 case GATE_PRINT_BOOL:
2560 {
2561 1 val_bool = *(gate_bool_t const*)values->value_ptr;
2562
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ptr_text = val_bool ? "true" : "false";
2563
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 text_len = val_bool ? 4 : 5;
2564 1 break;
2565 }
2566 1 case GATE_PRINT_I8:
2567 {
2568 1 val_i8 = *(gate_int8_t const*)values->value_ptr;
2569 1 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i8);
2570 1 ptr_text = buffer;
2571 1 break;
2572 }
2573 1 case GATE_PRINT_UI8:
2574 {
2575 1 val_ui8 = *(gate_uint8_t const*)values->value_ptr;
2576 1 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui8);
2577 1 ptr_text = buffer;
2578 1 break;
2579 }
2580 1 case GATE_PRINT_I16:
2581 {
2582 1 val_i16 = *(gate_int16_t const*)values->value_ptr;
2583 1 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i16);
2584 1 ptr_text = buffer;
2585 1 break;
2586 }
2587 1 case GATE_PRINT_UI16:
2588 {
2589 1 val_ui16 = *(gate_uint16_t const*)values->value_ptr;
2590 1 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui16);
2591 1 ptr_text = buffer;
2592 1 break;
2593 }
2594 1 case GATE_PRINT_I32:
2595 {
2596 1 val_i32 = *(gate_int32_t const*)values->value_ptr;
2597 1 text_len = gate_str_print_int32(buffer, sizeof(buffer), val_i32);
2598 1 ptr_text = buffer;
2599 1 break;
2600 }
2601 1 case GATE_PRINT_UI32:
2602 {
2603 1 val_ui32 = *(gate_uint32_t const*)values->value_ptr;
2604 1 text_len = gate_str_print_uint32(buffer, sizeof(buffer), val_ui32);
2605 1 ptr_text = buffer;
2606 1 break;
2607 }
2608 1 case GATE_PRINT_I64:
2609 {
2610 1 val_i64 = *(gate_int64_t const*)values->value_ptr;
2611 1 text_len = gate_str_print_int64(buffer, sizeof(buffer), val_i64);
2612 1 ptr_text = buffer;
2613 1 break;
2614 }
2615 1 case GATE_PRINT_UI64:
2616 {
2617 1 val_ui64 = *(gate_uint64_t const*)values->value_ptr;
2618 1 text_len = gate_str_print_uint64(buffer, sizeof(buffer), val_ui64);
2619 1 ptr_text = buffer;
2620 1 break;
2621 }
2622 case GATE_PRINT_H8:
2623 {
2624 val_ui8 = *(gate_uint8_t const*)values->value_ptr;
2625 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui8, 1, false);
2626 ptr_text = buffer;
2627 break;
2628 }
2629 case GATE_PRINT_H16:
2630 {
2631 val_ui16 = *(gate_uint16_t const*)values->value_ptr;
2632 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui16, 2, false);
2633 ptr_text = buffer;
2634 break;
2635 }
2636 case GATE_PRINT_H32:
2637 {
2638 val_ui32 = *(gate_uint32_t const*)values->value_ptr;
2639 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui32, 4, false);
2640 ptr_text = buffer;
2641 break;
2642 }
2643 case GATE_PRINT_H64:
2644 {
2645 val_ui64 = *(gate_uint64_t const*)values->value_ptr;
2646 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui64, 8, false);
2647 ptr_text = buffer;
2648 break;
2649 }
2650 case GATE_PRINT_R32:
2651 {
2652 val_r32 = *(gate_real32_t const*)values->value_ptr;
2653 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r32, 0, 6, 0);
2654 ptr_text = buffer;
2655 break;
2656 }
2657 case GATE_PRINT_R64:
2658 {
2659 val_r64 = *(gate_real64_t const*)values->value_ptr;
2660 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r64, 0, 6, 0);
2661 ptr_text = buffer;
2662 break;
2663 }
2664 case GATE_PRINT_ADDRESS:
2665 {
2666 text_len = gate_str_print_hex(buffer, sizeof(buffer), *(gate_uintptr_t*)values->value_ptr, sizeof(gate_uintptr_t) * 2, true);
2667 ptr_text = buffer;
2668 break;
2669 }
2670 default:
2671 {
2672 text_len = 0;
2673 continue_loop = false;
2674 break;
2675 }
2676 }
2677
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (text_len > 0)
2678 {
2679 9 chars_printed = gate_str_print_text(dst, dstlen, ptr_text, text_len);
2680 9 dst += chars_printed;
2681 9 dstlen -= chars_printed;
2682 9 used += chars_printed;
2683 }
2684 9 ++values;
2685 }
2686 9 return used;
2687 }
2688
2689
2690
2691
2692 1435 gate_bool_t gate_str_parse_digit(gate_char8_t const* src, gate_uint8_t* digit)
2693 {
2694 1435 gate_char8_t chr = *src;
2695
4/4
✓ Branch 0 taken 1313 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 1231 times.
✓ Branch 3 taken 82 times.
1435 if ((chr >= '0') && (chr <= '9'))
2696 {
2697 1231 *digit = chr - '0';
2698 1231 return true;
2699 }
2700 else
2701 {
2702 204 return false;
2703 }
2704 }
2705
2706 8 gate_size_t gate_str_parse_bool(gate_char8_t const* src, gate_size_t srclen, gate_bool_t* value)
2707 {
2708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (srclen == 0)
2709 {
2710 *value = false;
2711 return 0;
2712 }
2713
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
8 if (gate_str_starts_with_ic(src, srclen, "false", 5))
2714 {
2715 1 *value = false;
2716 1 return 5;
2717 }
2718
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 if (gate_str_starts_with_ic(src, srclen, "off", 3))
2719 {
2720 1 *value = false;
2721 1 return 3;
2722 }
2723
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
6 if (gate_str_starts_with_ic(src, srclen, "0", 1))
2724 {
2725 1 *value = false;
2726 1 return 1;
2727 }
2728
2729
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
5 if (gate_str_starts_with_ic(src, srclen, "true", 4))
2730 {
2731 1 *value = true;
2732 1 return 4;
2733 }
2734
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (gate_str_starts_with_ic(src, srclen, "on", 2))
2735 {
2736 1 *value = true;
2737 1 return 2;
2738 }
2739
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (gate_str_starts_with_ic(src, srclen, "yes", 3))
2740 {
2741 1 *value = true;
2742 1 return 3;
2743 }
2744
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_str_starts_with_ic(src, srclen, "1", 1))
2745 {
2746 1 *value = true;
2747 1 return 1;
2748 }
2749
2750 /* all other types of string will evaluate to true */
2751 1 *value = false;
2752 1 return srclen;
2753 }
2754
2755
2756 554 gate_size_t gate_str_parse_uint64(gate_char8_t const* src, gate_size_t srclen, gate_uint64_t* num)
2757 {
2758 554 gate_size_t ret = 0;
2759 gate_uint8_t digit;
2760 554 gate_uint64_t tmp = 0;
2761
2/2
✓ Branch 0 taken 1360 times.
✓ Branch 1 taken 360 times.
1720 while (srclen-- != 0)
2762 {
2763
2/2
✓ Branch 1 taken 194 times.
✓ Branch 2 taken 1166 times.
1360 if (!gate_str_parse_digit(src, &digit))
2764 {
2765 194 break;
2766 }
2767 1166 tmp *= 10;
2768 1166 tmp += (gate_uint64_t)digit;
2769 1166 ++src;
2770 1166 ++ret;
2771 }
2772
1/2
✓ Branch 0 taken 554 times.
✗ Branch 1 not taken.
554 if (num != NULL)
2773 {
2774 554 *num = tmp;
2775 }
2776
2777 554 return ret;
2778 }
2779 156 gate_size_t gate_str_parse_int64(gate_char8_t const* src, gate_size_t srclen, gate_int64_t* num)
2780 {
2781 156 gate_size_t ret = 0;
2782 gate_size_t tmpret;
2783 156 gate_uint64_t tmpnum = 0;
2784 156 gate_bool_t neg = false;
2785
2786 156 ret = gate_str_find_first_not_of(src, srclen, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
2787
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 145 times.
156 if (ret == GATE_STR_NPOS)
2788 {
2789 11 return 0;
2790 }
2791 145 src += ret;
2792 145 srclen -= ret;
2793
2794
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 142 times.
145 if (*src == '-')
2795 {
2796 3 neg = true;
2797 3 --srclen;
2798 3 ++src;
2799 3 ++ret;
2800 }
2801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 else if (*src == '+')
2802 {
2803 --srclen;
2804 ++src;
2805 ++ret;
2806 }
2807
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 tmpret = gate_str_parse_uint64(src, srclen, num ? &tmpnum : NULL);
2808
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 127 times.
145 if (tmpret == 0)
2809 {
2810 18 return 0;
2811 }
2812 127 ret += tmpret;
2813
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 if (num != NULL)
2814 {
2815
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 124 times.
127 if (neg)
2816 {
2817 3 *num = -((gate_int64_t)tmpnum);
2818 }
2819 else
2820 {
2821 124 *num = (gate_int64_t)tmpnum;
2822 }
2823 }
2824 127 return ret;
2825 }
2826
2827
2828 39 gate_size_t gate_str_parse_real(gate_char8_t const* src, gate_size_t srclen, gate_real64_t* num)
2829 {
2830 39 gate_int64_t int_part = 0;
2831 gate_uint8_t digit;
2832 39 gate_size_t ret = gate_str_parse_int64(src, srclen, &int_part);
2833 39 gate_bool_t const is_negative = int_part < 0;
2834 39 gate_real64_t a = 0.0;
2835
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 37 times.
39 gate_real64_t b = is_negative ? -1.0 : 1.0;
2836 39 src += ret;
2837 39 srclen -= ret;
2838
2839
4/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 22 times.
39 if ((srclen > 0) && (src[0] == '.'))
2840 {
2841 15 ++ret;
2842 15 ++src;
2843 15 --srclen;
2844
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 5 times.
61 while (srclen > 0)
2845 {
2846
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 46 times.
56 if (!gate_str_parse_digit(src, &digit))
2847 {
2848 10 break;
2849 }
2850 46 ++src;
2851 46 ++ret;
2852 46 --srclen;
2853 46 a *= 10.0;
2854 46 b *= 10.0;
2855 46 a += (gate_real64_t)digit;
2856 }
2857 }
2858
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if (num)
2859 {
2860 39 *num = (gate_real64_t)int_part + a / b;
2861 }
2862 39 return ret;
2863 }
2864
2865 1512 gate_bool_t gate_str_parse_hex_nibble(gate_char8_t chr, gate_uint8_t* value)
2866 {
2867
3/4
✓ Branch 0 taken 1512 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 698 times.
✓ Branch 3 taken 814 times.
1512 if ((chr >= '0') && (chr <= '9'))
2868 {
2869 698 *value = (gate_uint8_t)(chr - '0');
2870 698 return true;
2871 }
2872
4/4
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 777 times.
✓ Branch 3 taken 23 times.
814 else if ((chr >= 'A') && (chr <= 'F'))
2873 {
2874 777 *value = (gate_uint8_t)(chr - 'A' + 10);
2875 777 return true;
2876 }
2877
3/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
37 else if ((chr >= 'a') && (chr <= 'f'))
2878 {
2879 23 *value = (gate_uint8_t)(chr - 'a' + 10);
2880 23 return true;
2881 }
2882 else
2883 {
2884 14 return false;
2885 }
2886 }
2887 68 gate_bool_t gate_str_parse_hex_byte(gate_char8_t const chr[2], gate_uint8_t* value)
2888 {
2889 gate_uint8_t n1, n2;
2890
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
68 if (!gate_str_parse_hex_nibble(chr[0], &n1))
2891 {
2892 return false;
2893 }
2894
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
68 if (!gate_str_parse_hex_nibble(chr[1], &n2))
2895 {
2896 return false;
2897 }
2898 68 *value = n1 * 16 + n2;
2899 68 return true;
2900 }
2901 30 gate_size_t gate_str_parse_hex_int(gate_char8_t const* text, gate_size_t textlen, gate_uint64_t* num)
2902 {
2903 30 gate_size_t ret = 0;
2904 30 gate_uint64_t val = 0;
2905 gate_uint8_t n;
2906
2907
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 16 times.
111 while (textlen-- != 0)
2908 {
2909
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 81 times.
95 if (!gate_str_parse_hex_nibble(*text, &n))
2910 {
2911 14 break;
2912 }
2913 81 val *= 16;
2914 81 val += n;
2915 81 ++ret;
2916 81 ++text;
2917 }
2918
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (num != NULL)
2919 {
2920 30 *num = val;
2921 }
2922 30 return ret;
2923 }
2924 5 gate_size_t gate_str_parse_hex_buffer(gate_char8_t const* text, gate_size_t textlen, gate_char8_t* buffer, gate_size_t bufferlen)
2925 {
2926 5 gate_size_t ret = 0;
2927 gate_uint8_t tmp;
2928
2929
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
21 while ((textlen >= 2) && (bufferlen != 0))
2930 {
2931
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
16 if (!gate_str_parse_hex_byte(text, &tmp))
2932 {
2933 break;
2934 }
2935 16 *buffer = (char)tmp;
2936
2937 16 text += 2;
2938 16 textlen -= 2;
2939
2940 16 ++buffer;
2941 16 --bufferlen;
2942
2943 16 ++ret;
2944 }
2945 5 return ret;
2946 }
2947 2 gate_bool_t gate_str_parse_oct_byte(gate_char8_t const chr[3], gate_uint8_t* value)
2948 {
2949 2 gate_uint8_t digits[3] = GATE_INIT_EMPTY;
2950
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (gate_str_parse_digit(&chr[0], &digits[0])
2951
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 && gate_str_parse_digit(&chr[1], &digits[1])
2952
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 && gate_str_parse_digit(&chr[2], &digits[2])
2953 )
2954 {
2955 2 *value = (gate_uint8_t)((int)digits[0] * 64 + (int)digits[1] * 8 + (int)digits[2]);
2956 2 return true;
2957 }
2958 return false;
2959 }
2960 156 gate_size_t gate_str_parse_line(gate_char8_t const* text, gate_size_t textlen, gate_char8_t* buffer, gate_size_t* bufferlen)
2961 {
2962 gate_size_t pos;
2963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (textlen == 0)
2964 {
2965 if ((buffer != NULL) && (bufferlen != NULL))
2966 {
2967 if (*bufferlen > 0)
2968 {
2969 buffer[0] = 0;
2970 *bufferlen = 0;
2971 }
2972 }
2973 return 0;
2974 }
2975 else
2976 {
2977 156 pos = gate_str_char_pos(text, textlen, '\n', 0);
2978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (pos == GATE_STR_NPOS)
2979 {
2980 if ((buffer != NULL) && (bufferlen != NULL))
2981 {
2982 if (*bufferlen < textlen)
2983 {
2984 gate_mem_copy(buffer, text, *bufferlen);
2985 buffer[*bufferlen] = 0;
2986 return *bufferlen;
2987 }
2988 else
2989 {
2990 gate_mem_copy(buffer, text, textlen);
2991 if (*bufferlen > textlen)
2992 {
2993 buffer[textlen] = 0;
2994 }
2995 *bufferlen = textlen;
2996 }
2997 }
2998
2999 return textlen;
3000 }
3001 else
3002 {
3003
2/4
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 156 times.
✗ Branch 3 not taken.
156 if ((buffer != NULL) && (bufferlen != NULL))
3004 {
3005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (*bufferlen < pos)
3006 {
3007 gate_mem_copy(buffer, text, *bufferlen);
3008 return *bufferlen;
3009 }
3010 else
3011 {
3012 156 gate_mem_copy(buffer, text, pos);
3013
1/2
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
156 if (*bufferlen > pos)
3014 {
3015 156 buffer[pos] = 0;
3016 }
3017 156 *bufferlen = pos;
3018
1/2
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
156 if (pos > 0)
3019 {
3020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 if (buffer[pos - 1] == '\r')
3021 {
3022 buffer[pos - 1] = 0;
3023 --*bufferlen;
3024 }
3025 }
3026 }
3027 }
3028 156 return pos + 1;
3029 }
3030 }
3031 }
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042 /************************
3043 * String implementation *
3044 *************************/
3045
3046 2670 gate_string_t* gate_string_create(gate_string_t* obj, gate_char8_t const* str, gate_size_t len)
3047 {
3048
2/2
✓ Branch 0 taken 1890 times.
✓ Branch 1 taken 780 times.
2670 if (len > 0)
3049 {
3050 1890 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + len + 1);
3051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1890 times.
1890 if (obj->buffer == NULL)
3052 {
3053 return NULL;
3054 }
3055 1890 gate_mem_copy(&obj->buffer->data[0], str, len);
3056 1890 obj->buffer->data[len] = 0;
3057 1890 obj->str = &obj->buffer->data[0];
3058 1890 obj->length = len;
3059 1890 gate_atomic_int_init(&obj->buffer->refcount, 1);
3060 }
3061 else
3062 {
3063 780 gate_string_create_empty(obj);
3064 }
3065
3066 2670 return obj;
3067 }
3068 6099 gate_string_t* gate_string_create_static_len(gate_string_t* obj, gate_char8_t const* str, gate_size_t len)
3069 {
3070 6099 obj->str = str;
3071 6099 obj->length = len;
3072 6099 obj->buffer = NULL;
3073 6099 return obj;
3074 }
3075 2919 gate_string_t* gate_string_create_static(gate_string_t* obj, gate_char8_t const* str)
3076 {
3077
2/2
✓ Branch 0 taken 2903 times.
✓ Branch 1 taken 16 times.
2919 return gate_string_create_static_len(obj, str, (str == NULL) ? 0 : gate_str_length(str));
3078 }
3079 4709 gate_string_t* gate_string_create_empty(gate_string_t* obj)
3080 {
3081 4709 obj->str = NULL;
3082 4709 obj->length = 0;
3083 4709 obj->buffer = NULL;
3084 4709 return obj;
3085 }
3086 1 gate_string_t* gate_string_create_utf16(gate_string_t* obj, gate_char16_t const* str, gate_size_t len)
3087 {
3088 gate_char32_t chr32;
3089 1 gate_size_t processed16 = 0;
3090 gate_size_t decoded;
3091 gate_char8_t buffer[16];
3092 gate_size_t encoded;
3093 1 gate_size_t required8 = 0;
3094 1 gate_size_t used8 = 0;
3095 1 char* ptr = NULL;
3096
3097
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 while (processed16 < len)
3098 {
3099 5 decoded = gate_char_read_utf16(&str[processed16], len - processed16, &chr32);
3100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (decoded == 0)
3101 {
3102 break;
3103 }
3104
3105 5 processed16 += decoded;
3106 5 encoded = gate_char_write_utf8(chr32, buffer, sizeof(buffer));
3107 5 required8 += encoded;
3108 }
3109
3110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (required8 == 0)
3111 {
3112 gate_string_create_empty(obj);
3113 }
3114 else
3115 {
3116 1 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + required8 + 1);
3117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (obj->buffer == NULL)
3118 {
3119 return NULL;
3120 }
3121 1 processed16 = 0;
3122 1 ptr = &obj->buffer->data[0];
3123
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
6 while ((processed16 < len) && (used8 < required8))
3124 {
3125 5 decoded = gate_char_read_utf16(&str[processed16], len - processed16, &chr32);
3126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (decoded == 0)
3127 {
3128 break;
3129 }
3130
3131 5 processed16 += decoded;
3132 5 encoded = gate_char_write_utf8(chr32, ptr, required8 - used8);
3133 5 used8 += encoded;
3134 5 ptr += encoded;
3135 }
3136 1 *ptr = 0;
3137
3138 1 obj->str = &obj->buffer->data[0];
3139 1 obj->length = used8;
3140 1 gate_atomic_int_init(&obj->buffer->refcount, 1);
3141 }
3142
3143 1 return obj;
3144 }
3145 2 gate_string_t* gate_string_create_utf32(gate_string_t* obj, gate_char32_t const* str, gate_size_t len)
3146 {
3147 2 gate_size_t processed32 = 0;
3148 gate_char8_t buffer[16];
3149 gate_size_t encoded;
3150 2 gate_size_t required8 = 0;
3151 2 gate_size_t used8 = 0;
3152 2 char* ptr = NULL;
3153
3154
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 while (processed32 < len)
3155 {
3156 9 encoded = gate_char_write_utf8(str[processed32], buffer, sizeof(buffer));
3157 9 ++processed32;
3158 9 required8 += encoded;
3159 }
3160
3161 2 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + required8 + 1);
3162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (obj->buffer == NULL)
3163 {
3164 return NULL;
3165 }
3166
3167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (required8 == 0)
3168 {
3169 gate_string_create_empty(obj);
3170 }
3171 else
3172 {
3173 2 processed32 = 0;
3174 2 ptr = &obj->buffer->data[0];
3175
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
11 while ((processed32 < len) && (used8 < required8))
3176 {
3177 9 encoded = gate_char_write_utf8(str[processed32], ptr, required8 - used8);
3178 9 ++processed32;
3179 9 used8 += encoded;
3180 9 ptr += encoded;
3181 }
3182 2 *ptr = 0;
3183
3184 2 obj->str = &obj->buffer->data[0];
3185 2 obj->length = used8;
3186 2 gate_atomic_int_init(&obj->buffer->refcount, 1);
3187 }
3188
3189 2 return obj;
3190
3191 }
3192 14 gate_string_t* gate_string_create_copy(gate_string_t* obj, gate_string_t const* src)
3193 {
3194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (src == NULL)
3195 {
3196 return gate_string_create_empty(obj);
3197 }
3198 else
3199 {
3200 14 return gate_string_create(obj, src->str, src->length);
3201 }
3202 }
3203
3204
3205
3206 26544 void gate_string_release(gate_string_t* obj)
3207 {
3208
2/2
✓ Branch 0 taken 16400 times.
✓ Branch 1 taken 10144 times.
26544 if (obj->buffer != NULL)
3209 {
3210
2/2
✓ Branch 1 taken 2678 times.
✓ Branch 2 taken 13722 times.
16400 if (gate_atomic_int_dec(&obj->buffer->refcount) == 0)
3211 {
3212 2678 gate_mem_dealloc(obj->buffer);
3213 }
3214 16400 obj->buffer = NULL;
3215 }
3216 26544 obj->str = NULL;
3217 26544 obj->length = 0;
3218 26544 }
3219
3220 4770 gate_bool_t gate_string_is_empty(gate_string_t const* obj)
3221 {
3222
2/2
✓ Branch 0 taken 4750 times.
✓ Branch 1 taken 20 times.
4770 if (obj != NULL)
3223 {
3224
2/2
✓ Branch 0 taken 4205 times.
✓ Branch 1 taken 545 times.
4750 if (obj->length > 0)
3225 {
3226 4205 return false;
3227 }
3228 }
3229 565 return true;
3230 }
3231
3232 7732 gate_string_t* gate_string_duplicate(gate_string_t* dst, gate_string_t const* src)
3233 {
3234
2/2
✓ Branch 0 taken 7506 times.
✓ Branch 1 taken 226 times.
7732 if (src != NULL)
3235 {
3236 7506 dst->buffer = src->buffer;
3237 7506 dst->str = src->str;
3238 7506 dst->length = src->length;
3239
2/2
✓ Branch 0 taken 6452 times.
✓ Branch 1 taken 1054 times.
7506 if (dst->buffer != NULL)
3240 {
3241 6452 gate_atomic_int_inc(&dst->buffer->refcount);
3242 }
3243 }
3244 else
3245 {
3246 226 dst->buffer = NULL;
3247 226 dst->str = NULL;
3248 226 dst->length = 0;
3249 }
3250 7732 return dst;
3251 }
3252 3708 gate_string_t* gate_string_clone(gate_string_t* dst, gate_string_t const* src)
3253 {
3254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3708 times.
3708 if (src == NULL)
3255 {
3256 return gate_string_create_empty(dst);
3257 }
3258 else
3259 {
3260
2/2
✓ Branch 0 taken 1115 times.
✓ Branch 1 taken 2593 times.
3708 if (src->buffer == NULL)
3261 {
3262 1115 return gate_string_create(dst, src->str, src->length);
3263 }
3264 else
3265 {
3266 2593 dst->str = src->str;
3267 2593 dst->length = src->length;
3268 2593 dst->buffer = src->buffer;
3269 2593 gate_atomic_int_inc(&dst->buffer->refcount);
3270 2593 return dst;
3271 }
3272 }
3273 }
3274
3275 37829 gate_size_t gate_string_length(gate_string_t const* obj)
3276 {
3277
1/2
✓ Branch 0 taken 37829 times.
✗ Branch 1 not taken.
37829 return obj ? obj->length : 0;
3278 }
3279 4 gate_bool_t gate_string_like(gate_string_t const* obj, gate_string_t const* pattern)
3280 {
3281 4 return gate_str_like(obj->str, obj->length, pattern->str, pattern->length);
3282 }
3283 28 gate_bool_t gate_string_like_one_of(gate_string_t const* obj, gate_string_t const* pattern, gate_char8_t separator)
3284 {
3285 28 return gate_str_like_one_of(obj->str, obj->length, pattern->str, pattern->length, separator);
3286 }
3287
3288
3289 180 gate_size_t gate_string_count_chars(gate_string_t const* obj, gate_char8_t chr)
3290 {
3291
1/2
✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
180 if (obj)
3292 {
3293 180 return gate_str_count_chars(obj->str, obj->length, chr);
3294 }
3295 return 0;
3296 }
3297 81 gate_char8_t gate_string_char_at(gate_string_t const* str, gate_size_t index)
3298 {
3299 81 gate_char8_t ret = '\0';
3300
2/4
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
81 if (str && (index < str->length))
3301 {
3302 81 ret = str->str[index];
3303 }
3304 81 return ret;
3305 }
3306
3307 1358 gate_size_t gate_string_char_pos(gate_string_t const* obj, gate_char8_t find, gate_size_t startat)
3308 {
3309 1358 return gate_str_char_pos(obj->str, obj->length, find, startat);
3310 }
3311 446 gate_size_t gate_string_char_pos_last(gate_string_t const* obj, gate_char8_t find)
3312 {
3313 446 return gate_str_char_pos_last(obj->str, obj->length, find);
3314 }
3315 10 gate_size_t gate_string_find_first_of(gate_string_t const* obj, gate_string_t const* chars, gate_size_t startat)
3316 {
3317 10 return gate_str_find_first_of(obj->str, obj->length, chars->str, chars->length, startat);
3318 }
3319 77 gate_size_t gate_string_find_first_not_of(gate_string_t const* obj, gate_string_t const* chars, gate_size_t startat)
3320 {
3321 77 return gate_str_find_first_not_of(obj->str, obj->length, chars->str, chars->length, startat);
3322 }
3323 2 gate_size_t gate_string_find_last_of(gate_string_t const* obj, gate_string_t const* chars)
3324 {
3325 2 return gate_str_find_last_of(obj->str, obj->length, chars->str, chars->length);
3326 }
3327 26 gate_size_t gate_string_find_last_not_of(gate_string_t const* obj, gate_string_t const* chars)
3328 {
3329 26 return gate_str_find_last_not_of(obj->str, obj->length, chars->str, chars->length);
3330 }
3331
3332 68 gate_size_t gate_string_pos(gate_string_t const* obj, gate_string_t const* find, gate_size_t startat)
3333 {
3334 68 return gate_str_pos(obj->str, obj->length, find->str, find->length, startat);
3335 }
3336 2 gate_size_t gate_string_pos_last(gate_string_t const* obj, gate_string_t const* find)
3337 {
3338 2 return gate_str_pos_last(obj->str, obj->length, find->str, find->length);
3339 }
3340
3341
3342 43 gate_size_t gate_string_parse(gate_string_t const* obj, gate_string_t const* find, gate_size_t start_at,
3343 gate_string_t* head, gate_string_t* tail, gate_bool_t separator_as_tail)
3344 {
3345 43 gate_size_t pos = gate_string_pos(obj, find, start_at);
3346
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 32 times.
43 if (pos == GATE_STR_NPOS)
3347 {
3348 11 return 0; /* nothing parsed */
3349 }
3350 else
3351 {
3352
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (head)
3353 {
3354 32 gate_string_substr(head, obj, 0, pos);
3355 }
3356
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (tail)
3357 {
3358
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 25 times.
32 if (separator_as_tail)
3359 {
3360 7 gate_string_substr(tail, obj, pos, GATE_STR_NPOS);
3361 }
3362 else
3363 {
3364 25 gate_string_substr(tail, obj, pos + find->length, GATE_STR_NPOS);
3365 }
3366 }
3367 32 return pos + gate_string_length(find); /* (head + separator) parsed */
3368 }
3369 }
3370
3371 4 gate_size_t gate_string_parse_int(gate_string_t const* obj, gate_int64_t* num)
3372 {
3373 4 return gate_str_parse_int64(obj->str, obj->length, num);
3374 }
3375
3376 129 gate_size_t gate_string_parse_uint(gate_string_t const* obj, gate_uint64_t* num)
3377 {
3378 129 return gate_str_parse_uint64(obj->str, obj->length, num);
3379 }
3380
3381 3 gate_size_t gate_string_parse_real(gate_string_t const* obj, gate_real64_t* num)
3382 {
3383 3 return gate_str_parse_real(obj->str, obj->length, num);
3384 }
3385
3386
3387 1 gate_size_t gate_string_parse_hex(gate_string_t const* obj, gate_uint64_t* num)
3388 {
3389 1 return gate_str_parse_hex_int(obj->str, obj->length, num);
3390 }
3391
3392
3393 3370 gate_char8_t const* gate_string_ptr(gate_string_t const* obj, gate_size_t index)
3394 {
3395
3/4
✓ Branch 0 taken 3370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3354 times.
✓ Branch 3 taken 16 times.
3370 if ((obj != NULL) && (obj->str != NULL))
3396 {
3397 3354 return obj->str + index;
3398 }
3399 else
3400 {
3401 16 return NULL;
3402 }
3403 }
3404 5998 gate_string_t* gate_string_substr(gate_string_t* dst, gate_string_t const* src, gate_size_t offset, gate_size_t length)
3405 {
3406
1/2
✓ Branch 0 taken 5998 times.
✗ Branch 1 not taken.
5998 if (dst != NULL)
3407 {
3408
5/6
✓ Branch 0 taken 5998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5941 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 5920 times.
5998 if ((src == NULL) || (offset >= src->length) || (length == 0))
3409 {
3410
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 24 times.
156 if (src == dst)
3411 {
3412 54 gate_string_release(dst);
3413 }
3414 else
3415 {
3416 24 dst->str = NULL;
3417 24 dst->length = 0;
3418 24 dst->buffer = NULL;
3419 }
3420 }
3421 else
3422 {
3423
2/2
✓ Branch 0 taken 2911 times.
✓ Branch 1 taken 3009 times.
5920 if (length > src->length - offset)
3424 {
3425 2911 length = src->length - offset;
3426 }
3427
3428 5920 dst->buffer = src->buffer;
3429 5920 dst->str = &src->str[offset];
3430 5920 dst->length = length;
3431
3432
4/4
✓ Branch 0 taken 4042 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 3059 times.
✓ Branch 3 taken 983 times.
5920 if ((dst->buffer != NULL) && (dst != src))
3433 {
3434 3059 gate_atomic_int_inc(&dst->buffer->refcount);
3435 }
3436 }
3437 }
3438 5998 return dst;
3439 }
3440
3441 9670 int gate_string_comp(gate_string_t const* src, gate_string_t const* dst)
3442 {
3443 9670 gate_char8_t const* ptr_src = NULL;
3444 9670 gate_size_t len_src = 0;
3445 9670 gate_char8_t const* ptr_dst = NULL;
3446 9670 gate_size_t len_dst = 0;
3447
3448
1/2
✓ Branch 0 taken 9670 times.
✗ Branch 1 not taken.
9670 if (src)
3449 {
3450 9670 ptr_src = src->str;
3451 9670 len_src = src->length;
3452 }
3453
2/2
✓ Branch 0 taken 9664 times.
✓ Branch 1 taken 6 times.
9670 if (dst)
3454 {
3455 9664 ptr_dst = dst->str;
3456 9664 len_dst = dst->length;
3457 }
3458
3459 9670 return gate_str_compare(ptr_src, len_src, ptr_dst, len_dst);
3460 }
3461
3462 497 int gate_string_comp_ic(gate_string_t const* src, gate_string_t const* dst)
3463 {
3464 497 gate_char8_t const* ptr_src = NULL;
3465 497 gate_size_t len_src = 0;
3466 497 gate_char8_t const* ptr_dst = NULL;
3467 497 gate_size_t len_dst = 0;
3468
3469
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 if (src)
3470 {
3471 497 ptr_src = src->str;
3472 497 len_src = src->length;
3473 }
3474
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 if (dst)
3475 {
3476 497 ptr_dst = dst->str;
3477 497 len_dst = dst->length;
3478 }
3479 497 return gate_str_compare_ic(ptr_src, len_src, ptr_dst, len_dst);
3480 }
3481 1134 gate_size_t gate_string_to_buffer(gate_string_t const* src, gate_char8_t* buffer, gate_size_t bufferlength)
3482 {
3483 gate_size_t ret;
3484
2/4
✓ Branch 0 taken 1134 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1134 times.
1134 if ((buffer == NULL) || (bufferlength == 0))
3485 {
3486 ret = 0;
3487 }
3488 else
3489 {
3490
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1131 times.
1134 if (gate_string_is_empty(src))
3491 {
3492 3 buffer[0] = 0;
3493 3 ret = 0;
3494 }
3495 else
3496 {
3497 1131 ret = gate_str_print_text(buffer, bufferlength, src->str, src->length);
3498 }
3499 }
3500 1134 return ret;
3501 }
3502
3503
3504 12423 gate_bool_t gate_string_starts_with(gate_string_t const* obj, gate_string_t const* token)
3505 {
3506 12423 gate_size_t objlen = gate_string_length(obj);
3507 12423 gate_size_t tokenlen = gate_string_length(token);
3508
3/4
✓ Branch 0 taken 12423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 725 times.
✓ Branch 3 taken 11698 times.
12423 if ((tokenlen == 0) || (objlen < tokenlen))
3509 {
3510 725 return false;
3511 }
3512 11698 return (gate_str_compare(obj->str, tokenlen, token->str, tokenlen) == 0);
3513 }
3514 352 gate_bool_t gate_string_starts_with_str(gate_string_t const* obj, gate_char8_t const* text)
3515 {
3516 gate_string_t tmp;
3517 352 gate_string_create_static(&tmp, text);
3518 352 return gate_string_starts_with(obj, &tmp);
3519 }
3520 3095 gate_bool_t gate_string_starts_with_char(gate_string_t const* obj, gate_char8_t chr)
3521 {
3522 3095 gate_size_t objlen = gate_string_length(obj);
3523
4/4
✓ Branch 0 taken 3093 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1590 times.
✓ Branch 3 taken 1503 times.
3095 return (objlen >= 1) && (obj->str[0] == chr);
3524 }
3525 1 gate_bool_t gate_string_starts_with_ic(gate_string_t const* obj, gate_string_t const* token)
3526 {
3527 1 gate_size_t objlen = gate_string_length(obj);
3528 1 gate_size_t tokenlen = gate_string_length(token);
3529
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((tokenlen == 0) || (objlen < tokenlen))
3530 {
3531 return false;
3532 }
3533 1 return (gate_str_compare_ic(obj->str, tokenlen, token->str, tokenlen) == 0);
3534 }
3535 1 gate_bool_t gate_string_starts_with_str_ic(gate_string_t const* obj, gate_char8_t const* text)
3536 {
3537 gate_string_t tmp;
3538 1 gate_string_create_static(&tmp, text);
3539 1 return gate_string_starts_with_ic(obj, &tmp);
3540 }
3541
3542 480 gate_bool_t gate_string_ends_with(gate_string_t const* obj, gate_string_t const* token)
3543 {
3544 480 gate_size_t objlen = gate_string_length(obj);
3545 480 gate_size_t tokenlen = gate_string_length(token);
3546
3/4
✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 478 times.
480 if ((tokenlen == 0) || (objlen < tokenlen))
3547 {
3548 2 return false;
3549 }
3550 478 return (gate_str_compare(&obj->str[objlen - tokenlen], tokenlen, token->str, tokenlen) == 0);
3551 }
3552 460 gate_bool_t gate_string_ends_with_str(gate_string_t const* obj, gate_char8_t const* text)
3553 {
3554 gate_string_t tmp;
3555 460 gate_string_create_static(&tmp, text);
3556 460 return gate_string_ends_with(obj, &tmp);
3557 }
3558 441 gate_bool_t gate_string_ends_with_char(gate_string_t const* obj, gate_char8_t chr)
3559 {
3560 441 gate_size_t objlen = gate_string_length(obj);
3561
3/4
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 437 times.
441 return (objlen >= 1) && (obj->str[objlen - 1] == chr);
3562 }
3563 1 gate_bool_t gate_string_ends_with_ic(gate_string_t const* obj, gate_string_t const* token)
3564 {
3565 1 gate_size_t objlen = gate_string_length(obj);
3566 1 gate_size_t tokenlen = gate_string_length(token);
3567
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((tokenlen == 0) || (objlen < tokenlen))
3568 {
3569 return false;
3570 }
3571 1 return (gate_str_compare_ic(&obj->str[objlen - tokenlen], tokenlen, token->str, tokenlen) == 0);
3572 }
3573 1 gate_bool_t gate_string_ends_with_str_ic(gate_string_t const* obj, gate_char8_t const* text)
3574 {
3575 gate_string_t tmp;
3576 1 gate_string_create_static(&tmp, text);
3577 1 return gate_string_ends_with_ic(obj, &tmp);
3578 }
3579
3580 1 gate_bool_t gate_string_contains(gate_string_t const* obj, gate_string_t const* token)
3581 {
3582 1 return gate_string_pos(obj, token, 0) != GATE_STR_NPOS;
3583 }
3584
3585 1374 gate_bool_t gate_string_equals(gate_string_t const* obj, gate_string_t const* token)
3586 {
3587 1374 return gate_string_comp(obj, token) == 0;
3588 }
3589 605 gate_bool_t gate_string_equals_str(gate_string_t const* obj, gate_char8_t const* token)
3590 {
3591 gate_string_t tmp;
3592 605 gate_string_create_static(&tmp, token);
3593 605 return gate_string_equals(obj, &tmp);
3594 }
3595 8 gate_bool_t gate_string_equals_ic(gate_string_t const* obj, gate_string_t const* token)
3596 {
3597 8 return gate_string_comp_ic(obj, token) == 0;
3598 }
3599 4 gate_bool_t gate_string_equals_str_ic(gate_string_t const* obj, gate_char8_t const* token)
3600 {
3601 gate_string_t tmp;
3602 4 gate_string_create_static(&tmp, token);
3603 4 return gate_string_equals_ic(obj, &tmp);
3604 }
3605 2014 gate_string_t* gate_string_ltrim(gate_string_t* dst, gate_string_t const* src)
3606 {
3607 2014 gate_size_t pos = gate_str_find_first_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3608
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 1940 times.
2014 if (pos == GATE_STR_NPOS)
3609 {
3610
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 if (dst == src)
3611 {
3612 74 gate_string_release(dst);
3613 }
3614 74 gate_string_create_empty(dst);
3615 }
3616 else
3617 {
3618 1940 dst->str = &src->str[pos];
3619 1940 dst->length = src->length - pos;
3620
2/2
✓ Branch 0 taken 1619 times.
✓ Branch 1 taken 321 times.
1940 if (dst != src)
3621 {
3622 1619 dst->buffer = src->buffer;
3623
2/2
✓ Branch 0 taken 1618 times.
✓ Branch 1 taken 1 times.
1619 if (dst->buffer != NULL)
3624 {
3625 1618 gate_atomic_int_inc(&dst->buffer->refcount);
3626 }
3627 }
3628 }
3629 2014 return dst;
3630 }
3631 159 gate_string_t* gate_string_rtrim(gate_string_t* dst, gate_string_t const* src)
3632 {
3633 159 gate_size_t pos = gate_str_find_last_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH);
3634
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 135 times.
159 if (pos == GATE_STR_NPOS)
3635 {
3636
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (dst == src)
3637 {
3638 24 gate_string_release(dst);
3639 }
3640 24 gate_string_create_empty(dst);
3641 }
3642 else
3643 {
3644 135 dst->length = pos + 1;
3645
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 134 times.
135 if (dst != src)
3646 {
3647 1 dst->str = src->str;
3648 1 dst->buffer = src->buffer;
3649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (dst->buffer != NULL)
3650 {
3651 gate_atomic_int_inc(&dst->buffer->refcount);
3652 }
3653 }
3654 }
3655 159 return dst;
3656 }
3657 3580 gate_string_t* gate_string_trim(gate_string_t* dst, gate_string_t const* src)
3658 {
3659 3580 gate_size_t newlength = gate_str_find_last_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH);
3660 gate_size_t pos;
3661
3662
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 3436 times.
3580 if (newlength == GATE_STR_NPOS)
3663 {
3664
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if (dst == src)
3665 {
3666 144 gate_string_release(dst);
3667 }
3668 144 return gate_string_create_empty(dst);
3669 }
3670 3436 ++newlength;
3671
3672 3436 pos = gate_str_find_first_not_of(src->str, newlength, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3673
3674 3436 dst->str = &src->str[pos];
3675 3436 dst->length = newlength - pos;
3676
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3435 times.
3436 if (dst != src)
3677 {
3678 1 dst->buffer = src->buffer;
3679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (dst->buffer != NULL)
3680 {
3681 gate_atomic_int_inc(&dst->buffer->refcount);
3682 }
3683 }
3684 3436 return dst;
3685 }
3686
3687 163 gate_string_t* gate_string_read_line(gate_string_t* line, gate_string_t const* src, gate_string_t* tail)
3688 {
3689 163 gate_string_t* ret = NULL;
3690 gate_size_t pos;
3691
2/2
✓ Branch 1 taken 154 times.
✓ Branch 2 taken 9 times.
163 if (!gate_string_is_empty(src))
3692 {
3693 154 pos = gate_str_char_pos(src->str, src->length, '\n', 0);
3694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
154 if (pos == GATE_STR_NPOS)
3695 {
3696 ret = gate_string_duplicate(line, src);
3697 if (tail != NULL)
3698 {
3699 if (tail == src)
3700 {
3701 gate_string_release(tail);
3702 }
3703 else
3704 {
3705 gate_string_create_empty(tail);
3706 }
3707 }
3708 }
3709 else
3710 {
3711 154 ret = gate_string_substr(line, src, 0, pos);
3712
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (ret != NULL)
3713 {
3714
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 78 times.
154 if (gate_string_ends_with_str(line, "\r"))
3715 {
3716 76 --line->length;
3717 }
3718 }
3719
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (tail != NULL)
3720 {
3721
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 60 times.
154 if (tail == src)
3722 {
3723 94 tail->str += (pos + 1);
3724 94 tail->length -= (pos + 1);
3725 }
3726 else
3727 {
3728 60 gate_string_substr(tail, src, pos + 1, GATE_STR_NPOS);
3729 }
3730 }
3731 }
3732 }
3733 163 return ret;
3734 }
3735
3736 14 gate_string_t* gate_string_read_token(gate_string_t* token, gate_string_t const* src, gate_string_t* tail)
3737 {
3738 14 gate_string_t* ret = NULL;
3739 gate_size_t pos;
3740 gate_size_t pos2;
3741
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 if (!gate_string_is_empty(src))
3742 {
3743 14 pos = gate_str_find_first_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (pos == GATE_STR_NPOS)
3745 {
3746 ret = gate_string_create_empty(token);
3747 if (tail != NULL)
3748 {
3749 gate_string_create_empty(tail);
3750 }
3751 }
3752 else
3753 {
3754 14 pos2 = gate_str_find_first_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, pos);
3755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (pos2 == GATE_STR_NPOS)
3756 {
3757 ret = gate_string_substr(token, src, pos, src->length - pos);
3758 if (tail != NULL)
3759 {
3760 gate_string_create_empty(tail);
3761 }
3762 }
3763 else
3764 {
3765 14 ret = gate_string_substr(token, src, pos, pos2 - pos);
3766
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (tail != NULL)
3767 {
3768 14 gate_string_substr(tail, src, pos2, src->length - pos2);
3769 }
3770 }
3771 }
3772 }
3773 14 return ret;
3774 }
3775
3776 1 gate_string_t* gate_string_to_lower(gate_string_t* dst, gate_string_t const* src)
3777 {
3778 1 gate_string_t* ret = gate_string_create_copy(dst, src);
3779
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (NULL != ret)
3780 {
3781 1 gate_str_to_lower(ret->buffer->data, ret->length);
3782 }
3783 1 return ret;
3784 }
3785 1 gate_string_t* gate_string_to_upper(gate_string_t* dst, gate_string_t const* src)
3786 {
3787 1 gate_string_t* ret = gate_string_create_copy(dst, src);
3788
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (NULL != ret)
3789 {
3790 1 gate_str_to_upper(ret->buffer->data, ret->length);
3791 }
3792 1 return ret;
3793 }
3794 1 gate_uint32_t gate_string_hash(gate_string_t const* obj)
3795 {
3796 1 return gate_str_hash(gate_string_ptr(obj, 0), gate_string_length(obj));
3797 }
3798
3799
3800
3801
3802 2272 gate_result_t gate_string_copy_constructor(void* destMem, void const* srcMem)
3803 {
3804 2272 gate_string_t* dst = (gate_string_t*)destMem;
3805 2272 gate_string_t const* src = (gate_string_t const*)srcMem;
3806
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2272 times.
2272 if (NULL == gate_string_clone(dst, src))
3807 {
3808 return GATE_RESULT_OUTOFMEMORY;
3809 }
3810 else
3811 {
3812 2272 return GATE_RESULT_OK;
3813 }
3814 }
3815 43 gate_result_t gate_string_duplicate_constructor(void* destMem, void const* srcMem)
3816 {
3817 43 gate_string_t* dst = (gate_string_t*)destMem;
3818 43 gate_string_t const* src = (gate_string_t const*)srcMem;
3819
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 if (NULL == gate_string_duplicate(dst, src))
3820 {
3821 return GATE_RESULT_OUTOFMEMORY;
3822 }
3823 else
3824 {
3825 43 return GATE_RESULT_OK;
3826 }
3827 }
3828 2315 void gate_string_destructor(void* dest)
3829 {
3830 2315 gate_string_t* dst = (gate_string_t*)dest;
3831 2315 gate_string_release(dst);
3832 2315 }
3833
3834
3835
3836
3837
3838 #define GATE_CSTRBUFFER_CREATE_IMPL(char_type, buffer, textptr, length, copy_needed) \
3839 if(!buffer) return NULL; \
3840 gate_mem_clear(buffer, sizeof(*buffer)); \
3841 if(length > 0) \
3842 { \
3843 buffer->length = length; \
3844 if(!copy_needed && (textptr[length] == 0)) \
3845 { \
3846 buffer->str = textptr; \
3847 } \
3848 else if(length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]))) \
3849 { \
3850 gate_mem_copy(buffer->local_buffer, textptr, length * sizeof(buffer->local_buffer[0])); \
3851 buffer->local_buffer[length] = 0; \
3852 buffer->str = &buffer->local_buffer[0]; \
3853 } \
3854 else \
3855 { \
3856 buffer->heap_buffer = ( char_type *)gate_mem_alloc((length + 1) * sizeof(char_type)); \
3857 if(buffer->heap_buffer) \
3858 { \
3859 gate_mem_copy(buffer->heap_buffer, textptr, length * sizeof(char_type)); \
3860 buffer->heap_buffer[length] = 0; \
3861 buffer->str = buffer->heap_buffer; \
3862 } \
3863 else \
3864 { \
3865 buffer->length = 0; \
3866 buffer = NULL; \
3867 } \
3868 } \
3869 } \
3870 return buffer
3871
3872 #define GATE_CSTRBUFFER_DESTROY_IMPL(buffer) \
3873 do { \
3874 if(!buffer) break; \
3875 if(buffer->heap_buffer && (buffer->str == buffer->heap_buffer)) \
3876 { \
3877 gate_mem_dealloc(buffer->heap_buffer); \
3878 } \
3879 gate_mem_clear(buffer, sizeof(*buffer)); \
3880 } while(0)
3881
3882 #define GATE_CSTRBUFFER_GET_IMPL(buffer) return buffer ? buffer->str : NULL
3883
3884 #define GATE_CSTRBUFFER_LENGTH_IMPL(buffer) return buffer ? buffer->length : 0
3885
3886
3887 3 gate_cstrbuffer_t* gate_cstrbuffer_create_string(gate_cstrbuffer_t* buffer, gate_string_t const* strptr, gate_bool_t copy_needed)
3888 {
3889
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (strptr)
3890 {
3891 3 return gate_cstrbuffer_create(buffer, strptr->str, strptr->length, copy_needed);
3892 }
3893 else if (buffer)
3894 {
3895 gate_mem_clear(buffer, sizeof(*buffer));
3896 }
3897 return buffer;
3898 }
3899
3900 2 gate_cstrbuffer_t* gate_cstrbuffer_create_wstr(gate_cstrbuffer_t* buffer, wchar_t const* textptr, gate_size_t length)
3901 {
3902 2 const gate_size_t required_buffer = length * 3 + 1;
3903 2 char* target = NULL;
3904 2 gate_size_t used = 0;
3905
3906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!buffer) return NULL;
3907 2 gate_mem_clear(buffer, sizeof(*buffer));
3908
3909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (sizeof(buffer->local_buffer) <= required_buffer)
3910 {
3911 buffer->heap_buffer = (char*)gate_mem_alloc(required_buffer);
3912 if (NULL == buffer->heap_buffer)
3913 {
3914 /* allocation failed */
3915 return NULL;
3916 }
3917 target = buffer->heap_buffer;
3918 }
3919 else
3920 {
3921 2 target = &buffer->local_buffer[0];
3922 }
3923
3924 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
3925 used = gate_str_utf16_2_utf8((gate_char16_t const*)textptr, length, target, required_buffer - 1);
3926 #else
3927 2 used = gate_str_utf32_2_utf8((gate_char32_t const*)textptr, length, target, required_buffer - 1);
3928 #endif
3929
3930 2 buffer->str = target;
3931 2 buffer->length = used;
3932 2 return buffer;
3933 }
3934
3935 10 gate_cstrbuffer_t* gate_cstrbuffer_create(gate_cstrbuffer_t* buffer, gate_char8_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
3936 {
3937
9/12
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 2 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
10 GATE_CSTRBUFFER_CREATE_IMPL(gate_char8_t, buffer, textptr, length, copy_needed);
3938 }
3939
3940 12 void gate_cstrbuffer_destroy(gate_cstrbuffer_t* buffer)
3941 {
3942
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
12 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
3943 12 }
3944
3945 15 gate_char8_t const* gate_cstrbuffer_get(gate_cstrbuffer_t const* buffer)
3946 {
3947
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 GATE_CSTRBUFFER_GET_IMPL(buffer);
3948 }
3949
3950 5 gate_size_t gate_cstrbuffer_length(gate_cstrbuffer_t const* buffer)
3951 {
3952
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
3953 }
3954
3955
3956
3957 3 gate_cstrbuffer16_t* gate_cstrbuffer16_create_string(gate_cstrbuffer16_t* buffer, gate_string_t const* ptr)
3958 {
3959 gate_size_t len;
3960
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (buffer)
3961 {
3962 3 gate_mem_clear(buffer, sizeof(*buffer));
3963
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if (ptr && ptr->length)
3964 {
3965
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (ptr->length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0])))
3966 {
3967 2 len = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->local_buffer,
3968 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
3969 2 buffer->local_buffer[len] = 0;
3970 2 buffer->str = &buffer->local_buffer[0];
3971 2 buffer->length = len;
3972 }
3973 else
3974 {
3975 1 buffer->heap_buffer = (gate_char16_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char16_t));
3976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!buffer->heap_buffer)
3977 {
3978 buffer = NULL;
3979 }
3980 else
3981 {
3982 1 buffer->length = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
3983 1 buffer->heap_buffer[buffer->length] = 0;
3984 1 buffer->str = buffer->heap_buffer;
3985 }
3986 }
3987 }
3988 }
3989
3990 3 return buffer;
3991 }
3992
3993 1 gate_cstrbuffer16_t* gate_cstrbuffer16_create(gate_cstrbuffer16_t* buffer, gate_char16_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
3994 {
3995
4/12
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
1 GATE_CSTRBUFFER_CREATE_IMPL(gate_char16_t, buffer, textptr, length, copy_needed);
3996 }
3997
3998 4 void gate_cstrbuffer16_destroy(gate_cstrbuffer16_t* buffer)
3999 {
4000
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
4 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
4001 4 }
4002
4003 2 gate_char16_t const* gate_cstrbuffer16_get(gate_cstrbuffer16_t const* buffer)
4004 {
4005
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_GET_IMPL(buffer);
4006 }
4007
4008 2 gate_size_t gate_cstrbuffer16_length(gate_cstrbuffer16_t const* buffer)
4009 {
4010
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
4011 }
4012
4013
4014
4015 1 gate_cstrbuffer32_t* gate_cstrbuffer32_create_string(gate_cstrbuffer32_t* buffer, gate_string_t const* ptr)
4016 {
4017 gate_size_t len;
4018
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer)
4019 {
4020 1 gate_mem_clear(buffer, sizeof(*buffer));
4021
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (ptr && ptr->length)
4022 {
4023
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr->length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0])))
4024 {
4025 1 len = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->local_buffer,
4026 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
4027 1 buffer->local_buffer[len] = 0;
4028 1 buffer->str = &buffer->local_buffer[0];
4029 1 buffer->length = len;
4030 }
4031 else
4032 {
4033 buffer->heap_buffer = (gate_char32_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char32_t));
4034 if (!buffer->heap_buffer)
4035 {
4036 buffer = NULL;
4037 }
4038 else
4039 {
4040 buffer->length = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
4041 buffer->heap_buffer[buffer->length] = 0;
4042 buffer->str = buffer->heap_buffer;
4043 }
4044 }
4045 }
4046 }
4047
4048 1 return buffer;
4049 }
4050
4051 1 gate_cstrbuffer32_t* gate_cstrbuffer32_create(gate_cstrbuffer32_t* buffer, gate_char32_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
4052 {
4053
4/12
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
1 GATE_CSTRBUFFER_CREATE_IMPL(gate_char32_t, buffer, textptr, length, copy_needed);
4054 }
4055
4056 2 void gate_cstrbuffer32_destroy(gate_cstrbuffer32_t* buffer)
4057 {
4058
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
4059 2 }
4060
4061 1 gate_char32_t const* gate_cstrbuffer32_get(gate_cstrbuffer32_t const* buffer)
4062 {
4063
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_GET_IMPL(buffer);
4064 }
4065
4066 1 gate_size_t gate_cstrbuffer32_length(gate_cstrbuffer32_t const* buffer)
4067 {
4068
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
4069 }
4070