GCC Code Coverage Report


Directory: src/gate/
File: src/gate/strings.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 934 1860 50.2%
Functions: 138 250 55.2%
Branches: 493 1428 34.5%

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