GCC Code Coverage Report


Directory: src/gate/
File: src/gate/strings_strbuffer.c
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 73 87 83.9%
Functions: 19 19 100.0%
Branches: 50 108 46.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/strings.h"
30
31
32 #define GATE_CSTRBUFFER_CREATE_IMPL(char_type, buffer, textptr, length, copy_needed) \
33 if(!buffer) return NULL; \
34 gate_mem_clear(buffer, sizeof(*buffer)); \
35 if(length > 0) \
36 { \
37 buffer->length = length; \
38 if(!copy_needed && (textptr[length] == 0)) \
39 { \
40 buffer->str = textptr; \
41 } \
42 else if(length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]))) \
43 { \
44 gate_mem_copy(buffer->local_buffer, textptr, length * sizeof(buffer->local_buffer[0])); \
45 buffer->local_buffer[length] = 0; \
46 buffer->str = &buffer->local_buffer[0]; \
47 } \
48 else \
49 { \
50 buffer->heap_buffer = ( char_type *)gate_mem_alloc((length + 1) * sizeof(char_type)); \
51 if(buffer->heap_buffer) \
52 { \
53 gate_mem_copy(buffer->heap_buffer, textptr, length * sizeof(char_type)); \
54 buffer->heap_buffer[length] = 0; \
55 buffer->str = buffer->heap_buffer; \
56 } \
57 else \
58 { \
59 buffer->length = 0; \
60 buffer = NULL; \
61 } \
62 } \
63 } \
64 return buffer
65
66 #define GATE_CSTRBUFFER_DESTROY_IMPL(buffer) \
67 do { \
68 if(!buffer) break; \
69 if(buffer->heap_buffer && (buffer->str == buffer->heap_buffer)) \
70 { \
71 gate_mem_dealloc(buffer->heap_buffer); \
72 } \
73 gate_mem_clear(buffer, sizeof(*buffer)); \
74 } while(0)
75
76 #define GATE_CSTRBUFFER_GET_IMPL(buffer) return buffer ? buffer->str : NULL
77
78 #define GATE_CSTRBUFFER_LENGTH_IMPL(buffer) return buffer ? buffer->length : 0
79
80
81 4 gate_cstrbuffer_t* gate_cstrbuffer_create_string(gate_cstrbuffer_t* buffer, gate_string_t const* strptr, gate_bool_t copy_needed)
82 {
83
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (strptr)
84 {
85 4 return gate_cstrbuffer_create(buffer, strptr->str, strptr->length, copy_needed);
86 }
87 ✗ else if (buffer)
88 {
89 ✗ gate_mem_clear(buffer, sizeof(*buffer));
90 }
91 ✗ return buffer;
92 }
93
94 3 gate_cstrbuffer_t* gate_cstrbuffer_create_wstr(gate_cstrbuffer_t* buffer, wchar_t const* textptr, gate_size_t length)
95 {
96 3 const gate_size_t required_buffer = length * 3 + 1;
97 3 char* target = NULL;
98 3 gate_size_t used = 0;
99
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!buffer) return NULL;
101 3 gate_mem_clear(buffer, sizeof(*buffer));
102
103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sizeof(buffer->local_buffer) <= required_buffer)
104 {
105 ✗ buffer->heap_buffer = (char*)gate_mem_alloc(required_buffer);
106 ✗ if (NULL == buffer->heap_buffer)
107 {
108 /* allocation failed */
109 ✗ return NULL;
110 }
111 ✗ target = buffer->heap_buffer;
112 }
113 else
114 {
115 3 target = &buffer->local_buffer[0];
116 }
117
118 #if defined(GATE_TYPE_WCHAR_IS_UTF16)
119 used = gate_str_utf16_2_utf8((gate_char16_t const*)textptr, length, target, required_buffer - 1);
120 #else
121 3 used = gate_str_utf32_2_utf8((gate_char32_t const*)textptr, length, target, required_buffer - 1);
122 #endif
123
124 3 buffer->str = target;
125 3 buffer->length = used;
126 3 return buffer;
127 }
128
129 11 gate_cstrbuffer_t* gate_cstrbuffer_create(gate_cstrbuffer_t* buffer, gate_char8_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
130 {
131
10/12
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 2 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
11 GATE_CSTRBUFFER_CREATE_IMPL(gate_char8_t, buffer, textptr, length, copy_needed);
132 }
133
134 25 void gate_cstrbuffer_destroy(gate_cstrbuffer_t* buffer)
135 {
136
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
25 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
137 25 }
138
139 16 gate_char8_t const* gate_cstrbuffer_get(gate_cstrbuffer_t const* buffer)
140 {
141
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 GATE_CSTRBUFFER_GET_IMPL(buffer);
142 }
143
144 #define GATE_CSTRBUFFER_GET_LOCAL_IMPL(buffer) \
145 if (buffer->str == &buffer->local_buffer[0]) { \
146 return &buffer->local_buffer[0]; \
147 } \
148 else if (buffer->str == buffer->heap_buffer) { \
149 return buffer->heap_buffer; \
150 } \
151 else { \
152 return NULL; \
153 }
154
155 1 gate_char8_t* gate_cstrbuffer_get_local(gate_cstrbuffer_t* buffer)
156 {
157
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 GATE_CSTRBUFFER_GET_LOCAL_IMPL(buffer);
158 }
159
160
161 7 gate_size_t gate_cstrbuffer_length(gate_cstrbuffer_t const* buffer)
162 {
163
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
164 }
165
166
167
168 3 gate_cstrbuffer16_t* gate_cstrbuffer16_create_string(gate_cstrbuffer16_t* buffer, gate_string_t const* ptr)
169 {
170 gate_size_t len;
171
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (buffer)
172 {
173 3 gate_mem_clear(buffer, sizeof(*buffer));
174
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if (ptr && ptr->length)
175 {
176
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (ptr->length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0])))
177 {
178 2 len = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->local_buffer,
179 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
180 2 buffer->local_buffer[len] = 0;
181 2 buffer->str = &buffer->local_buffer[0];
182 2 buffer->length = len;
183 }
184 else
185 {
186 1 buffer->heap_buffer = (gate_char16_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char16_t));
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!buffer->heap_buffer)
188 {
189 ✗ buffer = NULL;
190 }
191 else
192 {
193 1 buffer->length = gate_str_utf8_2_utf16(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
194 1 buffer->heap_buffer[buffer->length] = 0;
195 1 buffer->str = buffer->heap_buffer;
196 }
197 }
198 }
199 }
200
201 3 return buffer;
202 }
203
204 1 gate_cstrbuffer16_t* gate_cstrbuffer16_create(gate_cstrbuffer16_t* buffer, gate_char16_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
205 {
206
4/12
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
1 GATE_CSTRBUFFER_CREATE_IMPL(gate_char16_t, buffer, textptr, length, copy_needed);
207 }
208
209 4 void gate_cstrbuffer16_destroy(gate_cstrbuffer16_t* buffer)
210 {
211
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
4 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
212 4 }
213
214 2 gate_char16_t const* gate_cstrbuffer16_get(gate_cstrbuffer16_t const* buffer)
215 {
216
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_GET_IMPL(buffer);
217 }
218
219 1 gate_char16_t* gate_cstrbuffer16_get_local(gate_cstrbuffer16_t* buffer)
220 {
221
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 GATE_CSTRBUFFER_GET_LOCAL_IMPL(buffer);
222 }
223
224 2 gate_size_t gate_cstrbuffer16_length(gate_cstrbuffer16_t const* buffer)
225 {
226
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
227 }
228
229
230
231 1 gate_cstrbuffer32_t* gate_cstrbuffer32_create_string(gate_cstrbuffer32_t* buffer, gate_string_t const* ptr)
232 {
233 gate_size_t len;
234
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer)
235 {
236 1 gate_mem_clear(buffer, sizeof(*buffer));
237
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (ptr && ptr->length)
238 {
239
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr->length < (sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0])))
240 {
241 1 len = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->local_buffer,
242 sizeof(buffer->local_buffer) / sizeof(buffer->local_buffer[0]) - 1);
243 1 buffer->local_buffer[len] = 0;
244 1 buffer->str = &buffer->local_buffer[0];
245 1 buffer->length = len;
246 }
247 else
248 {
249 ✗ buffer->heap_buffer = (gate_char32_t*)gate_mem_alloc((ptr->length + 1) * sizeof(gate_char32_t));
250 ✗ if (!buffer->heap_buffer)
251 {
252 ✗ buffer = NULL;
253 }
254 else
255 {
256 ✗ buffer->length = gate_str_utf8_2_utf32(ptr->str, ptr->length, buffer->heap_buffer, ptr->length);
257 ✗ buffer->heap_buffer[buffer->length] = 0;
258 ✗ buffer->str = buffer->heap_buffer;
259 }
260 }
261 }
262 }
263
264 1 return buffer;
265 }
266
267 1 gate_cstrbuffer32_t* gate_cstrbuffer32_create(gate_cstrbuffer32_t* buffer, gate_char32_t const* textptr, gate_size_t length, gate_bool_t copy_needed)
268 {
269
4/12
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
1 GATE_CSTRBUFFER_CREATE_IMPL(gate_char32_t, buffer, textptr, length, copy_needed);
270 }
271
272 2 void gate_cstrbuffer32_destroy(gate_cstrbuffer32_t* buffer)
273 {
274
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 GATE_CSTRBUFFER_DESTROY_IMPL(buffer);
275 2 }
276
277 1 gate_char32_t const* gate_cstrbuffer32_get(gate_cstrbuffer32_t const* buffer)
278 {
279
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_GET_IMPL(buffer);
280 }
281
282 1 gate_char32_t* gate_cstrbuffer32_get_local(gate_cstrbuffer32_t* buffer)
283 {
284
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 GATE_CSTRBUFFER_GET_LOCAL_IMPL(buffer);
285 }
286
287 1 gate_size_t gate_cstrbuffer32_length(gate_cstrbuffer32_t const* buffer)
288 {
289
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 GATE_CSTRBUFFER_LENGTH_IMPL(buffer);
290 }
291