GCC Code Coverage Report


Directory: src/gate/
File: src/gate/strings.c
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 1382 1863 74.2%
Functions: 194 250 77.6%
Branches: 707 1436 49.2%

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 7841 int gate_char_lowercase(int chr)
239 {
240
4/4
✓ Branch 0 taken 6795 times.
✓ Branch 1 taken 1046 times.
✓ Branch 2 taken 134 times.
✓ Branch 3 taken 6661 times.
7841 if ((chr >= 'A') && (chr <= 'Z'))
241 {
242 134 return chr + ('a' - 'A');
243 }
244 7707 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 3172 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 3170 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3166 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3164 times.
✓ Branch 6 taken 2310 times.
✓ Branch 7 taken 84655 times.
✓ Branch 8 taken 86965 times.
✓ Branch 9 taken 854 times.
87827 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 684 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 684 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 684 times.
✓ Branch 4 taken 546 times.
✓ Branch 5 taken 3482 times.
✓ Branch 6 taken 4028 times.
✓ Branch 7 taken 138 times.
4166 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 812099 gate_size_t gate_str_length(gate_char8_t const* src)
438 {
439
4/4
✓ Branch 0 taken 811992 times.
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 32969995 times.
✓ Branch 3 taken 811992 times.
33782094 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 3142 gate_bool_t gate_str_is_empty(gate_char8_t const* src)
483 {
484
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 3125 times.
3142 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 28589 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 28302 times.
✓ Branch 1 taken 287 times.
✓ Branch 2 taken 15133 times.
✓ Branch 3 taken 57153 times.
✓ Branch 4 taken 8888 times.
✓ Branch 5 taken 48265 times.
✓ Branch 6 taken 72286 times.
✓ Branch 7 taken 4281 times.
76854 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 const c1 = (gate_char8_t)gate_char_lowercase(*str1); \
532 gate_char8_t const c2 = (gate_char8_t)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 2850 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 2849 times.
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 2057 times.
✓ Branch 5 taken 1860 times.
✓ Branch 6 taken 619 times.
✓ Branch 7 taken 1241 times.
✓ Branch 8 taken 3917 times.
✓ Branch 9 taken 173 times.
4091 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(cast_type, str, len) \
555 while(len-- > 0) \
556 { \
557 *str = (cast_type)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(gate_char8_t, str, len);
564 1 }
565 void gate_str16_to_lower(gate_char16_t* str, gate_size_t len)
566 {
567 GATE_STR_TO_LOWER(gate_char16_t, str, len);
568 }
569 void gate_str32_to_lower(gate_char32_t* str, gate_size_t len)
570 {
571 GATE_STR_TO_LOWER(gate_char32_t, str, len);
572 }
573
574
575
576
577 #define GATE_STR_TO_UPPER(cast_type, str, len) \
578 while(len-- > 0) \
579 { \
580 *str = (cast_type)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(gate_char8_t, str, len);
587 1 }
588 void gate_str16_to_upper(gate_char16_t* str, gate_size_t len)
589 {
590 GATE_STR_TO_UPPER(gate_char16_t, str, len);
591 }
592 void gate_str32_to_upper(gate_char32_t* str, gate_size_t len)
593 {
594 GATE_STR_TO_UPPER(gate_char32_t, 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 133960 void gate_str_reverse(gate_char8_t* src, gate_size_t len)
617 {
618
3/4
✓ Branch 0 taken 133960 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 134465 times.
✓ Branch 3 taken 133960 times.
268425 GATE_STR_REVERSE(gate_char8_t, src, len);
619 133960 }
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 24891 int gate_str_compare(gate_char8_t const* str1, gate_size_t len1, gate_char8_t const* str2, gate_size_t len2)
677 {
678 24891 gate_size_t len = len1 < len2 ? len1 : len2;
679 24891 int ret = gate_str_comp_range(str1, str2, len);
680
2/2
✓ Branch 0 taken 3238 times.
✓ Branch 1 taken 21653 times.
24891 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 24891 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 2468 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 2468 gate_size_t len = len1 < len2 ? len1 : len2;
694 2468 int ret = gate_str_comp_range_ic(str1, str2, len);
695
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 2319 times.
2468 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 2468 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 511 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 511 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 511 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 511 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 511 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 511 times.
511 if ((str == NULL) || (len == 0) || (startat >= len) || (chars == NULL) || (charcount == 0))
787 {
788 return GATE_STR_NPOS;
789 }
790 511 ret = startat;
791 511 str += startat;
792 511 len -= startat;
793
2/2
✓ Branch 0 taken 3571 times.
✓ Branch 1 taken 399 times.
3970 while (len-- > 0)
794 {
795
2/2
✓ Branch 0 taken 13890 times.
✓ Branch 1 taken 3459 times.
17349 for (ndx = 0; ndx != charcount; ++ndx)
796 {
797
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 13778 times.
13890 if (*str == chars[ndx])
798 {
799 /* first character found, that is included in 'chars' */
800 112 return ret;
801 }
802 }
803 3459 ++str;
804 3459 ++ret;
805 }
806 399 return GATE_STR_NPOS;
807 }
808
809 5660 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 5581 times.
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 5577 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5577 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5577 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 5577 times.
5660 if ((str == NULL) || (len == 0) || (startat >= len) || (chars == NULL) || (charcount == 0))
814 {
815 83 return GATE_STR_NPOS;
816 }
817 5577 ret = startat;
818 5577 str += startat;
819 5577 len -= startat;
820
2/2
✓ Branch 0 taken 13016 times.
✓ Branch 1 taken 1 times.
13017 while (len-- > 0)
821 {
822
2/2
✓ Branch 0 taken 30915 times.
✓ Branch 1 taken 5576 times.
36491 for (ndx = 0; ndx != charcount; ++ndx)
823 {
824
2/2
✓ Branch 0 taken 7440 times.
✓ Branch 1 taken 23475 times.
30915 if (*str == chars[ndx])
825 {
826 7440 break;
827 }
828 }
829
2/2
✓ Branch 0 taken 5576 times.
✓ Branch 1 taken 7440 times.
13016 if (ndx == charcount)
830 {
831 /* first character found, that is not included in 'chars' */
832 5576 return ret;
833 }
834 7440 ++str;
835 7440 ++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 3760 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 3760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3756 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3756 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3756 times.
3760 if ((str == NULL) || (len == 0) || (chars == NULL) || (charcount == 0))
869 {
870 4 return GATE_STR_NPOS;
871 }
872 3756 ret = len;
873 3756 str += len;
874
2/2
✓ Branch 0 taken 5846 times.
✓ Branch 1 taken 164 times.
6010 while (len-- > 0)
875 {
876 5846 --str;
877 5846 --ret;
878
2/2
✓ Branch 0 taken 22992 times.
✓ Branch 1 taken 3592 times.
26584 for (ndx = 0; ndx != charcount; ++ndx)
879 {
880
2/2
✓ Branch 0 taken 2254 times.
✓ Branch 1 taken 20738 times.
22992 if (*str == chars[ndx])
881 {
882 2254 break;
883 }
884 }
885
2/2
✓ Branch 0 taken 3592 times.
✓ Branch 1 taken 2254 times.
5846 if (ndx == charcount)
886 {
887 /* last character found, that is not included in 'chars' */
888 3592 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 3383 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 3375 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 1219 times.
✓ Branch 4 taken 2156 times.
3383 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 464 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 382 times.
✓ Branch 1 taken 82 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 357 times.
464 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 4309 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 3376 times.
4309 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 3376 times.
3376 if (newcapacity <= srclength)
1043 {
1044 ret = src;
1045 }
1046 else
1047 {
1048 3376 ++newcapacity;
1049 3376 ret = (gate_stringbuffer_t*)gate_mem_realloc(src, sizeof(gate_stringbuffer_t) + newcapacity);
1050
1/2
✓ Branch 0 taken 3376 times.
✗ Branch 1 not taken.
3376 if (ret != NULL)
1051 {
1052 3376 ret->data[newcapacity] = 0;
1053 3376 ret->refcount = 0;
1054 }
1055 }
1056 }
1057 4309 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 1610 gate_size_t gate_strbuilder_length(gate_strbuilder_t const* builder)
1106 {
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1610 times.
1610 if (builder == NULL)
1108 {
1109 return 0;
1110 }
1111 else
1112 {
1113 1610 return builder->length;
1114 }
1115 }
1116 1089 gate_char8_t const* gate_strbuilder_ptr(gate_strbuilder_t const* builder, gate_size_t charpos)
1117 {
1118
2/4
✓ Branch 0 taken 1089 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1089 times.
1089 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 1038 times.
1089 if (charpos >= builder->length)
1125 {
1126 51 return NULL;
1127 }
1128 else
1129 {
1130 1038 return &builder->ptr_data[charpos];
1131 }
1132 }
1133 }
1134 2584 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 2584 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2584 times.
✗ Branch 3 not taken.
2584 if ((builder->resize != NULL) && (sz != 0))
1138 {
1139 2584 newbuffer = builder->resize(builder->buffer, builder->length, sz + 1);
1140
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2582 times.
2584 if (newbuffer == NULL)
1141 {
1142 /* allocation failed */
1143 2 return 0;
1144 }
1145 2582 builder->buffer = newbuffer;
1146 2582 builder->ptr_data = newbuffer->data;
1147 2582 builder->capacity = sz;
1148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2582 times.
2582 if (builder->length > builder->capacity)
1149 {
1150 builder->length = builder->capacity;
1151 }
1152 2582 return builder->capacity;
1153 }
1154 else
1155 {
1156 return 0;
1157 }
1158 }
1159
1160 2574 gate_size_t gate_strbuilder_increase(gate_strbuilder_t* builder, gate_size_t sz)
1161 {
1162 2574 return gate_strbuilder_resize(builder, builder->capacity + sz + 1);
1163 }
1164
1165
1166 820525 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 820502 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 820502 times.
✗ Branch 3 not taken.
820525 if ((txtlen != 0) && (txt != NULL))
1169 {
1170 820502 gate_size_t const free_chars = builder->capacity - builder->length;
1171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 820502 times.
820502 GATE_DEBUG_ASSERT(builder->capacity >= builder->length);
1172
2/2
✓ Branch 0 taken 2548 times.
✓ Branch 1 taken 817954 times.
820502 if (txtlen >= free_chars)
1173 {
1174
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2548 times.
2548 if (gate_strbuilder_increase(builder, txtlen + (builder->length + 1) / 2) == 0)
1175 {
1176 return 0;
1177 }
1178 }
1179 820502 gate_mem_copy(&builder->ptr_data[builder->length], txt, txtlen);
1180 820502 builder->length += txtlen;
1181 820502 builder->ptr_data[builder->length] = 0;
1182 820502 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 661252 gate_size_t gate_strbuilder_append_cstr(gate_strbuilder_t* builder, char const* txt)
1220 {
1221
1/2
✓ Branch 0 taken 661252 times.
✗ Branch 1 not taken.
661252 if (txt)
1222 {
1223 661252 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 132216 gate_size_t gate_strbuilder_append_uint32(gate_strbuilder_t* builder, gate_uint32_t num)
1305 {
1306 gate_char8_t buffer[16];
1307 132216 gate_size_t bufferlen = sizeof(buffer) / sizeof(buffer[0]);
1308 132216 gate_size_t bufferused = gate_str_print_uint32(&buffer[0], bufferlen, num);
1309 132216 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_CALL 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 894 gate_size_t gate_strbuilder_discard(gate_strbuilder_t* builder, gate_size_t charcount)
1509 {
1510
2/2
✓ Branch 0 taken 572 times.
✓ Branch 1 taken 322 times.
894 if (charcount >= builder->length)
1511 {
1512 572 charcount = builder->length;
1513 572 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 894 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 138386 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 138386 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 138381 times.
✓ Branch 4 taken 138270 times.
✓ Branch 5 taken 116 times.
138386 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 332 gate_size_t gate_str_print_uint16(gate_char8_t* dst, gate_size_t dstlen, gate_uint16_t num)
1724 {
1725 332 gate_size_t ret = 0;
1726
2/4
✓ Branch 0 taken 332 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332 times.
✗ Branch 3 not taken.
332 if ((dst != NULL) && (dstlen != 0))
1727 {
1728 gate_char8_t* ptr;
1729
6/8
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 227 times.
✓ Branch 2 taken 559 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 161 times.
✓ Branch 5 taken 171 times.
✓ Branch 7 taken 332 times.
✗ Branch 8 not taken.
559 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint16_t, num, gate_str_reverse);
1730 }
1731 332 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 133441 gate_size_t gate_str_print_uint32(gate_char8_t* dst, gate_size_t dstlen, gate_uint32_t num)
1744 {
1745 133441 gate_size_t ret = 0;
1746
2/4
✓ Branch 0 taken 133441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 133441 times.
✗ Branch 3 not taken.
133441 if ((dst != NULL) && (dstlen != 0))
1747 {
1748 gate_char8_t* ptr;
1749
6/8
✓ Branch 0 taken 133441 times.
✓ Branch 1 taken 255704 times.
✓ Branch 2 taken 389145 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 133099 times.
✓ Branch 5 taken 342 times.
✓ Branch 7 taken 133441 times.
✗ Branch 8 not taken.
389145 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint32_t, num, gate_str_reverse);
1750 }
1751 133441 return ret;
1752 }
1753 340 gate_size_t gate_str_print_int32(gate_char8_t* dst, gate_size_t dstlen, gate_int32_t num)
1754 {
1755 340 gate_size_t ret = 0;
1756
2/4
✓ Branch 0 taken 340 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 340 times.
✗ Branch 3 not taken.
340 if ((dst != NULL) && (dstlen != 0))
1757 {
1758 gate_uint32_t unum;
1759
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 339 times.
340 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint32_t, gate_str_print_uint32);
1760 }
1761 340 return ret;
1762 }
1763 1193 gate_size_t gate_str_print_uint64(gate_char8_t* dst, gate_size_t dstlen, gate_uint64_t num)
1764 {
1765 1193 gate_size_t ret = 0;
1766
2/4
✓ Branch 0 taken 1193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1193 times.
✗ Branch 3 not taken.
1193 if ((dst != NULL) && (dstlen != 0))
1767 {
1768 gate_char8_t* ptr;
1769
8/8
✓ Branch 0 taken 1192 times.
✓ Branch 1 taken 1612 times.
✓ Branch 2 taken 2804 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 700 times.
✓ Branch 5 taken 493 times.
✓ Branch 7 taken 1192 times.
✓ Branch 8 taken 1 times.
2805 GATE_STR_PRINT_NUM(dst, dstlen, ptr, ret, gate_uint64_t, num, gate_str_reverse);
1770 }
1771 1193 return ret;
1772 }
1773 288 gate_size_t gate_str_print_int64(gate_char8_t* dst, gate_size_t dstlen, gate_int64_t num)
1774 {
1775 288 gate_size_t ret = 0;
1776
2/4
✓ Branch 0 taken 288 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 288 times.
✗ Branch 3 not taken.
288 if ((dst != NULL) && (dstlen != 0))
1777 {
1778 gate_uint64_t unum;
1779
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 251 times.
288 GATE_STR_PRINT_INUM(ret, dst, dstlen, unum, num, gate_uint64_t, gate_str_print_uint64);
1780 }
1781 288 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 156 times.
✓ Branch 1 taken 158 times.
314 if (intlen > bytesused)
1921 {
1922 gate_size_t ndx;
1923
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 156 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
322 for (ndx = bytesused; (ndx < intlen) && (dstlen != 0); ++ndx)
1924 {
1925 166 *dst = '0';
1926 166 ++dst;
1927 166 --dstlen;
1928 166 ++ret;
1929 }
1930 }
1931
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 154 times.
158 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 306 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 306 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 306 gate_char8_t* bufferptr = &buffer[0];
2009 306 gate_size_t bufferlen = sizeof(buffer) - 1;
2010
2011 306 gate_size_t intcount = 0;
2012 306 gate_size_t decimalcount = 0;
2013 306 gate_size_t bufferused = 0;
2014 gate_size_t ndx;
2015
2016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 if (dstlen < 3)
2017 {
2018 return 0;
2019 }
2020
2021
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 306 times.
306 if (gate_math_isnan(num))
2022 {
2023 return gate_str_print_text(dst, dstlen, "NaN", 3);
2024 }
2025 306 infini = gate_math_isinfinite(num);
2026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 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 306 times.
306 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 306 times.
306 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 304 times.
306 if (num < 0.0)
2043 {
2044 2 *bufferptr = '-';
2045 2 ++bufferptr;
2046 2 --bufferlen;
2047 2 num = -num;
2048 }
2049
2050 306 intcount = gate_str_print_uint64(intbuffer, sizeof(intbuffer) - 1, (gate_uint64_t)num);
2051 306 decimalnum = num - (gate_real64_t)(gate_int64_t)num;
2052 306 factor = 1.0;
2053
3/4
✓ Branch 1 taken 1458 times.
✓ Branch 2 taken 306 times.
✓ Branch 3 taken 1458 times.
✗ Branch 4 not taken.
1764 while (!gate_math_iszerof((gate_real32_t)(decimalnum * factor)) && (decimalcount < sizeof(decimalbuffer) - 1))
2054 {
2055 1458 factor *= 0.1;
2056 1458 decimalnum *= 10.0;
2057 1458 decimalbuffer[decimalcount] = '0' + (gate_char8_t)(gate_uint64_t)decimalnum;
2058 1458 ++decimalcount;
2059 1458 decimalnum -= (gate_real64_t)(gate_int64_t)decimalnum;
2060 }
2061 }
2062
2063
2064
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 305 times.
306 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 295 times.
305 if (grouplen != 0)
2093 {
2094 10 ndx = gate_str_print_grouped(bufferptr, bufferlen, &intbuffer[0], intcount, grouplen);
2095 }
2096 else
2097 {
2098 295 ndx = gate_str_print_text(bufferptr, bufferlen, &intbuffer[0], intcount);
2099 }
2100 }
2101 306 bufferptr += ndx;
2102 306 bufferlen -= ndx;
2103 306 bufferused += ndx;
2104
2105
2106
2107
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 298 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
306 if ((decimallen > 0) || (decimalcount > 0))
2108 {
2109 302 *bufferptr = '.';
2110 302 ++bufferptr;
2111 302 --bufferlen;
2112 302 ++bufferused;
2113
2114
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 4 times.
302 if (decimallen > 0)
2115 {
2116
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 201 times.
298 if (decimallen > decimalcount)
2117 {
2118 97 ndx = gate_str_print_text(bufferptr, bufferlen, &decimalbuffer[0], decimalcount);
2119
2/2
✓ Branch 0 taken 482 times.
✓ Branch 1 taken 97 times.
579 for (; ndx < decimallen; ++ndx)
2120 {
2121 482 bufferptr[ndx] = '0';
2122 }
2123 }
2124 else
2125 {
2126 201 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 302 bufferptr += ndx;
2134 302 bufferlen -= ndx;
2135 302 bufferused += ndx;
2136 }
2137
2138 306 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 404 times.
✓ Branch 1 taken 64 times.
468 if (nibble < 10)
2144 {
2145 404 return '0' + nibble;
2146 }
2147 else
2148 {
2149
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 40 times.
64 if (uppercase)
2150 {
2151 24 return 'A' + (nibble - 10);
2152 }
2153 else
2154 {
2155 40 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_CALL 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 1439 gate_bool_t gate_str_parse_digit(gate_char8_t const* src, gate_uint8_t* digit)
2693 {
2694 1439 gate_char8_t chr = *src;
2695
4/4
✓ Branch 0 taken 1317 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 1235 times.
✓ Branch 3 taken 82 times.
1439 if ((chr >= '0') && (chr <= '9'))
2696 {
2697 1235 *digit = chr - '0';
2698 1235 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 1364 times.
✓ Branch 1 taken 360 times.
1724 while (srclen-- != 0)
2762 {
2763
2/2
✓ Branch 1 taken 194 times.
✓ Branch 2 taken 1170 times.
1364 if (!gate_str_parse_digit(src, &digit))
2764 {
2765 194 break;
2766 }
2767 1170 tmp *= 10;
2768 1170 tmp += (gate_uint64_t)digit;
2769 1170 ++src;
2770 1170 ++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 153 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 153 times.
153 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 153 pos = gate_str_char_pos(text, textlen, '\n', 0);
2978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 153 times.
153 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 153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 153 times.
✗ Branch 3 not taken.
153 if ((buffer != NULL) && (bufferlen != NULL))
3004 {
3005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 153 times.
153 if (*bufferlen < pos)
3006 {
3007 gate_mem_copy(buffer, text, *bufferlen);
3008 return *bufferlen;
3009 }
3010 else
3011 {
3012 153 gate_mem_copy(buffer, text, pos);
3013
1/2
✓ Branch 0 taken 153 times.
✗ Branch 1 not taken.
153 if (*bufferlen > pos)
3014 {
3015 153 buffer[pos] = 0;
3016 }
3017 153 *bufferlen = pos;
3018
1/2
✓ Branch 0 taken 153 times.
✗ Branch 1 not taken.
153 if (pos > 0)
3019 {
3020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 153 times.
153 if (buffer[pos - 1] == '\r')
3021 {
3022 buffer[pos - 1] = 0;
3023 --*bufferlen;
3024 }
3025 }
3026 }
3027 }
3028 153 return pos + 1;
3029 }
3030 }
3031 }
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042 /************************
3043 * String implementation *
3044 *************************/
3045
3046 2672 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 1892 times.
✓ Branch 1 taken 780 times.
2672 if (len > 0)
3049 {
3050 1892 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + len + 1);
3051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1892 times.
1892 if (obj->buffer == NULL)
3052 {
3053 return NULL;
3054 }
3055 1892 gate_mem_copy(&obj->buffer->data[0], str, len);
3056 1892 obj->buffer->data[len] = 0;
3057 1892 obj->str = &obj->buffer->data[0];
3058 1892 obj->length = len;
3059 1892 gate_atomic_int_init(&obj->buffer->refcount, 1);
3060 }
3061 else
3062 {
3063 780 gate_string_create_empty(obj);
3064 }
3065
3066 2672 return obj;
3067 }
3068 6090 gate_string_t* gate_string_create_static_len(gate_string_t* obj, gate_char8_t const* str, gate_size_t len)
3069 {
3070 6090 obj->str = str;
3071 6090 obj->length = len;
3072 6090 obj->buffer = NULL;
3073 6090 return obj;
3074 }
3075 2908 gate_string_t* gate_string_create_static(gate_string_t* obj, gate_char8_t const* str)
3076 {
3077 2908 gate_size_t const len = gate_str_length(str);
3078 2908 return gate_string_create_static_len(obj, str, len);
3079 }
3080 4695 gate_string_t* gate_string_create_empty(gate_string_t* obj)
3081 {
3082 4695 obj->str = NULL;
3083 4695 obj->length = 0;
3084 4695 obj->buffer = NULL;
3085 4695 return obj;
3086 }
3087 1 gate_string_t* gate_string_create_utf16(gate_string_t* obj, gate_char16_t const* str, gate_size_t len)
3088 {
3089 gate_char32_t chr32;
3090 1 gate_size_t processed16 = 0;
3091 gate_size_t decoded;
3092 gate_char8_t buffer[16];
3093 gate_size_t encoded;
3094 1 gate_size_t required8 = 0;
3095 1 gate_size_t used8 = 0;
3096 1 char* ptr = NULL;
3097
3098
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 while (processed16 < len)
3099 {
3100 5 decoded = gate_char_read_utf16(&str[processed16], len - processed16, &chr32);
3101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (decoded == 0)
3102 {
3103 break;
3104 }
3105
3106 5 processed16 += decoded;
3107 5 encoded = gate_char_write_utf8(chr32, buffer, sizeof(buffer));
3108 5 required8 += encoded;
3109 }
3110
3111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (required8 == 0)
3112 {
3113 gate_string_create_empty(obj);
3114 }
3115 else
3116 {
3117 1 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + required8 + 1);
3118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (obj->buffer == NULL)
3119 {
3120 return NULL;
3121 }
3122 1 processed16 = 0;
3123 1 ptr = &obj->buffer->data[0];
3124
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))
3125 {
3126 5 decoded = gate_char_read_utf16(&str[processed16], len - processed16, &chr32);
3127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (decoded == 0)
3128 {
3129 break;
3130 }
3131
3132 5 processed16 += decoded;
3133 5 encoded = gate_char_write_utf8(chr32, ptr, required8 - used8);
3134 5 used8 += encoded;
3135 5 ptr += encoded;
3136 }
3137 1 *ptr = 0;
3138
3139 1 obj->str = &obj->buffer->data[0];
3140 1 obj->length = used8;
3141 1 gate_atomic_int_init(&obj->buffer->refcount, 1);
3142 }
3143
3144 1 return obj;
3145 }
3146 2 gate_string_t* gate_string_create_utf32(gate_string_t* obj, gate_char32_t const* str, gate_size_t len)
3147 {
3148 2 gate_size_t processed32 = 0;
3149 gate_char8_t buffer[16];
3150 gate_size_t encoded;
3151 2 gate_size_t required8 = 0;
3152 2 gate_size_t used8 = 0;
3153 2 char* ptr = NULL;
3154
3155
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 while (processed32 < len)
3156 {
3157 9 encoded = gate_char_write_utf8(str[processed32], buffer, sizeof(buffer));
3158 9 ++processed32;
3159 9 required8 += encoded;
3160 }
3161
3162 2 obj->buffer = gate_mem_alloc(sizeof(gate_stringbuffer_t) + required8 + 1);
3163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (obj->buffer == NULL)
3164 {
3165 return NULL;
3166 }
3167
3168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (required8 == 0)
3169 {
3170 gate_string_create_empty(obj);
3171 }
3172 else
3173 {
3174 2 processed32 = 0;
3175 2 ptr = &obj->buffer->data[0];
3176
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))
3177 {
3178 9 encoded = gate_char_write_utf8(str[processed32], ptr, required8 - used8);
3179 9 ++processed32;
3180 9 used8 += encoded;
3181 9 ptr += encoded;
3182 }
3183 2 *ptr = 0;
3184
3185 2 obj->str = &obj->buffer->data[0];
3186 2 obj->length = used8;
3187 2 gate_atomic_int_init(&obj->buffer->refcount, 1);
3188 }
3189
3190 2 return obj;
3191
3192 }
3193 14 gate_string_t* gate_string_create_copy(gate_string_t* obj, gate_string_t const* src)
3194 {
3195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (src == NULL)
3196 {
3197 return gate_string_create_empty(obj);
3198 }
3199 else
3200 {
3201 14 return gate_string_create(obj, src->str, src->length);
3202 }
3203 }
3204
3205
3206
3207 26443 void gate_string_release(gate_string_t* obj)
3208 {
3209
2/2
✓ Branch 0 taken 16337 times.
✓ Branch 1 taken 10106 times.
26443 if (obj->buffer != NULL)
3210 {
3211
2/2
✓ Branch 1 taken 2680 times.
✓ Branch 2 taken 13657 times.
16337 if (gate_atomic_int_dec(&obj->buffer->refcount) == 0)
3212 {
3213 2680 gate_mem_dealloc(obj->buffer);
3214 }
3215 16337 obj->buffer = NULL;
3216 }
3217 26443 obj->str = NULL;
3218 26443 obj->length = 0;
3219 26443 }
3220
3221 4738 gate_bool_t gate_string_is_empty(gate_string_t const* obj)
3222 {
3223
2/2
✓ Branch 0 taken 4718 times.
✓ Branch 1 taken 20 times.
4738 if (obj != NULL)
3224 {
3225
2/2
✓ Branch 0 taken 4180 times.
✓ Branch 1 taken 538 times.
4718 if (obj->length > 0)
3226 {
3227 4180 return false;
3228 }
3229 }
3230 558 return true;
3231 }
3232
3233 7710 gate_string_t* gate_string_duplicate(gate_string_t* dst, gate_string_t const* src)
3234 {
3235
2/2
✓ Branch 0 taken 7485 times.
✓ Branch 1 taken 225 times.
7710 if (src != NULL)
3236 {
3237 7485 dst->buffer = src->buffer;
3238 7485 dst->str = src->str;
3239 7485 dst->length = src->length;
3240
2/2
✓ Branch 0 taken 6431 times.
✓ Branch 1 taken 1054 times.
7485 if (dst->buffer != NULL)
3241 {
3242 6431 gate_atomic_int_inc(&dst->buffer->refcount);
3243 }
3244 }
3245 else
3246 {
3247 225 dst->buffer = NULL;
3248 225 dst->str = NULL;
3249 225 dst->length = 0;
3250 }
3251 7710 return dst;
3252 }
3253 3710 gate_string_t* gate_string_clone(gate_string_t* dst, gate_string_t const* src)
3254 {
3255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3710 times.
3710 if (src == NULL)
3256 {
3257 return gate_string_create_empty(dst);
3258 }
3259 else
3260 {
3261
2/2
✓ Branch 0 taken 1117 times.
✓ Branch 1 taken 2593 times.
3710 if (src->buffer == NULL)
3262 {
3263 1117 return gate_string_create(dst, src->str, src->length);
3264 }
3265 else
3266 {
3267 2593 dst->str = src->str;
3268 2593 dst->length = src->length;
3269 2593 dst->buffer = src->buffer;
3270 2593 gate_atomic_int_inc(&dst->buffer->refcount);
3271 2593 return dst;
3272 }
3273 }
3274 }
3275
3276 37817 gate_size_t gate_string_length(gate_string_t const* obj)
3277 {
3278
1/2
✓ Branch 0 taken 37817 times.
✗ Branch 1 not taken.
37817 return obj ? obj->length : 0;
3279 }
3280 4 gate_bool_t gate_string_like(gate_string_t const* obj, gate_string_t const* pattern)
3281 {
3282 4 return gate_str_like(obj->str, obj->length, pattern->str, pattern->length);
3283 }
3284 28 gate_bool_t gate_string_like_one_of(gate_string_t const* obj, gate_string_t const* pattern, gate_char8_t separator)
3285 {
3286 28 return gate_str_like_one_of(obj->str, obj->length, pattern->str, pattern->length, separator);
3287 }
3288
3289
3290 180 gate_size_t gate_string_count_chars(gate_string_t const* obj, gate_char8_t chr)
3291 {
3292
1/2
✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
180 if (obj)
3293 {
3294 180 return gate_str_count_chars(obj->str, obj->length, chr);
3295 }
3296 return 0;
3297 }
3298 81 gate_char8_t gate_string_char_at(gate_string_t const* str, gate_size_t index)
3299 {
3300 81 gate_char8_t ret = '\0';
3301
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))
3302 {
3303 81 ret = str->str[index];
3304 }
3305 81 return ret;
3306 }
3307
3308 1344 gate_size_t gate_string_char_pos(gate_string_t const* obj, gate_char8_t find, gate_size_t startat)
3309 {
3310 1344 return gate_str_char_pos(obj->str, obj->length, find, startat);
3311 }
3312 446 gate_size_t gate_string_char_pos_last(gate_string_t const* obj, gate_char8_t find)
3313 {
3314 446 return gate_str_char_pos_last(obj->str, obj->length, find);
3315 }
3316 10 gate_size_t gate_string_find_first_of(gate_string_t const* obj, gate_string_t const* chars, gate_size_t startat)
3317 {
3318 10 return gate_str_find_first_of(obj->str, obj->length, chars->str, chars->length, startat);
3319 }
3320 77 gate_size_t gate_string_find_first_not_of(gate_string_t const* obj, gate_string_t const* chars, gate_size_t startat)
3321 {
3322 77 return gate_str_find_first_not_of(obj->str, obj->length, chars->str, chars->length, startat);
3323 }
3324 2 gate_size_t gate_string_find_last_of(gate_string_t const* obj, gate_string_t const* chars)
3325 {
3326 2 return gate_str_find_last_of(obj->str, obj->length, chars->str, chars->length);
3327 }
3328 26 gate_size_t gate_string_find_last_not_of(gate_string_t const* obj, gate_string_t const* chars)
3329 {
3330 26 return gate_str_find_last_not_of(obj->str, obj->length, chars->str, chars->length);
3331 }
3332
3333 68 gate_size_t gate_string_pos(gate_string_t const* obj, gate_string_t const* find, gate_size_t startat)
3334 {
3335 68 return gate_str_pos(obj->str, obj->length, find->str, find->length, startat);
3336 }
3337 2 gate_size_t gate_string_pos_last(gate_string_t const* obj, gate_string_t const* find)
3338 {
3339 2 return gate_str_pos_last(obj->str, obj->length, find->str, find->length);
3340 }
3341
3342
3343 43 gate_size_t gate_string_parse(gate_string_t const* obj, gate_string_t const* find, gate_size_t start_at,
3344 gate_string_t* head, gate_string_t* tail, gate_bool_t separator_as_tail)
3345 {
3346 43 gate_size_t pos = gate_string_pos(obj, find, start_at);
3347
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 32 times.
43 if (pos == GATE_STR_NPOS)
3348 {
3349 11 return 0; /* nothing parsed */
3350 }
3351 else
3352 {
3353
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (head)
3354 {
3355 32 gate_string_substr(head, obj, 0, pos);
3356 }
3357
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (tail)
3358 {
3359
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 25 times.
32 if (separator_as_tail)
3360 {
3361 7 gate_string_substr(tail, obj, pos, GATE_STR_NPOS);
3362 }
3363 else
3364 {
3365 25 gate_string_substr(tail, obj, pos + find->length, GATE_STR_NPOS);
3366 }
3367 }
3368 32 return pos + gate_string_length(find); /* (head + separator) parsed */
3369 }
3370 }
3371
3372 4 gate_size_t gate_string_parse_int(gate_string_t const* obj, gate_int64_t* num)
3373 {
3374 4 return gate_str_parse_int64(obj->str, obj->length, num);
3375 }
3376
3377 129 gate_size_t gate_string_parse_uint(gate_string_t const* obj, gate_uint64_t* num)
3378 {
3379 129 return gate_str_parse_uint64(obj->str, obj->length, num);
3380 }
3381
3382 3 gate_size_t gate_string_parse_real(gate_string_t const* obj, gate_real64_t* num)
3383 {
3384 3 return gate_str_parse_real(obj->str, obj->length, num);
3385 }
3386
3387
3388 1 gate_size_t gate_string_parse_hex(gate_string_t const* obj, gate_uint64_t* num)
3389 {
3390 1 return gate_str_parse_hex_int(obj->str, obj->length, num);
3391 }
3392
3393
3394 3371 gate_char8_t const* gate_string_ptr(gate_string_t const* obj, gate_size_t index)
3395 {
3396
3/4
✓ Branch 0 taken 3371 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3355 times.
✓ Branch 3 taken 16 times.
3371 if ((obj != NULL) && (obj->str != NULL))
3397 {
3398 3355 return obj->str + index;
3399 }
3400 else
3401 {
3402 16 return NULL;
3403 }
3404 }
3405 5928 gate_string_t* gate_string_substr(gate_string_t* dst, gate_string_t const* src, gate_size_t offset, gate_size_t length)
3406 {
3407
1/2
✓ Branch 0 taken 5928 times.
✗ Branch 1 not taken.
5928 if (dst != NULL)
3408 {
3409
5/6
✓ Branch 0 taken 5928 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5877 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 5856 times.
5928 if ((src == NULL) || (offset >= src->length) || (length == 0))
3410 {
3411
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
144 if (src == dst)
3412 {
3413 48 gate_string_release(dst);
3414 }
3415 else
3416 {
3417 24 dst->str = NULL;
3418 24 dst->length = 0;
3419 24 dst->buffer = NULL;
3420 }
3421 }
3422 else
3423 {
3424
2/2
✓ Branch 0 taken 2881 times.
✓ Branch 1 taken 2975 times.
5856 if (length > src->length - offset)
3425 {
3426 2881 length = src->length - offset;
3427 }
3428
3429 5856 dst->buffer = src->buffer;
3430 5856 dst->str = &src->str[offset];
3431 5856 dst->length = length;
3432
3433
4/4
✓ Branch 0 taken 3978 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 3017 times.
✓ Branch 3 taken 961 times.
5856 if ((dst->buffer != NULL) && (dst != src))
3434 {
3435 3017 gate_atomic_int_inc(&dst->buffer->refcount);
3436 }
3437 }
3438 }
3439 5928 return dst;
3440 }
3441
3442 9675 int gate_string_comp(gate_string_t const* src, gate_string_t const* dst)
3443 {
3444 9675 gate_char8_t const* ptr_src = NULL;
3445 9675 gate_size_t len_src = 0;
3446 9675 gate_char8_t const* ptr_dst = NULL;
3447 9675 gate_size_t len_dst = 0;
3448
3449
1/2
✓ Branch 0 taken 9675 times.
✗ Branch 1 not taken.
9675 if (src)
3450 {
3451 9675 ptr_src = src->str;
3452 9675 len_src = src->length;
3453 }
3454
2/2
✓ Branch 0 taken 9669 times.
✓ Branch 1 taken 6 times.
9675 if (dst)
3455 {
3456 9669 ptr_dst = dst->str;
3457 9669 len_dst = dst->length;
3458 }
3459
3460 9675 return gate_str_compare(ptr_src, len_src, ptr_dst, len_dst);
3461 }
3462
3463 497 int gate_string_comp_ic(gate_string_t const* src, gate_string_t const* dst)
3464 {
3465 497 gate_char8_t const* ptr_src = NULL;
3466 497 gate_size_t len_src = 0;
3467 497 gate_char8_t const* ptr_dst = NULL;
3468 497 gate_size_t len_dst = 0;
3469
3470
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 if (src)
3471 {
3472 497 ptr_src = src->str;
3473 497 len_src = src->length;
3474 }
3475
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 if (dst)
3476 {
3477 497 ptr_dst = dst->str;
3478 497 len_dst = dst->length;
3479 }
3480 497 return gate_str_compare_ic(ptr_src, len_src, ptr_dst, len_dst);
3481 }
3482 1134 gate_size_t gate_string_to_buffer(gate_string_t const* src, gate_char8_t* buffer, gate_size_t bufferlength)
3483 {
3484 gate_size_t ret;
3485
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))
3486 {
3487 ret = 0;
3488 }
3489 else
3490 {
3491
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1131 times.
1134 if (gate_string_is_empty(src))
3492 {
3493 3 buffer[0] = 0;
3494 3 ret = 0;
3495 }
3496 else
3497 {
3498 1131 ret = gate_str_print_text(buffer, bufferlength, src->str, src->length);
3499 }
3500 }
3501 1134 return ret;
3502 }
3503
3504
3505 12423 gate_bool_t gate_string_starts_with(gate_string_t const* obj, gate_string_t const* token)
3506 {
3507 12423 gate_size_t objlen = gate_string_length(obj);
3508 12423 gate_size_t tokenlen = gate_string_length(token);
3509
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))
3510 {
3511 725 return false;
3512 }
3513 11698 return (gate_str_compare(obj->str, tokenlen, token->str, tokenlen) == 0);
3514 }
3515 352 gate_bool_t gate_string_starts_with_str(gate_string_t const* obj, gate_char8_t const* text)
3516 {
3517 gate_string_t tmp;
3518 352 gate_string_create_static(&tmp, text);
3519 352 return gate_string_starts_with(obj, &tmp);
3520 }
3521 3091 gate_bool_t gate_string_starts_with_char(gate_string_t const* obj, gate_char8_t chr)
3522 {
3523 3091 gate_size_t objlen = gate_string_length(obj);
3524
4/4
✓ Branch 0 taken 3089 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1588 times.
✓ Branch 3 taken 1501 times.
3091 return (objlen >= 1) && (obj->str[0] == chr);
3525 }
3526 1 gate_bool_t gate_string_starts_with_ic(gate_string_t const* obj, gate_string_t const* token)
3527 {
3528 1 gate_size_t objlen = gate_string_length(obj);
3529 1 gate_size_t tokenlen = gate_string_length(token);
3530
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))
3531 {
3532 return false;
3533 }
3534 1 return (gate_str_compare_ic(obj->str, tokenlen, token->str, tokenlen) == 0);
3535 }
3536 1 gate_bool_t gate_string_starts_with_str_ic(gate_string_t const* obj, gate_char8_t const* text)
3537 {
3538 gate_string_t tmp;
3539 1 gate_string_create_static(&tmp, text);
3540 1 return gate_string_starts_with_ic(obj, &tmp);
3541 }
3542
3543 480 gate_bool_t gate_string_ends_with(gate_string_t const* obj, gate_string_t const* token)
3544 {
3545 480 gate_size_t objlen = gate_string_length(obj);
3546 480 gate_size_t tokenlen = gate_string_length(token);
3547
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))
3548 {
3549 2 return false;
3550 }
3551 478 return (gate_str_compare(&obj->str[objlen - tokenlen], tokenlen, token->str, tokenlen) == 0);
3552 }
3553 460 gate_bool_t gate_string_ends_with_str(gate_string_t const* obj, gate_char8_t const* text)
3554 {
3555 gate_string_t tmp;
3556 460 gate_string_create_static(&tmp, text);
3557 460 return gate_string_ends_with(obj, &tmp);
3558 }
3559 439 gate_bool_t gate_string_ends_with_char(gate_string_t const* obj, gate_char8_t chr)
3560 {
3561 439 gate_size_t objlen = gate_string_length(obj);
3562
3/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 435 times.
439 return (objlen >= 1) && (obj->str[objlen - 1] == chr);
3563 }
3564 1 gate_bool_t gate_string_ends_with_ic(gate_string_t const* obj, gate_string_t const* token)
3565 {
3566 1 gate_size_t objlen = gate_string_length(obj);
3567 1 gate_size_t tokenlen = gate_string_length(token);
3568
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))
3569 {
3570 return false;
3571 }
3572 1 return (gate_str_compare_ic(&obj->str[objlen - tokenlen], tokenlen, token->str, tokenlen) == 0);
3573 }
3574 1 gate_bool_t gate_string_ends_with_str_ic(gate_string_t const* obj, gate_char8_t const* text)
3575 {
3576 gate_string_t tmp;
3577 1 gate_string_create_static(&tmp, text);
3578 1 return gate_string_ends_with_ic(obj, &tmp);
3579 }
3580
3581 1 gate_bool_t gate_string_contains(gate_string_t const* obj, gate_string_t const* token)
3582 {
3583 1 return gate_string_pos(obj, token, 0) != GATE_STR_NPOS;
3584 }
3585
3586 1379 gate_bool_t gate_string_equals(gate_string_t const* obj, gate_string_t const* token)
3587 {
3588 1379 return gate_string_comp(obj, token) == 0;
3589 }
3590 605 gate_bool_t gate_string_equals_str(gate_string_t const* obj, gate_char8_t const* token)
3591 {
3592 gate_string_t tmp;
3593 605 gate_string_create_static(&tmp, token);
3594 605 return gate_string_equals(obj, &tmp);
3595 }
3596 8 gate_bool_t gate_string_equals_ic(gate_string_t const* obj, gate_string_t const* token)
3597 {
3598 8 return gate_string_comp_ic(obj, token) == 0;
3599 }
3600 4 gate_bool_t gate_string_equals_str_ic(gate_string_t const* obj, gate_char8_t const* token)
3601 {
3602 gate_string_t tmp;
3603 4 gate_string_create_static(&tmp, token);
3604 4 return gate_string_equals_ic(obj, &tmp);
3605 }
3606 1982 gate_string_t* gate_string_ltrim(gate_string_t* dst, gate_string_t const* src)
3607 {
3608 1982 gate_size_t pos = gate_str_find_first_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3609
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1914 times.
1982 if (pos == GATE_STR_NPOS)
3610 {
3611
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 if (dst == src)
3612 {
3613 68 gate_string_release(dst);
3614 }
3615 68 gate_string_create_empty(dst);
3616 }
3617 else
3618 {
3619 1914 dst->str = &src->str[pos];
3620 1914 dst->length = src->length - pos;
3621
2/2
✓ Branch 0 taken 1617 times.
✓ Branch 1 taken 297 times.
1914 if (dst != src)
3622 {
3623 1617 dst->buffer = src->buffer;
3624
2/2
✓ Branch 0 taken 1616 times.
✓ Branch 1 taken 1 times.
1617 if (dst->buffer != NULL)
3625 {
3626 1616 gate_atomic_int_inc(&dst->buffer->refcount);
3627 }
3628 }
3629 }
3630 1982 return dst;
3631 }
3632 159 gate_string_t* gate_string_rtrim(gate_string_t* dst, gate_string_t const* src)
3633 {
3634 159 gate_size_t pos = gate_str_find_last_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH);
3635
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 135 times.
159 if (pos == GATE_STR_NPOS)
3636 {
3637
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (dst == src)
3638 {
3639 24 gate_string_release(dst);
3640 }
3641 24 gate_string_create_empty(dst);
3642 }
3643 else
3644 {
3645 135 dst->length = pos + 1;
3646
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 134 times.
135 if (dst != src)
3647 {
3648 1 dst->str = src->str;
3649 1 dst->buffer = src->buffer;
3650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (dst->buffer != NULL)
3651 {
3652 gate_atomic_int_inc(&dst->buffer->refcount);
3653 }
3654 }
3655 }
3656 159 return dst;
3657 }
3658 3575 gate_string_t* gate_string_trim(gate_string_t* dst, gate_string_t const* src)
3659 {
3660 3575 gate_size_t newlength = gate_str_find_last_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH);
3661 gate_size_t pos;
3662
3663
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 3431 times.
3575 if (newlength == GATE_STR_NPOS)
3664 {
3665
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if (dst == src)
3666 {
3667 144 gate_string_release(dst);
3668 }
3669 144 return gate_string_create_empty(dst);
3670 }
3671 3431 ++newlength;
3672
3673 3431 pos = gate_str_find_first_not_of(src->str, newlength, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3674
3675 3431 dst->str = &src->str[pos];
3676 3431 dst->length = newlength - pos;
3677
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3430 times.
3431 if (dst != src)
3678 {
3679 1 dst->buffer = src->buffer;
3680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (dst->buffer != NULL)
3681 {
3682 gate_atomic_int_inc(&dst->buffer->refcount);
3683 }
3684 }
3685 3431 return dst;
3686 }
3687
3688 163 gate_string_t* gate_string_read_line(gate_string_t* line, gate_string_t const* src, gate_string_t* tail)
3689 {
3690 163 gate_string_t* ret = NULL;
3691 gate_size_t pos;
3692
2/2
✓ Branch 1 taken 154 times.
✓ Branch 2 taken 9 times.
163 if (!gate_string_is_empty(src))
3693 {
3694 154 pos = gate_str_char_pos(src->str, src->length, '\n', 0);
3695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
154 if (pos == GATE_STR_NPOS)
3696 {
3697 ret = gate_string_duplicate(line, src);
3698 if (tail != NULL)
3699 {
3700 if (tail == src)
3701 {
3702 gate_string_release(tail);
3703 }
3704 else
3705 {
3706 gate_string_create_empty(tail);
3707 }
3708 }
3709 }
3710 else
3711 {
3712 154 ret = gate_string_substr(line, src, 0, pos);
3713
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (ret != NULL)
3714 {
3715
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 78 times.
154 if (gate_string_ends_with_str(line, "\r"))
3716 {
3717 76 --line->length;
3718 }
3719 }
3720
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (tail != NULL)
3721 {
3722
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 60 times.
154 if (tail == src)
3723 {
3724 94 tail->str += (pos + 1);
3725 94 tail->length -= (pos + 1);
3726 }
3727 else
3728 {
3729 60 gate_string_substr(tail, src, pos + 1, GATE_STR_NPOS);
3730 }
3731 }
3732 }
3733 }
3734 163 return ret;
3735 }
3736
3737 14 gate_string_t* gate_string_read_token(gate_string_t* token, gate_string_t const* src, gate_string_t* tail)
3738 {
3739 14 gate_string_t* ret = NULL;
3740 gate_size_t pos;
3741 gate_size_t pos2;
3742
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 if (!gate_string_is_empty(src))
3743 {
3744 14 pos = gate_str_find_first_not_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, 0);
3745
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (pos == GATE_STR_NPOS)
3746 {
3747 ret = gate_string_create_empty(token);
3748 if (tail != NULL)
3749 {
3750 gate_string_create_empty(tail);
3751 }
3752 }
3753 else
3754 {
3755 14 pos2 = gate_str_find_first_of(src->str, src->length, GATE_STR_WHITESPACES, GATE_STR_WHITESPACES_LENGTH, pos);
3756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (pos2 == GATE_STR_NPOS)
3757 {
3758 ret = gate_string_substr(token, src, pos, src->length - pos);
3759 if (tail != NULL)
3760 {
3761 gate_string_create_empty(tail);
3762 }
3763 }
3764 else
3765 {
3766 14 ret = gate_string_substr(token, src, pos, pos2 - pos);
3767
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (tail != NULL)
3768 {
3769 14 gate_string_substr(tail, src, pos2, src->length - pos2);
3770 }
3771 }
3772 }
3773 }
3774 14 return ret;
3775 }
3776
3777 1 gate_string_t* gate_string_to_lower(gate_string_t* dst, gate_string_t const* src)
3778 {
3779 1 gate_string_t* ret = gate_string_create_copy(dst, src);
3780
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (NULL != ret)
3781 {
3782 1 gate_str_to_lower(ret->buffer->data, ret->length);
3783 }
3784 1 return ret;
3785 }
3786 1 gate_string_t* gate_string_to_upper(gate_string_t* dst, gate_string_t const* src)
3787 {
3788 1 gate_string_t* ret = gate_string_create_copy(dst, src);
3789
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (NULL != ret)
3790 {
3791 1 gate_str_to_upper(ret->buffer->data, ret->length);
3792 }
3793 1 return ret;
3794 }
3795 1 gate_uint32_t gate_string_hash(gate_string_t const* obj)
3796 {
3797 1 return gate_str_hash(gate_string_ptr(obj, 0), gate_string_length(obj));
3798 }
3799
3800
3801
3802
3803 2272 gate_result_t gate_string_copy_constructor(void* destMem, void const* srcMem)
3804 {
3805 2272 gate_string_t* dst = (gate_string_t*)destMem;
3806 2272 gate_string_t const* src = (gate_string_t const*)srcMem;
3807
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2272 times.
2272 if (NULL == gate_string_clone(dst, src))
3808 {
3809 return GATE_RESULT_OUTOFMEMORY;
3810 }
3811 else
3812 {
3813 2272 return GATE_RESULT_OK;
3814 }
3815 }
3816 43 gate_result_t gate_string_duplicate_constructor(void* destMem, void const* srcMem)
3817 {
3818 43 gate_string_t* dst = (gate_string_t*)destMem;
3819 43 gate_string_t const* src = (gate_string_t const*)srcMem;
3820
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 if (NULL == gate_string_duplicate(dst, src))
3821 {
3822 return GATE_RESULT_OUTOFMEMORY;
3823 }
3824 else
3825 {
3826 43 return GATE_RESULT_OK;
3827 }
3828 }
3829 2315 void gate_string_destructor(void* dest)
3830 {
3831 2315 gate_string_t* dst = (gate_string_t*)dest;
3832 2315 gate_string_release(dst);
3833 2315 }
3834
3835
3836
3837
3838
3839 #define GATE_CSTRBUFFER_CREATE_IMPL(char_type, buffer, textptr, length, copy_needed) \
3840 if(!buffer) return NULL; \
3841 gate_mem_clear(buffer, sizeof(*buffer)); \
3842 if(length > 0) \
3843 { \
3844 buffer->length = length; \
3845 if(!copy_needed && (textptr[length] == 0)) \
3846 { \
3847 buffer->str = textptr; \
3848 } \
3849 else if(length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]))) \
3850 { \
3851 gate_mem_copy(buffer->local_buffer, textptr, length * sizeof(buffer->local_buffer[0])); \
3852 buffer->local_buffer[length] = 0; \
3853 buffer->str = &buffer->local_buffer[0]; \
3854 } \
3855 else \
3856 { \
3857 buffer->heap_buffer = ( char_type *)gate_mem_alloc((length + 1) * sizeof(char_type)); \
3858 if(buffer->heap_buffer) \
3859 { \
3860 gate_mem_copy(buffer->heap_buffer, textptr, length * sizeof(char_type)); \
3861 buffer->heap_buffer[length] = 0; \
3862 buffer->str = buffer->heap_buffer; \
3863 } \
3864 else \
3865 { \
3866 buffer->length = 0; \
3867 buffer = NULL; \
3868 } \
3869 } \
3870 } \
3871 return buffer
3872
3873 #define GATE_CSTRBUFFER_DESTROY_IMPL(buffer) \
3874 do { \
3875 if(!buffer) break; \
3876 if(buffer->heap_buffer && (buffer->str == buffer->heap_buffer)) \
3877 { \
3878 gate_mem_dealloc(buffer->heap_buffer); \
3879 } \
3880 gate_mem_clear(buffer, sizeof(*buffer)); \
3881 } while(0)
3882
3883 #define GATE_CSTRBUFFER_GET_IMPL(buffer) return buffer ? buffer->str : NULL
3884
3885 #define GATE_CSTRBUFFER_LENGTH_IMPL(buffer) return buffer ? buffer->length : 0
3886
3887
3888 3 gate_cstrbuffer_t* gate_cstrbuffer_create_string(gate_cstrbuffer_t* buffer, gate_string_t const* strptr, gate_bool_t copy_needed)
3889 {
3890
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (strptr)
3891 {
3892 3 return gate_cstrbuffer_create(buffer, strptr->str, strptr->length, copy_needed);
3893 }
3894 else if (buffer)
3895 {
3896 gate_mem_clear(buffer, sizeof(*buffer));
3897 }
3898 return buffer;
3899 }
3900
3901 2 gate_cstrbuffer_t* gate_cstrbuffer_create_wstr(gate_cstrbuffer_t* buffer, wchar_t const* textptr, gate_size_t length)
3902 {
3903 2 const gate_size_t required_buffer = length * 3 + 1;
3904 2 char* target = NULL;
3905 2 gate_size_t used = 0;
3906
3907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!buffer) return NULL;
3908 2 gate_mem_clear(buffer, sizeof(*buffer));
3909
3910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (sizeof(buffer->local_buffer) <= required_buffer)
3911 {
3912 buffer->heap_buffer = (char*)gate_mem_alloc(required_buffer);
3913 if (NULL == buffer->heap_buffer)
3914 {
3915 /* allocation failed */
3916 return NULL;
3917 }
3918 target = buffer->heap_buffer;
3919 }
3920 else
3921 {
3922 2 target = &buffer->local_buffer[0];
3923 }
3924
3925 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
3926 used = gate_str_utf16_2_utf8((gate_char16_t const*)textptr, length, target, required_buffer - 1);
3927 #else
3928 2 used = gate_str_utf32_2_utf8((gate_char32_t const*)textptr, length, target, required_buffer - 1);
3929 #endif
3930
3931 2 buffer->str = target;
3932 2 buffer->length = used;
3933 2 return buffer;
3934 }
3935
3936 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)
3937 {
3938
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);
3939 }
3940
3941 12 void gate_cstrbuffer_destroy(gate_cstrbuffer_t* buffer)
3942 {
3943
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);
3944 12 }
3945
3946 15 gate_char8_t const* gate_cstrbuffer_get(gate_cstrbuffer_t const* buffer)
3947 {
3948
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 GATE_CSTRBUFFER_GET_IMPL(buffer);
3949 }
3950
3951 5 gate_size_t gate_cstrbuffer_length(gate_cstrbuffer_t const* buffer)
3952 {
3953
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
3954 }
3955
3956
3957
3958 3 gate_cstrbuffer16_t* gate_cstrbuffer16_create_string(gate_cstrbuffer16_t* buffer, gate_string_t const* ptr)
3959 {
3960 gate_size_t len;
3961
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (buffer)
3962 {
3963 3 gate_mem_clear(buffer, sizeof(*buffer));
3964
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)
3965 {
3966
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])))
3967 {
3968 2 len = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->local_buffer,
3969 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
3970 2 buffer->local_buffer[len] = 0;
3971 2 buffer->str = &buffer->local_buffer[0];
3972 2 buffer->length = len;
3973 }
3974 else
3975 {
3976 1 buffer->heap_buffer = (gate_char16_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char16_t));
3977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!buffer->heap_buffer)
3978 {
3979 buffer = NULL;
3980 }
3981 else
3982 {
3983 1 buffer->length = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
3984 1 buffer->heap_buffer[buffer->length] = 0;
3985 1 buffer->str = buffer->heap_buffer;
3986 }
3987 }
3988 }
3989 }
3990
3991 3 return buffer;
3992 }
3993
3994 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)
3995 {
3996
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);
3997 }
3998
3999 4 void gate_cstrbuffer16_destroy(gate_cstrbuffer16_t* buffer)
4000 {
4001
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);
4002 4 }
4003
4004 2 gate_char16_t const* gate_cstrbuffer16_get(gate_cstrbuffer16_t const* buffer)
4005 {
4006
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_GET_IMPL(buffer);
4007 }
4008
4009 2 gate_size_t gate_cstrbuffer16_length(gate_cstrbuffer16_t const* buffer)
4010 {
4011
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
4012 }
4013
4014
4015
4016 1 gate_cstrbuffer32_t* gate_cstrbuffer32_create_string(gate_cstrbuffer32_t* buffer, gate_string_t const* ptr)
4017 {
4018 gate_size_t len;
4019
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer)
4020 {
4021 1 gate_mem_clear(buffer, sizeof(*buffer));
4022
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)
4023 {
4024
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr->length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0])))
4025 {
4026 1 len = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->local_buffer,
4027 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
4028 1 buffer->local_buffer[len] = 0;
4029 1 buffer->str = &buffer->local_buffer[0];
4030 1 buffer->length = len;
4031 }
4032 else
4033 {
4034 buffer->heap_buffer = (gate_char32_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char32_t));
4035 if (!buffer->heap_buffer)
4036 {
4037 buffer = NULL;
4038 }
4039 else
4040 {
4041 buffer->length = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
4042 buffer->heap_buffer[buffer->length] = 0;
4043 buffer->str = buffer->heap_buffer;
4044 }
4045 }
4046 }
4047 }
4048
4049 1 return buffer;
4050 }
4051
4052 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)
4053 {
4054
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);
4055 }
4056
4057 2 void gate_cstrbuffer32_destroy(gate_cstrbuffer32_t* buffer)
4058 {
4059
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);
4060 2 }
4061
4062 1 gate_char32_t const* gate_cstrbuffer32_get(gate_cstrbuffer32_t const* buffer)
4063 {
4064
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_GET_IMPL(buffer);
4065 }
4066
4067 1 gate_size_t gate_cstrbuffer32_length(gate_cstrbuffer32_t const* buffer)
4068 {
4069
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
4070 }
4071