GCC Code Coverage Report


Directory: src/gate/
File: src/gate/encode/texts.c
Date: 2026-02-03 22:06:38
Exec Total Coverage
Lines: 658 794 82.9%
Functions: 33 33 100.0%
Branches: 262 414 63.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/encode/texts.h"
30 #include "gate/results.h"
31 #include "gate/debugging.h"
32 #include "gate/utilities.h"
33
34 static char const gate_bom_utf8[] = { (char)0xEF, (char)0xBB, (char)0xBF };
35 static char const gate_bom_utf16le[] = { (char)0xFF, (char)0xFE };
36 static char const gate_bom_utf16be[] = { (char)0xFE, (char)0xFF };
37 static char const gate_bom_utf32le[] = { (char)0x00, (char)0x00, (char)0xFF, (char)0xFE };
38 static char const gate_bom_utf32be[] = { (char)0x00, (char)0x00, (char)0xFE, (char)0xFF };
39
40 gate_string_t const gate_text_bom_utf8 = { gate_bom_utf8, 3, NULL };
41 gate_string_t const gate_text_bom_utf16le = { gate_bom_utf16le, 2, NULL };
42 gate_string_t const gate_text_bom_utf16be = { gate_bom_utf16be, 2, NULL };
43 gate_string_t const gate_text_bom_utf32le = { gate_bom_utf32le, 4, NULL };
44 gate_string_t const gate_text_bom_utf32be = { gate_bom_utf32be, 4, NULL };
45
46 6 gate_size_t gate_text_detect_bom(char const* data, gate_size_t datalen, unsigned int* bomtype)
47 {
48
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
6 if (gate_str_starts_with(data, datalen, gate_text_bom_utf8.str, gate_text_bom_utf8.length))
49 {
50 1 *bomtype = GATE_TEXT_BOMTYPE_UTF8;
51 1 return gate_text_bom_utf8.length;
52 }
53
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
5 if (gate_str_starts_with(data, datalen, gate_text_bom_utf16le.str, gate_text_bom_utf16le.length))
54 {
55 1 *bomtype = GATE_TEXT_BOMTYPE_UTF16LE;
56 1 return gate_text_bom_utf16le.length;
57 }
58
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (gate_str_starts_with(data, datalen, gate_text_bom_utf16be.str, gate_text_bom_utf16be.length))
59 {
60 1 *bomtype = GATE_TEXT_BOMTYPE_UTF16BE;
61 1 return gate_text_bom_utf16be.length;
62 }
63
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (gate_str_starts_with(data, datalen, gate_text_bom_utf32le.str, gate_text_bom_utf32le.length))
64 {
65 1 *bomtype = GATE_TEXT_BOMTYPE_UTF32LE;
66 1 return gate_text_bom_utf32le.length;
67 }
68
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_str_starts_with(data, datalen, gate_text_bom_utf32be.str, gate_text_bom_utf32be.length))
69 {
70 1 *bomtype = GATE_TEXT_BOMTYPE_UTF32BE;
71 1 return gate_text_bom_utf32be.length;
72 }
73
74 1 *bomtype = GATE_TEXT_BOMTYPE_UNKNOWN;
75 1 return 0;
76 }
77
78
79 1 gate_result_t gate_text_load_utf8(gate_stream_t* src, gate_strbuilder8_t* dst)
80 {
81 gate_result_t ret;
82 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
83 gate_size_t bytesreturned;
84 gate_size_t byteswritten;
85
86 do
87 {
88 1 ret = gate_stream_read_block(src, buffer, 3, &bytesreturned);
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret))
90 {
91 break;
92 }
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (bytesreturned < 3)
94 {
95 gate_strbuilder_append_text(dst, buffer, bytesreturned);
96 ret = GATE_RESULT_OK;
97 break;
98 }
99
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_str_compare(buffer, bytesreturned, gate_bom_utf8, 3) != 0)
100 {
101 gate_strbuilder_append_text(dst, buffer, bytesreturned);
102 }
103
104 for (;;)
105 {
106 2 ret = gate_stream_read_block(src, buffer, sizeof(buffer), &bytesreturned);
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (GATE_FAILED(ret))
108 {
109 break;
110 }
111
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (bytesreturned == 0)
112 {
113 1 ret = GATE_RESULT_OK;
114 1 break;
115 }
116 1 byteswritten = gate_strbuilder_append_text(dst, buffer, bytesreturned);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (byteswritten != bytesreturned)
118 {
119 ret = GATE_RESULT_OUTOFMEMORY;
120 break;
121 }
122 }
123
124 } while (0);
125
126 1 return ret;
127 }
128
129 /* ANSI byte character mapping of 128 - 159 to unicode characters */
130 static const gate_uint32_t gate_text_ansi_char_map[] = {
131 8364, 129, 8218, 402, 8222, 8230, 8224, 8225,
132 710, 8240, 352, 8249, 338, 141, 381, 143,
133 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212,
134 732, 8482, 353, 8250, 339, 157, 382, 376
135 };
136
137 1 gate_result_t gate_text_load_ansi(gate_stream_t* src, gate_strbuilder8_t* dst)
138 {
139 1 gate_result_t ret = GATE_RESULT_OK;
140 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
141 gate_size_t bytesreturned;
142 gate_size_t ndx;
143 gate_uint8_t chr;
144 char utf8buffer[16];
145 gate_size_t utf8size;
146
147 do
148 {
149 2 ret = gate_stream_read_block(src, buffer, sizeof(buffer), &bytesreturned);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (GATE_FAILED(ret))
151 {
152 /* failed to read from stream */
153 break;
154 }
155
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (bytesreturned == 0)
156 {
157 /* end of stream reached -> returning success */
158 1 break;
159 }
160
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
27 for (ndx = 0; ndx != bytesreturned; ++ndx)
161 {
162 26 chr = (gate_uint8_t)buffer[ndx];
163
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (chr <= 127)
164 {
165
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (0 == gate_strbuilder_append_text(dst, &buffer[ndx], 1))
166 {
167 ret = GATE_RESULT_OUTOFMEMORY;
168 break;
169 }
170 }
171 else if (chr >= 160)
172 {
173 utf8size = gate_char_write_utf8((gate_char32_t)chr, utf8buffer, sizeof(utf8buffer));
174 if (utf8size != gate_strbuilder_append_text(dst, utf8buffer, utf8size))
175 {
176 ret = GATE_RESULT_OUTOFMEMORY;
177 break;
178 }
179 }
180 else
181 {
182 utf8size = gate_char_write_utf8(gate_text_ansi_char_map[chr - 128], utf8buffer, sizeof(utf8buffer));
183 if (utf8size != gate_strbuilder_append_text(dst, utf8buffer, utf8size))
184 {
185 ret = GATE_RESULT_OUTOFMEMORY;
186 break;
187 }
188 }
189 }
190
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } while (GATE_SUCCEEDED(ret));
191
192 1 return ret;
193
194 }
195 1 gate_result_t gate_text_load_utf16le(gate_stream_t* src, gate_strbuilder8_t* dst)
196 {
197 1 gate_result_t ret = GATE_RESULT_OK;
198 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
199 1 gate_size_t bufferpos = 0;
200 1 gate_bool_t is_first_read = true;
201
202
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 while (GATE_SUCCEEDED(ret))
203 {
204 gate_size_t bytesread;
205 gate_size_t length;
206 char* ptr;
207
208 2 ret = gate_stream_read_block(src, &buffer[bufferpos], sizeof(buffer) - bufferpos, &bytesread);
209
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (GATE_FAILED(ret) || (bytesread == 0))
210 {
211 break;
212 }
213
214 1 bufferpos += bytesread;
215 1 ptr = buffer;
216 1 length = bufferpos;
217
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 while (length > 1)
218 {
219 gate_char16_t chr16[2];
220 gate_size_t chr16used;
221 gate_char32_t chr32;
222 gate_char8_t chr8[8];
223 gate_size_t byteswritten;
224
225
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (is_first_read)
226 {
227 1 is_first_read = false;
228
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((ptr[0] == gate_bom_utf16le[0]) && (ptr[1] == gate_bom_utf16le[1]))
229 {
230 /* skip correct BOM header */
231 1 ptr += 2;
232 1 length -= 2;
233 1 continue;
234 }
235 }
236
237 52 chr16[0] = (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[0]))
238 26 | (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[1]) >> 8)
239 ;
240
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
26 if (length > 3)
241 {
242 50 chr16[1] = (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[2]))
243 25 | (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[3]) >> 8)
244 ;
245 }
246 else
247 {
248 1 chr16[1] = 0;
249 }
250 26 chr16used = gate_char_read_utf16(chr16, 2, &chr32);
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (chr16used == 0)
252 {
253 break;
254 }
255 26 ptr += 2 * chr16used;
256 26 length -= 2 * chr16used;
257
258 26 byteswritten = gate_char_write_utf8(chr32, &chr8[0], sizeof(chr8));
259
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (0 == gate_strbuilder_append_text(dst, chr8, byteswritten))
260 {
261 ret = GATE_RESULT_OUTOFMEMORY;
262 break;
263 }
264 }
265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length != 0)
266 {
267 gate_mem_move(&buffer[0], ptr, length);
268 }
269 1 bufferpos = length;
270 }
271
272 1 return ret;
273 }
274 1 gate_result_t gate_text_load_utf16be(gate_stream_t* src, gate_strbuilder8_t* dst)
275 {
276 1 gate_result_t ret = GATE_RESULT_OK;
277 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
278 1 gate_size_t bufferpos = 0;
279 1 gate_bool_t is_first_read = true;
280
281
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 while (GATE_SUCCEEDED(ret))
282 {
283 gate_size_t bytesread;
284 gate_size_t length;
285 char* ptr;
286
287 2 ret = gate_stream_read_block(src, &buffer[bufferpos], sizeof(buffer) - bufferpos, &bytesread);
288
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (GATE_FAILED(ret) || (bytesread == 0))
289 {
290 break;
291 }
292
293 1 bufferpos += bytesread;
294 1 ptr = buffer;
295 1 length = bufferpos;
296
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 while (length > 1)
297 {
298 gate_char16_t chr16[2];
299 gate_size_t chr16used;
300 gate_char32_t chr32;
301 gate_char8_t chr8[32];
302 gate_size_t byteswritten;
303
304
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (is_first_read)
305 {
306 1 is_first_read = false;
307
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((ptr[0] == gate_bom_utf16be[0]) && (ptr[1] == gate_bom_utf16be[1]))
308 {
309 /* skip correct BOM header */
310 1 ptr += 2;
311 1 length -= 2;
312 1 continue;
313 }
314 }
315
316 52 chr16[0] = (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[1]))
317 26 | (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[0]) >> 8)
318 ;
319
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
26 if (length > 3)
320 {
321 50 chr16[1] = (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[3]))
322 25 | (gate_char16_t)(((gate_uint16_t)(gate_uint8_t)ptr[2]) >> 8)
323 ;
324 }
325 else
326 {
327 1 chr16[1] = 0;
328 }
329 26 chr16used = gate_char_read_utf16(chr16, 2, &chr32);
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (chr16used == 0)
331 {
332 break;
333 }
334 26 ptr += 2 * chr16used;
335 26 length -= 2 * chr16used;
336
337 26 byteswritten = gate_char_write_utf8(chr32, &chr8[0], sizeof(chr8));
338
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (0 == gate_strbuilder_append_text(dst, chr8, byteswritten))
339 {
340 ret = GATE_RESULT_OUTOFMEMORY;
341 break;
342 }
343 }
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length != 0)
345 {
346 gate_mem_move(&buffer[0], ptr, length);
347 }
348 1 bufferpos = length;
349 }
350 1 return ret;
351 }
352 1 gate_result_t gate_text_load_utf32le(gate_stream_t* src, gate_strbuilder8_t* dst)
353 {
354 1 gate_result_t ret = GATE_RESULT_OK;
355 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
356 1 gate_size_t bufferpos = 0;
357 1 gate_bool_t is_first_read = true;
358
359
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 while (GATE_SUCCEEDED(ret))
360 {
361 gate_size_t bytesread;
362 gate_size_t length;
363 char* ptr;
364
365 2 ret = gate_stream_read_block(src, &buffer[bufferpos], sizeof(buffer) - bufferpos, &bytesread);
366
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (GATE_FAILED(ret) || (bytesread == 0))
367 {
368 break;
369 }
370
371 1 bufferpos += bytesread;
372 1 ptr = buffer;
373 1 length = bufferpos;
374
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 while (length > 3)
375 {
376 gate_char32_t chr32;
377 gate_char8_t chr8[32];
378 gate_size_t byteswritten;
379
380
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (is_first_read)
381 {
382 1 is_first_read = false;
383
4/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1 if ((ptr[0] == gate_bom_utf32le[0]) && (ptr[1] == gate_bom_utf32le[1]) && (ptr[2] == gate_bom_utf32le[2]) && (ptr[3] == gate_bom_utf32le[3]))
384 {
385 /* skip correct BOM header */
386 1 ptr += 4;
387 1 length -= 4;
388 1 continue;
389 }
390 }
391
392 52 chr32 = (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[0]))
393 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[1]) >> 8)
394 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[2]) >> 16)
395 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[3]) >> 24)
396 ;
397 26 ptr += 4;
398 26 length -= 4;
399
400 26 byteswritten = gate_char_write_utf8(chr32, &chr8[0], sizeof(chr8));
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (0 == gate_strbuilder_append_text(dst, chr8, byteswritten))
402 {
403 ret = GATE_RESULT_OUTOFMEMORY;
404 break;
405 }
406 }
407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length != 0)
408 {
409 gate_mem_move(&buffer[0], ptr, length);
410 }
411 1 bufferpos = length;
412 }
413 1 return ret;
414 }
415 1 gate_result_t gate_text_load_utf32be(gate_stream_t* src, gate_strbuilder8_t* dst)
416 {
417 1 gate_result_t ret = GATE_RESULT_OK;
418 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
419 1 gate_size_t bufferpos = 0;
420 1 gate_bool_t is_first_read = true;
421
422
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 while (GATE_SUCCEEDED(ret))
423 {
424 gate_size_t bytesread;
425 gate_size_t length;
426 char* ptr;
427
428 2 ret = gate_stream_read_block(src, &buffer[bufferpos], sizeof(buffer) - bufferpos, &bytesread);
429
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (GATE_FAILED(ret) || (bytesread == 0))
430 {
431 break;
432 }
433
434 1 bufferpos += bytesread;
435 1 ptr = buffer;
436 1 length = bufferpos;
437
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 while (length > 3)
438 {
439 gate_char32_t chr32;
440 gate_char8_t chr8[32];
441 gate_size_t byteswritten;
442
443
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (is_first_read)
444 {
445 1 is_first_read = false;
446
4/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1 if ((ptr[0] == gate_bom_utf32be[0]) && (ptr[1] == gate_bom_utf32be[1]) && (ptr[2] == gate_bom_utf32be[2]) && (ptr[3] == gate_bom_utf32be[3]))
447 {
448 /* skip correct BOM header */
449 1 ptr += 4;
450 1 length -= 4;
451 1 continue;
452 }
453 }
454
455 52 chr32 = (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[3]))
456 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[2]) >> 8)
457 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[1]) >> 16)
458 26 | (gate_char32_t)(((gate_uint32_t)(gate_uint8_t)ptr[0]) >> 24)
459 ;
460 26 ptr += 4;
461 26 length -= 4;
462
463 26 byteswritten = gate_char_write_utf8(chr32, &chr8[0], sizeof(chr8));
464
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (0 == gate_strbuilder_append_text(dst, chr8, byteswritten))
465 {
466 ret = GATE_RESULT_OUTOFMEMORY;
467 break;
468 }
469 }
470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length != 0)
471 {
472 gate_mem_move(&buffer[0], ptr, length);
473 }
474 1 bufferpos = length;
475 }
476 1 return ret;
477 }
478
479 1 gate_result_t gate_text_save_utf8(gate_string_t const* src, gate_stream_t* dst, gate_bool_t addbom)
480 {
481 1 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
482 1 gate_size_t byteswritten = 0;
483
484
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (addbom)
485 {
486 1 ret = gate_stream_write_block(dst, gate_text_bom_utf8.str, gate_text_bom_utf8.length, &byteswritten);
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret)) return ret;
488 }
489 1 ret = gate_stream_write_block(dst, src->str, src->length, &byteswritten);
490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(byteswritten == src->length);
491 1 return ret;
492 }
493 1 gate_result_t gate_text_save_ansi(gate_string_t const* src, gate_stream_t* dst)
494 {
495 1 gate_result_t ret = GATE_RESULT_OK;
496 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
497 1 gate_size_t bufferpos = 0;
498 gate_size_t byteswritten;
499 1 char const* ptr = gate_string_ptr(src, 0);
500 1 gate_size_t length = gate_string_length(src);
501
502
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
27 while ((length != 0) && GATE_SUCCEEDED(ret))
503 {
504 gate_char8_t chr8;
505 gate_char32_t chr32;
506 gate_size_t utf8block;
507 gate_size_t ndx;
508
509 26 utf8block = gate_char_read_utf8(ptr, length, &chr32);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (utf8block == 0)
511 {
512 ret = GATE_RESULT_INVALIDINPUT;
513 break;
514 }
515 26 ptr += utf8block;
516 26 length -= utf8block;
517
518
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
26 if ((chr32 <= 127) || ((chr32 >= 160) && (chr32 <= 255)))
519 {
520 26 buffer[bufferpos++] = (gate_char8_t)chr32;
521 }
522 else
523 {
524 chr8 = '?'; /* if character not in ansi map -> use '?' as replacement */
525 for (ndx = 0; ndx != sizeof(gate_text_ansi_char_map) / sizeof(gate_text_ansi_char_map[0]); ++ndx)
526 {
527 if (gate_text_ansi_char_map[ndx] == chr32)
528 {
529 chr8 = (gate_char8_t)(ndx + 128);
530 break;
531 }
532 }
533 buffer[bufferpos++] = chr8;
534 }
535
536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (bufferpos >= sizeof(buffer) / 2)
537 {
538 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
539 /* if write attempt fails, while-loop while be canceled */
540 bufferpos = 0;
541 }
542 }
543
544
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (bufferpos != 0)
545 {
546 1 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
547 1 bufferpos = 0;
548 }
549
550 1 return ret;
551 }
552 1 gate_result_t gate_text_save_utf16le(gate_string_t const* src, gate_stream_t* dst, gate_bool_t addbom)
553 {
554 1 gate_result_t ret = GATE_RESULT_OK;
555 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
556 1 gate_size_t bufferpos = 0;
557 gate_size_t byteswritten;
558 1 char const* ptr = gate_string_ptr(src, 0);
559 1 gate_size_t length = gate_string_length(src);
560
561
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (addbom)
562 {
563 1 ret = gate_stream_write_block(dst, gate_text_bom_utf16le.str, gate_text_bom_utf16le.length, &byteswritten);
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret)) return ret;
565 }
566
567
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
27 while ((length != 0) && GATE_SUCCEEDED(ret))
568 {
569 gate_char16_t utf16[8];
570 gate_size_t utf16used;
571 gate_char32_t chr32;
572 gate_size_t utf8block;
573 gate_size_t ndx;
574
575 26 utf8block = gate_char_read_utf8(ptr, length, &chr32);
576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (utf8block == 0)
577 {
578 ret = GATE_RESULT_INVALIDINPUT;
579 break;
580 }
581 26 ptr += utf8block;
582 26 length -= utf8block;
583
584 26 utf16used = gate_char_write_utf16(chr32, utf16, sizeof(utf16) / sizeof(utf16[0]));
585
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 26 times.
52 for (ndx = 0; ndx != utf16used; ++ndx)
586 {
587 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint16_t)utf16[ndx]) & 0x00ff);
588 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint16_t)utf16[ndx] >> 8) & 0x00ff);
589 }
590
591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (bufferpos >= sizeof(buffer) / 2)
592 {
593 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
594 /* if write attempt fails, while-loop while be canceled */
595 bufferpos = 0;
596 }
597 }
598
599
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (bufferpos != 0)
600 {
601 1 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
602 1 bufferpos = 0;
603 }
604
605 1 return ret;
606 }
607 1 gate_result_t gate_text_save_utf16be(gate_string_t const* src, gate_stream_t* dst, gate_bool_t addbom)
608 {
609 1 gate_result_t ret = GATE_RESULT_OK;
610 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
611 1 gate_size_t bufferpos = 0;
612 gate_size_t byteswritten;
613 1 char const* ptr = gate_string_ptr(src, 0);
614 1 gate_size_t length = gate_string_length(src);
615
616
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (addbom)
617 {
618 1 ret = gate_stream_write_block(dst, gate_text_bom_utf16be.str, gate_text_bom_utf16be.length, &byteswritten);
619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret)) return ret;
620 }
621
622
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
27 while ((length != 0) && GATE_SUCCEEDED(ret))
623 {
624 gate_char16_t utf16[8];
625 gate_size_t utf16used;
626 gate_char32_t chr32;
627 gate_size_t utf8block;
628 gate_size_t ndx;
629
630 26 utf8block = gate_char_read_utf8(ptr, length, &chr32);
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (utf8block == 0)
632 {
633 ret = GATE_RESULT_INVALIDINPUT;
634 break;
635 }
636 26 ptr += utf8block;
637 26 length -= utf8block;
638
639 26 utf16used = gate_char_write_utf16(chr32, utf16, sizeof(utf16) / sizeof(utf16[0]));
640
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 26 times.
52 for (ndx = 0; ndx != utf16used; ++ndx)
641 {
642 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint16_t)utf16[ndx] >> 8) & 0x00ff);
643 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint16_t)utf16[ndx]) & 0x00ff);
644 }
645
646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (bufferpos >= sizeof(buffer) / 2)
647 {
648 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
649 /* if write attempt fails, while-loop while be canceled */
650 bufferpos = 0;
651 }
652 }
653
654
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (bufferpos != 0)
655 {
656 1 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
657 1 bufferpos = 0;
658 }
659
660 1 return ret;
661 }
662 1 gate_result_t gate_text_save_utf32le(gate_string_t const* src, gate_stream_t* dst, gate_bool_t addbom)
663 {
664 1 gate_result_t ret = GATE_RESULT_OK;
665 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
666 1 gate_size_t bufferpos = 0;
667 gate_size_t byteswritten;
668 1 char const* ptr = gate_string_ptr(src, 0);
669 1 gate_size_t length = gate_string_length(src);
670
671
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (addbom)
672 {
673 1 ret = gate_stream_write_block(dst, gate_text_bom_utf32le.str, gate_text_bom_utf32le.length, &byteswritten);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret)) return ret;
675 }
676
677
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
27 while ((length != 0) && GATE_SUCCEEDED(ret))
678 {
679 gate_char32_t chr32;
680 26 gate_size_t utf8block = gate_char_read_utf8(ptr, length, &chr32);
681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (utf8block == 0)
682 {
683 ret = GATE_RESULT_INVALIDINPUT;
684 break;
685 }
686 26 ptr += utf8block;
687 26 length -= utf8block;
688
689 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32) & 0x00ff);
690 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 8) & 0x00ff);
691 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 16) & 0x00ff);
692 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 24) & 0x00ff);
693
694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (bufferpos >= sizeof(buffer) / 2)
695 {
696 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
697 /* if write attempt fails, while-loop while be canceled */
698 bufferpos = 0;
699 }
700 }
701
702
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (bufferpos != 0)
703 {
704 1 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
705 1 bufferpos = 0;
706 }
707
708 1 return ret;
709 }
710 1 gate_result_t gate_text_save_utf32be(gate_string_t const* src, gate_stream_t* dst, gate_bool_t addbom)
711 {
712 1 gate_result_t ret = GATE_RESULT_OK;
713 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
714 1 gate_size_t bufferpos = 0;
715 gate_size_t byteswritten;
716 1 char const* ptr = gate_string_ptr(src, 0);
717 1 gate_size_t length = gate_string_length(src);
718
719
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (addbom)
720 {
721 1 ret = gate_stream_write_block(dst, gate_text_bom_utf32be.str, gate_text_bom_utf32be.length, &byteswritten);
722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(ret)) return ret;
723 }
724
725
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
27 while ((length != 0) && GATE_SUCCEEDED(ret))
726 {
727 gate_char32_t chr32;
728 gate_size_t utf8block;
729
730 26 utf8block = gate_char_read_utf8(ptr, length, &chr32);
731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (utf8block == 0)
732 {
733 ret = GATE_RESULT_INVALIDINPUT;
734 break;
735 }
736 26 ptr += utf8block;
737 26 length -= utf8block;
738
739 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 24) & 0x00ff);
740 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 16) & 0x00ff);
741 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32 >> 8) & 0x00ff);
742 26 buffer[bufferpos++] = (char)(gate_uint8_t)(((gate_uint32_t)chr32) & 0x00ff);
743
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (bufferpos >= sizeof(buffer) / 2)
745 {
746 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
747 /* if write attempt fails, while-loop while be canceled */
748 bufferpos = 0;
749 }
750 }
751
752
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (bufferpos != 0)
753 {
754 1 ret = gate_stream_write_block(dst, buffer, bufferpos, &byteswritten);
755 1 bufferpos = 0;
756 }
757
758 1 return ret;
759 }
760
761 1 gate_result_t gate_text_c_escape(gate_string_t const* str, gate_strbuilder8_t* dst)
762 {
763 1 gate_result_t ret = GATE_RESULT_OK;
764 1 char const* ptr = gate_string_ptr(str, 0);
765 1 gate_size_t len = gate_string_length(str);
766 1 char buffer[8] = GATE_INIT_EMPTY;
767 1 gate_size_t buffer_used = 0;
768
769
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1 times.
41 while (len != 0)
770 {
771 40 char const chr = *ptr;
772
10/11
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 30 times.
40 switch (chr)
773 {
774 1 case '\\': buffer[0] = '\\'; buffer[1] = '\\'; buffer_used = 2; break;
775 2 case '\"': buffer[0] = '\\'; buffer[1] = '\"'; buffer_used = 2; break;
776 1 case '\a': buffer[0] = '\\'; buffer[1] = 'a'; buffer_used = 2; break;
777 1 case '\b': buffer[0] = '\\'; buffer[1] = 'b'; buffer_used = 2; break;
778 case 0x1b: buffer[0] = '\\'; buffer[1] = 'e'; buffer_used = 2; break;
779 1 case '\f': buffer[0] = '\\'; buffer[1] = 'f'; buffer_used = 2; break;
780 1 case '\n': buffer[0] = '\\'; buffer[1] = 'n'; buffer_used = 2; break;
781 1 case '\r': buffer[0] = '\\'; buffer[1] = 'r'; buffer_used = 2; break;
782 1 case '\t': buffer[0] = '\\'; buffer[1] = 't'; buffer_used = 2; break;
783 1 case '\v': buffer[0] = '\\'; buffer[1] = 'v'; buffer_used = 2; break;
784 30 default:
785 {
786
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3 times.
30 if ((chr >= 0) && (chr <= 127))
787 {
788 27 buffer[0] = chr;
789 27 buffer_used = 1;
790 }
791 else
792 {
793 3 buffer[0] = '\\';
794 3 buffer[1] = 'x';
795 3 gate_str_print_hex_byte(&buffer[2], 2, chr, true);
796 3 buffer_used = 4;
797 }
798 30 break;
799 }
800 }
801
802
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if (0 == gate_strbuilder_append_text(dst, buffer, buffer_used))
803 {
804 ret = GATE_RESULT_OUTOFMEMORY;
805 break;
806 }
807 40 ++ptr;
808 40 --len;
809 }
810 1 return ret;
811 }
812
813 2 gate_result_t gate_text_c_unescape(gate_string_t const* str, gate_strbuilder8_t* dst)
814 {
815 2 gate_result_t ret = GATE_RESULT_OK;
816 2 char const* ptr = gate_string_ptr(str, 0);
817 2 gate_size_t len = gate_string_length(str);
818 2 char buffer[8] = GATE_INIT_EMPTY;
819
820
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2 times.
51 while (len != 0)
821 {
822
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 33 times.
49 if (*ptr == '\\')
823 {
824 gate_uint8_t u8;
825 16 gate_size_t buffer_used = 8;
826 gate_size_t len_parsed;
827
828 16 len_parsed = 2;
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (len < 2)
830 {
831 ret = GATE_RESULT_INVALIDDATA;
832 break;
833 }
834 16 buffer_used = 1;
835
13/16
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
16 switch (ptr[1])
836 {
837 1 case '\\': buffer[0] = '\\'; break;
838 2 case '\"': buffer[0] = '\"'; break;
839 case '?': buffer[0] = '\?'; break;
840 1 case 'a': buffer[0] = '\a'; break;
841 1 case 'b': buffer[0] = '\b'; break;
842 case 'e': buffer[0] = 0x1b; break;
843 1 case 'f': buffer[0] = '\f'; break;
844 1 case 'n': buffer[0] = '\n'; break;
845 1 case 'r': buffer[0] = '\r'; break;
846 1 case 't': buffer[0] = '\t'; break;
847 1 case 'v': buffer[0] = '\v'; break;
848 3 case 'x':
849 {
850 3 buffer_used = 0;
851
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (len >= 4)
852 {
853
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (gate_str_parse_hex_byte(&ptr[2], &u8))
854 {
855 3 buffer[0] = (char)u8;
856 3 buffer_used = 1;
857 3 len_parsed = 4;
858 }
859 }
860 3 break;
861 }
862 1 case 'u':
863 {
864 1 buffer_used = 0;
865
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (len >= 6)
866 {
867 char h[2];
868
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (2 == gate_str_parse_hex_buffer(&ptr[2], 4, &h[0], 2))
869 {
870 2 gate_uint16_t u16 = (((gate_uint16_t)(gate_uint8_t)h[0]) << 8)
871 1 | ((gate_uint16_t)(gate_uint8_t)h[1]);
872 1 buffer_used = gate_char_write_utf8((gate_char32_t)u16, buffer, sizeof(buffer));
873 1 len_parsed = 6;
874 }
875 }
876 1 break;
877 }
878 1 case 'U':
879 {
880 1 buffer_used = 0;
881
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (len >= 10)
882 {
883 char h[4];
884
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (4 == gate_str_parse_hex_buffer(&ptr[2], 8, &h[0], 4))
885 {
886 2 gate_uint32_t u32 = (((gate_uint32_t)(gate_uint8_t)h[0]) << 24)
887 1 | (((gate_uint32_t)(gate_uint8_t)h[1]) << 16)
888 1 | (((gate_uint32_t)(gate_uint8_t)h[2]) << 24)
889 1 | ((gate_uint32_t)(gate_uint8_t)h[3]);
890 1 buffer_used = gate_char_write_utf8((gate_char32_t)u32, buffer, sizeof(buffer));
891 1 len_parsed = 10;
892 }
893 }
894 1 break;
895 }
896 1 case '0':
897 case '1':
898 case '2':
899 case '3':
900 {
901 1 buffer_used = 0;
902
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (len >= 4)
903 {
904
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_str_parse_oct_byte(&ptr[1], &u8))
905 {
906 1 buffer[0] = (char)u8;
907 1 buffer_used = 1;
908 1 len_parsed = 4;
909 }
910 }
911 1 break;
912 }
913 default:
914 {
915 buffer[0] = ptr[0];
916 buffer[1] = ptr[1];
917 buffer_used = 2;
918 break;
919 }
920 }
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (buffer_used == 0)
922 {
923 ret = GATE_RESULT_INVALIDDATA;
924 break;
925 }
926 16 gate_strbuilder_append_text(dst, buffer, buffer_used);
927 16 ptr += len_parsed;
928 16 len -= len_parsed;
929 }
930 else
931 {
932 33 gate_strbuilder_append_text(dst, ptr, 1);
933 33 ++ptr;
934 33 --len;
935 }
936 }
937 2 return ret;
938 }
939 1 gate_size_t gate_text_c_escape_str(gate_char8_t const* src, gate_size_t srclen, gate_char8_t* dst, gate_size_t dstlen)
940 {
941 1 gate_size_t ret = 0;
942
943
3/4
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
41 while ((srclen != 0) && (dstlen > 1))
944 {
945 40 char const chr = *src;
946 40 gate_size_t coded_len = 2;
947
10/11
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 30 times.
40 switch (chr)
948 {
949 1 case '\\': dst[0] = '\\'; dst[1] = '\\'; break;
950 2 case '\"': dst[0] = '\\'; dst[1] = '\"'; break;
951 1 case '\a': dst[0] = '\\'; dst[1] = 'a'; break;
952 1 case '\b': dst[0] = '\\'; dst[1] = 'b'; break;
953 case 0x1b: dst[0] = '\\'; dst[1] = 'e'; break;
954 1 case '\f': dst[0] = '\\'; dst[1] = 'f'; break;
955 1 case '\n': dst[0] = '\\'; dst[1] = 'n'; break;
956 1 case '\r': dst[0] = '\\'; dst[1] = 'r'; break;
957 1 case '\t': dst[0] = '\\'; dst[1] = 't'; break;
958 1 case '\v': dst[0] = '\\'; dst[1] = 'v'; break;
959 30 default:
960 {
961
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3 times.
30 if ((chr >= 0) && (chr <= 127))
962 {
963 27 dst[0] = chr;
964 27 coded_len = 1;
965 }
966 else
967 {
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (dstlen < 4)
969 {
970 dst[0] = chr;
971 coded_len = 1;
972 }
973 else
974 {
975 3 dst[0] = '\\';
976 3 dst[1] = 'x';
977 3 gate_str_print_hex_byte(&dst[2], 2, chr, true);
978 3 coded_len = 4;
979 }
980 }
981 30 break;
982 }
983 }
984 40 ++src;
985 40 --srclen;
986 40 dst += coded_len;
987 40 dstlen -= coded_len;
988 40 ret += coded_len;
989 }
990
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (dstlen > 0)
991 {
992 1 *dst = 0;
993 }
994 1 return ret;
995 }
996 158 gate_size_t gate_text_c_unescape_str(gate_char8_t const* src, gate_size_t srclen, gate_char8_t* dst, gate_size_t dstlen)
997 {
998 158 gate_size_t ret = 0;
999 158 char buffer[8] = GATE_INIT_EMPTY;
1000 158 gate_size_t buffer_used = 8;
1001
1002
3/4
✓ Branch 0 taken 1445 times.
✓ Branch 1 taken 158 times.
✓ Branch 2 taken 1445 times.
✗ Branch 3 not taken.
1603 while ((srclen != 0) && (dstlen != 0))
1003 {
1004
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1429 times.
1445 if (*src == '\\')
1005 {
1006 gate_uint8_t u8;
1007 gate_size_t len_parsed;
1008
1009 16 len_parsed = 2;
1010
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (srclen < 2)
1011 {
1012 break;
1013 }
1014 16 buffer_used = 1;
1015
13/16
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
16 switch (src[1])
1016 {
1017 1 case '\\': buffer[0] = '\\'; break;
1018 2 case '\"': buffer[0] = '\"'; break;
1019 case '?': buffer[0] = '\?'; break;
1020 1 case 'a': buffer[0] = '\a'; break;
1021 1 case 'b': buffer[0] = '\b'; break;
1022 case 'e': buffer[0] = 0x1b; break;
1023 1 case 'f': buffer[0] = '\f'; break;
1024 1 case 'n': buffer[0] = '\n'; break;
1025 1 case 'r': buffer[0] = '\r'; break;
1026 1 case 't': buffer[0] = '\t'; break;
1027 1 case 'v': buffer[0] = '\v'; break;
1028 3 case 'x':
1029 {
1030 3 buffer_used = 0;
1031
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (srclen >= 4)
1032 {
1033
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (gate_str_parse_hex_byte(&src[2], &u8))
1034 {
1035 3 buffer[0] = (char)u8;
1036 3 buffer_used = 1;
1037 3 len_parsed = 4;
1038 }
1039 }
1040 3 break;
1041 }
1042 1 case 'u':
1043 {
1044
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (srclen >= 6)
1045 {
1046 char h[2];
1047
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (2 == gate_str_parse_hex_buffer(&src[2], 4, &h[0], 2))
1048 {
1049 2 gate_uint16_t u16 = (((gate_uint16_t)(gate_uint8_t)h[0]) << 8)
1050 1 | ((gate_uint16_t)(gate_uint8_t)h[1]);
1051 1 buffer_used = gate_char_write_utf8((gate_char32_t)u16, buffer, sizeof(buffer));
1052 1 len_parsed = 6;
1053 }
1054 }
1055 1 break;
1056 }
1057 1 case 'U':
1058 {
1059 1 buffer_used = 0;
1060
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (srclen >= 10)
1061 {
1062 char h[4];
1063
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (4 == gate_str_parse_hex_buffer(&src[2], 8, &h[0], 4))
1064 {
1065 2 gate_uint32_t u32 = (((gate_uint32_t)(gate_uint8_t)h[0]) << 24)
1066 1 | (((gate_uint32_t)(gate_uint8_t)h[1]) << 16)
1067 1 | (((gate_uint32_t)(gate_uint8_t)h[2]) << 24)
1068 1 | ((gate_uint32_t)(gate_uint8_t)h[3]);
1069 1 buffer_used = gate_char_write_utf8((gate_char32_t)u32, buffer, sizeof(buffer));
1070 1 len_parsed = 10;
1071 }
1072 }
1073 1 break;
1074 }
1075 1 case '0':
1076 case '1':
1077 case '2':
1078 case '3':
1079 {
1080 1 buffer_used = 0;
1081
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (srclen >= 4)
1082 {
1083
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_str_parse_oct_byte(&src[1], &u8))
1084 {
1085 1 buffer[0] = (char)u8;
1086 1 buffer_used = 1;
1087 1 len_parsed = 4;
1088 }
1089 }
1090 1 break;
1091 }
1092 default:
1093 {
1094 buffer[0] = src[0];
1095 buffer[1] = src[1];
1096 buffer_used = 2;
1097 break;
1098 }
1099 }
1100
1101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (dstlen < buffer_used)
1102 {
1103 break;
1104 }
1105
1106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (buffer_used == 0)
1107 {
1108 *dst = *src;
1109 ++dst;
1110 ++src;
1111 ++ret;
1112 --srclen;
1113 --dstlen;
1114 }
1115 else
1116 {
1117 16 gate_mem_copy(dst, buffer, buffer_used);
1118
1119 16 dst += buffer_used;
1120 16 dstlen -= buffer_used;
1121 16 ret += buffer_used;
1122 16 src += len_parsed;
1123 16 srclen -= len_parsed;
1124 }
1125 }
1126 else
1127 {
1128 1429 *dst = *src;
1129 1429 ++dst;
1130 1429 ++src;
1131 1429 ++ret;
1132 1429 --srclen;
1133 1429 --dstlen;
1134 }
1135 }
1136 158 return ret;
1137 }
1138
1139 1 gate_result_t gate_text_print_vartoken(gate_strbuilder_t* target, gate_string_t const* varname)
1140 {
1141 1 gate_result_t ret = GATE_RESULT_OK;
1142 1 gate_size_t varnamelen = gate_string_length(varname);
1143 do
1144 {
1145
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_strbuilder_append_cstr(target, "${") < 2)
1146 {
1147 ret = GATE_RESULT_OUTOFMEMORY;
1148 break;
1149 }
1150
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_strbuilder_append_string(target, varname) < varnamelen)
1151 {
1152 ret = GATE_RESULT_OUTOFMEMORY;
1153 break;
1154 }
1155
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_strbuilder_append_cstr(target, "}") < 1)
1156 {
1157 ret = GATE_RESULT_OUTOFMEMORY;
1158 break;
1159 }
1160 } while (0);
1161 1 return ret;
1162 }
1163
1164 2 static gate_size_t gate_text_resolve_var(gate_string_t const* postdollartoken, gate_map_t const* strmap, gate_string_t* replace)
1165 {
1166 2 gate_size_t ret = 0;
1167 2 gate_string_t var_name = GATE_STRING_INIT_EMPTY;
1168
1169 do
1170 {
1171 gate_string_t const* ptr_str;
1172 gate_map_iterator_t iter;
1173
1174
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_string_starts_with_char(postdollartoken, '{'))
1175 {
1176 1 gate_size_t pos = gate_string_char_pos(postdollartoken, '}', 1);
1177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pos == GATE_STR_NPOS)
1178 {
1179 break;
1180 }
1181 1 gate_string_substr(&var_name, postdollartoken, 1, pos - 1);
1182
1183 1 ptr_str = (gate_string_t const*)gate_map_get_value(strmap, &var_name);
1184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ptr_str)
1185 {
1186 /* no match */
1187 break;
1188 }
1189 1 gate_string_duplicate(replace, ptr_str);
1190 1 ret = pos + 1;
1191 1 break;
1192 }
1193
1194 1 iter = gate_map_first(strmap);
1195
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 while (gate_map_iterator_valid(iter))
1196 {
1197 2 ptr_str = (gate_string_t const*)gate_map_iterator_key(iter);
1198
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_string_starts_with(postdollartoken, ptr_str))
1199 {
1200 1 gate_string_duplicate(replace, (gate_string_t const*)gate_map_iterator_value(iter));
1201 1 ret = gate_string_length(ptr_str);
1202 1 break;
1203 }
1204 1 iter = gate_map_iterator_next(iter);
1205 }
1206
1207 } while (0);
1208
1209 2 gate_string_release(&var_name);
1210 2 return ret;
1211 }
1212
1213 1 gate_result_t gate_text_print_vars(gate_strbuilder_t* target, gate_string_t const* src, gate_map_t const* strmap)
1214 {
1215 1 gate_result_t ret = GATE_RESULT_OK;
1216 1 gate_size_t start_at = 0;
1217 1 gate_size_t const src_len = gate_string_length(src);
1218 1 char const* const ptr = gate_string_ptr(src, 0);
1219 1 gate_string_t dollartoken = GATE_STRING_INIT_EMPTY;
1220 1 gate_string_t replacement = GATE_STRING_INIT_EMPTY;
1221
1222 for (;;)
1223 2 {
1224 gate_size_t len;
1225 3 gate_size_t match_pos = gate_string_char_pos(src, '$', start_at);
1226
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (match_pos == GATE_STR_NPOS)
1227 {
1228 /* no further occurance */
1229 1 len = src_len - start_at;
1230
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (len != gate_strbuilder_append_text(target, &ptr[start_at], len))
1231 {
1232 ret = GATE_RESULT_OUTOFMEMORY;
1233 }
1234 1 break;
1235 }
1236
1237 2 len = match_pos - start_at;
1238
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (len != gate_strbuilder_append_text(target, &ptr[start_at], len))
1239 {
1240 ret = GATE_RESULT_OUTOFMEMORY;
1241 break;
1242 }
1243 2 gate_string_substr(&dollartoken, src, match_pos + 1, src_len - match_pos - 1);
1244 2 len = gate_text_resolve_var(&dollartoken, strmap, &replacement);
1245 2 start_at = match_pos + 1 + len;
1246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (len == 0)
1247 {
1248 if (1 != gate_strbuilder_append_chars(target, 1, '$'))
1249 {
1250 ret = GATE_RESULT_OUTOFMEMORY;
1251 break;
1252 }
1253 }
1254 else
1255 {
1256 2 len = gate_strbuilder_append_string(target, &replacement);
1257
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (len != gate_string_length(&replacement))
1258 {
1259 ret = GATE_RESULT_OUTOFMEMORY;
1260 break;
1261 }
1262 }
1263 2 gate_string_release(&dollartoken);
1264 2 gate_string_release(&replacement);
1265 }
1266 1 gate_string_release(&dollartoken);
1267 1 gate_string_release(&replacement);
1268
1269 1 return ret;
1270 }
1271
1272
1273
1274 3 gate_result_t gate_text_format_create(gate_text_formater_t* formater, gate_string_t const* format)
1275 {
1276 3 gate_result_t ret = GATE_RESULT_FAILED;
1277 3 gate_size_t const len = gate_string_length(format);
1278 do
1279 {
1280 3 gate_mem_clear(formater, sizeof(gate_text_formater_t));
1281 3 gate_strbuilder_create(&formater->format, len * 4 / 3 + 2);
1282
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (len != gate_strbuilder_append_string(&formater->format, format))
1283 {
1284 ret = GATE_RESULT_OUTOFMEMORY;
1285 break;
1286 }
1287 3 formater->counter = 0;
1288
1289 3 ret = GATE_RESULT_OK;
1290 } while (0);
1291 3 return ret;
1292 }
1293 3 gate_result_t gate_text_format_create_str(gate_text_formater_t* formater, char const* format)
1294 {
1295 3 gate_string_t str_format = GATE_STRING_INIT_EMPTY;
1296
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (NULL == gate_string_create_static(&str_format, format))
1297 {
1298 return GATE_RESULT_OUTOFMEMORY;
1299 }
1300 else
1301 {
1302 3 gate_result_t const ret = gate_text_format_create(formater, &str_format);
1303 3 gate_string_release(&str_format);
1304 3 return ret;
1305 }
1306 }
1307 3 gate_result_t gate_text_format_destroy(gate_text_formater_t* formater)
1308 {
1309
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (formater)
1310 {
1311 3 gate_strbuilder_release(&formater->format);
1312 3 gate_mem_clear(formater, sizeof(gate_text_formater_t));
1313 }
1314 3 return GATE_RESULT_OK;
1315 }
1316
1317
1318 typedef gate_size_t(*gate_text_format_replacer_t)(
1319 gate_text_formater_t* formater, gate_size_t replace_at, gate_size_t replace_len,
1320 void const* replace_to, gate_string_t const* format_param);
1321
1322
1323 15 static gate_size_t gate_text_format_replace(gate_text_formater_t* formater, gate_text_format_replacer_t replacer, void const* replace_to)
1324 {
1325 15 gate_size_t ret = 0;
1326 static char const* end_chars = "}:{";
1327 static gate_size_t const end_char_count = 3;
1328 15 gate_size_t start_at = 0;
1329 15 gate_string_t replace_param = GATE_STRING_INIT_EMPTY;
1330 gate_size_t replaced_chars;
1331 15 gate_bool_t continue_replacing = true;
1332 15 gate_uint64_t const current_counter = formater->counter++;
1333
1334
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 4 times.
67 while (continue_replacing)
1335 {
1336 63 char const* const format_ptr = gate_strbuilder_ptr(&formater->format, 0);
1337 63 gate_size_t const format_len = gate_strbuilder_length(&formater->format);
1338 63 gate_size_t pos = gate_str_char_pos(format_ptr, format_len, '{', start_at);
1339 gate_size_t pos_end;
1340 gate_uint64_t parsed_counter;
1341 gate_size_t len;
1342
1343
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 52 times.
63 if (pos == GATE_STR_NPOS)
1344 {
1345 11 break;
1346 }
1347
1348 52 pos_end = gate_str_find_first_of(format_ptr, format_len, end_chars, end_char_count, pos + 1);
1349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if (pos == GATE_STR_NPOS)
1350 {
1351 break;
1352 }
1353
1354 52 start_at = pos_end; /* if parsing failed, just skip this token */
1355
1356
2/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 switch (format_ptr[pos_end])
1357 {
1358 51 case '}':
1359 {
1360 /* simple replace */
1361 51 len = pos_end - pos - 1;
1362
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 4 times.
51 if (len > 0)
1363 { /* parse placeholder counter */
1364
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
47 if (len != gate_str_parse_uint64(&format_ptr[pos + 1], len, &parsed_counter))
1365 {
1366 /* failed to parse counter */
1367 continue_replacing = false;
1368 break;
1369 }
1370
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 13 times.
47 if (parsed_counter != current_counter)
1371 {
1372 /* parsed counter not matching current counter */
1373 34 break;
1374 }
1375 }
1376 /* we can replace the current format block */
1377 17 gate_string_create_empty(&replace_param);
1378 17 replaced_chars = replacer(formater, pos, pos_end + 1 - pos, replace_to, &replace_param);
1379 17 ret += replaced_chars;
1380 17 start_at = pos + replaced_chars;
1381
1382 /* if placeholder has no counter, cancel further parsing */
1383 17 continue_replacing = len > 0;
1384 17 break;
1385 }
1386 1 case ':':
1387 {
1388 /* formated replace */
1389 1 gate_size_t const total_end_pos = gate_str_char_pos(format_ptr, format_len, '}', pos_end + 1);
1390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (total_end_pos == GATE_STR_NPOS)
1391 {
1392 /* format-end-braces missing */
1393 continue_replacing = false;
1394 break;
1395 }
1396 1 len = pos_end - pos - 1;
1397
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (len > 0)
1398 { /* parse placeholder counter*/
1399
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (len != gate_str_parse_uint64(&format_ptr[pos + 1], len, &parsed_counter))
1400 {
1401 /* failed to parse placeholder counter */
1402 continue_replacing = false;
1403 break;
1404 }
1405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (parsed_counter != current_counter)
1406 {
1407 /* placeholder counter does not match current counter */
1408 break;
1409 }
1410 }
1411 1 gate_string_create_static_len(&replace_param, &format_ptr[pos_end + 1], total_end_pos - pos_end - 1);
1412 1 replaced_chars = replacer(formater, pos, total_end_pos + 1 - pos, replace_to, &replace_param);
1413 1 ret += replaced_chars;
1414 1 start_at = pos + replaced_chars;
1415 1 gate_string_release(&replace_param);
1416
1417 /* if placeholder has no counter, cancel further parsing */
1418 1 continue_replacing = len > 0;
1419 1 break;
1420 }
1421 case '{':
1422 {
1423 /* next replacement */
1424 start_at = pos_end;
1425 break;
1426 }
1427 }
1428 52 }
1429 15 return ret;
1430 }
1431
1432
1433
1434 4 static gate_size_t gate_text_format_string_impl(gate_text_formater_t* formater,
1435 gate_size_t replace_at, gate_size_t replace_len,
1436 void const* replace_to, gate_string_t const* format_param)
1437 {
1438 4 gate_string_t const* ptr_value = (gate_string_t const*)replace_to;
1439 4 char const* ptr_text = gate_string_ptr(ptr_value, 0);
1440 4 gate_size_t len = gate_string_length(ptr_value);
1441
1442 do
1443 {
1444 gate_size_t colon_pos;
1445 4 gate_int64_t substr_begin_at = 0;
1446 4 gate_int64_t substr_length = -1;
1447
1448
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (gate_string_is_empty(format_param))
1449 {
1450 // no further substring formating required
1451 3 break;
1452 }
1453 1 colon_pos = gate_string_char_pos(format_param, ':', 0);
1454
1455
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (colon_pos == GATE_STR_NPOS)
1456 {
1457 1 gate_str_parse_int64(format_param->str, format_param->length, &substr_begin_at);
1458 }
1459 else
1460 {
1461 gate_str_parse_int64(&format_param->str[0], colon_pos, &substr_begin_at);
1462 gate_str_parse_int64(&format_param->str[colon_pos + 1], format_param->length - colon_pos - 1, &substr_length);
1463 }
1464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (substr_begin_at < 0)
1465 {
1466 substr_begin_at = (gate_int64_t)len + substr_begin_at;
1467 if (substr_begin_at < 0)
1468 {
1469 substr_begin_at = 0;
1470 }
1471 }
1472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (substr_begin_at >= (gate_int64_t)len)
1473 {
1474 /* replace with NOTHING */
1475 len = 0;
1476 break;
1477 }
1478 1 ptr_text = gate_string_ptr(ptr_value, (gate_size_t)substr_begin_at);
1479 1 len -= (gate_size_t)substr_begin_at;
1480
1481
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (substr_length < 0)
1482 {
1483 1 substr_length += (gate_int64_t)len + 1;
1484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (substr_length <= 0)
1485 {
1486 /* replace with NOTHING */
1487 len = 0;
1488 break;
1489 }
1490 }
1491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (substr_length > (gate_int64_t)len)
1492 {
1493 len = (gate_size_t)substr_length;
1494 }
1495 } while (0);
1496
1497 4 gate_strbuilder_replace(&formater->format, replace_at, replace_len, ptr_text, len);
1498 4 return len;
1499 }
1500 3 gate_result_t gate_text_format_text(gate_text_formater_t* formater, gate_string_t const* text)
1501 {
1502 3 gate_result_t ret = GATE_RESULT_OK;
1503 3 gate_size_t len = gate_text_format_replace(formater, &gate_text_format_string_impl, text);
1504 (void)len;
1505 3 return ret;
1506 }
1507 2 gate_result_t gate_text_format_str(gate_text_formater_t* formater, char const* str)
1508 {
1509 gate_result_t ret;
1510 2 gate_string_t tmp = GATE_STRING_INIT_EMPTY;
1511 2 gate_string_create_static(&tmp, str);
1512 2 ret = gate_text_format_text(formater, &tmp);
1513 2 gate_string_release(&tmp);
1514 2 return ret;
1515 }
1516
1517
1518
1519 11 static gate_size_t gate_text_format_int_impl(gate_text_formater_t* formater,
1520 gate_size_t replace_at, gate_size_t replace_len,
1521 void const* replace_to, gate_string_t const* format_param)
1522 {
1523 11 char buffer[64] = GATE_INIT_EMPTY;
1524 11 gate_int64_t const* ptr_value = (gate_int64_t const*)replace_to;
1525 11 gate_size_t len = gate_str_print_int64(buffer, sizeof(buffer), *ptr_value);
1526 /* TODO: format_param */
1527
1528 11 gate_strbuilder_replace(&formater->format, replace_at, replace_len, buffer, len);
1529 11 return len;
1530 }
1531 10 gate_result_t gate_text_format_int(gate_text_formater_t* formater, gate_int64_t num)
1532 {
1533 10 gate_result_t ret = GATE_RESULT_OK;
1534 10 gate_size_t len = gate_text_format_replace(formater, &gate_text_format_int_impl, &num);
1535 (void)len;
1536 10 return ret;
1537 }
1538
1539
1540
1541 3 static gate_size_t gate_text_format_real_impl(gate_text_formater_t* formater,
1542 gate_size_t replace_at, gate_size_t replace_len,
1543 void const* replace_to, gate_string_t const* format_param)
1544 {
1545 3 char buffer[128] = GATE_INIT_EMPTY;
1546 3 gate_real64_t const* ptr_value = (gate_real64_t const*)replace_to;
1547 3 unsigned int_len = 0;
1548 3 unsigned decimal_len = 0;
1549 3 unsigned group_len = 0;
1550 3 gate_size_t len = gate_str_print_real(buffer, sizeof(buffer), *ptr_value, int_len, decimal_len, group_len);
1551 /* TODO: format_param */
1552 3 gate_strbuilder_replace(&formater->format, replace_at, replace_len, buffer, len);
1553 3 return len;
1554 }
1555 2 gate_result_t gate_text_format_real(gate_text_formater_t* formater, gate_real64_t num)
1556 {
1557 2 gate_result_t ret = GATE_RESULT_OK;
1558 2 gate_size_t len = gate_text_format_replace(formater, &gate_text_format_real_impl, &num);
1559 (void)len;
1560 2 return ret;
1561 }
1562
1563 1 gate_result_t gate_text_format_extract(gate_text_formater_t const* formater, gate_string_t* output)
1564 {
1565 1 gate_result_t ret = GATE_RESULT_FAILED;
1566
1567 do
1568 {
1569
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_strbuilder_copy_to_string(&formater->format, output))
1570 {
1571 ret = GATE_RESULT_OUTOFMEMORY;
1572 break;
1573 }
1574 1 ret = GATE_RESULT_OK;
1575 } while (0);
1576 1 return ret;
1577 }
1578
1579
1580 3 gate_result_t gate_text_format_print(gate_text_formater_t* formater, gate_string_t* output)
1581 {
1582 3 gate_result_t ret = GATE_RESULT_FAILED;
1583
1584 do
1585 {
1586
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (NULL == gate_strbuilder_to_string(&formater->format, output))
1587 {
1588 ret = GATE_RESULT_OUTOFMEMORY;
1589 break;
1590 }
1591 3 ret = GATE_RESULT_OK;
1592 } while (0);
1593 3 return ret;
1594 }
1595