GCC Code Coverage Report


Directory: src/gate/
File: src/gate/streams.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 689 1046 65.9%
Functions: 86 118 72.9%
Branches: 203 401 50.6%

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/streams.h"
30 #include "gate/results.h"
31 #include "gate/strings.h"
32 #include "gate/atomics.h"
33 #include "gate/debugging.h"
34 #include "gate/times.h"
35 #include "gate/arrays.h"
36
37 #include <stdarg.h>
38
39 #if defined(GATE_SYS_WIN)
40 # define GATE_CORE_STREAMS_WINAPI 1
41 #elif defined(GATE_SYS_DOS)
42 # define GATE_CORE_STREAMS_POSIX 1
43 #elif defined(GATE_SYS_POSIX)
44 # define GATE_CORE_STREAMS_POSIX 1
45 #endif
46
47
48
49 /********************************
50 * memory stream implementation *
51 ********************************/
52
53 static void gate_memstream_release_impl(void* self);
54 static int gate_memstream_retain_impl(void* self);
55 static char const* gate_memstream_interface_name_impl(void* self);
56 static gate_result_t gate_memstream_read_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned);
57 static gate_result_t gate_memstream_peek_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned);
58 static gate_result_t gate_memstream_write_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written);
59 static gate_result_t gate_memstream_flush_impl(void* self);
60 static gate_result_t gate_memstream_reserve_impl(void* self, gate_size_t space);
61 static gate_size_t gate_memstream_size_impl(void* self);
62 static gate_result_t gate_memstream_fill_impl(void* self, char fillitem, gate_size_t fillsize);
63 static gate_size_t gate_memstream_discard_impl(void* self, gate_size_t bytestodiscard);
64 static gate_size_t gate_memstream_discard_back_impl(void* self, gate_size_t bytestodiscard);
65 static char const* gate_memstream_get_data_impl(void* self);
66 static gate_result_t gate_memstream_reset_impl(void* self);
67
68
69 static void gate_memstream_release_static_impl(void* self);
70 static int gate_memstream_retain_static_impl(void* self);
71 static gate_result_t gate_memstream_write_static_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written);
72 static gate_result_t gate_memstream_reserve_static_impl(void* self, gate_size_t space);
73 static gate_result_t gate_memstream_fill_static_impl(void* self, char fillitem, gate_size_t fillsize);
74 static gate_result_t gate_memstream_write_disabled_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written);
75 static gate_result_t gate_memstream_reserve_disabled_impl(void* self, gate_size_t space);
76 static gate_result_t gate_memstream_fill_disabled_impl(void* self, char fillitem, gate_size_t fillsize);
77
78 static void gate_memstream_release_static_unmanaged_impl(void* self);
79
80 static GATE_INTERFACE_VTBL(gate_memstream) gate_memstream_static_unmanaged_readonly_vtbl;
81
82 4 static void gate_init_memstream_static_unmanaged_readonly_vtbl()
83 {
84
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (!gate_memstream_static_unmanaged_readonly_vtbl.get_interface_name)
85 {
86 GATE_INTERFACE_VTBL(gate_memstream) const local_vtbl =
87 {
88 &gate_memstream_interface_name_impl,
89 &gate_memstream_release_static_unmanaged_impl,
90 &gate_memstream_retain_static_impl,
91
92 &gate_memstream_read_impl,
93 &gate_memstream_peek_impl,
94 &gate_memstream_write_disabled_impl,
95 &gate_memstream_flush_impl,
96
97 &gate_memstream_get_data_impl,
98 &gate_memstream_size_impl,
99 &gate_memstream_reserve_disabled_impl,
100 &gate_memstream_fill_disabled_impl,
101 &gate_memstream_discard_impl,
102 &gate_memstream_discard_back_impl,
103 &gate_memstream_reset_impl
104 };
105 2 gate_memstream_static_unmanaged_readonly_vtbl = local_vtbl;
106 }
107 4 }
108
109
110
111 48 static void gate_memstream_release_impl(void* self)
112 {
113 48 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
114
2/2
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 6 times.
48 if (gate_atomic_int_dec(&strm->ref_counter) == 0)
115 {
116 /* release memstream */
117
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 2 times.
42 if (strm->priv_membuffer != NULL)
118 {
119 40 gate_mem_dealloc(strm->priv_membuffer);
120 40 strm->priv_membuffer = NULL;
121 }
122 42 gate_mem_dealloc(strm);
123 }
124 48 }
125 6 static int gate_memstream_retain_impl(void* self)
126 {
127 6 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
128 6 return gate_atomic_int_inc(&strm->ref_counter);
129 }
130 6 static char const* gate_memstream_interface_name_impl(void* self)
131 {
132 (void)self;
133 6 return GATE_INTERFACE_NAME_MEMSTREAM;
134 }
135
136 46168 gate_result_t gate_memstream_read_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
137 {
138 46168 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
139
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 46122 times.
46168 if (bufferlength > strm->priv_memlength)
140 {
141 46 bufferlength = strm->priv_memlength;
142 }
143
2/2
✓ Branch 0 taken 46140 times.
✓ Branch 1 taken 28 times.
46168 if (bufferlength != 0)
144 {
145 46140 gate_mem_copy(buffer, &strm->priv_membuffer[strm->priv_memoffset], bufferlength);
146 46140 strm->priv_memlength -= bufferlength;
147
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 46109 times.
46140 if (strm->priv_memlength == 0)
148 {
149 31 strm->priv_memoffset = 0;
150 }
151 else
152 {
153 46109 strm->priv_memoffset += bufferlength;
154 }
155 }
156
1/2
✓ Branch 0 taken 46168 times.
✗ Branch 1 not taken.
46168 if (returned != NULL)
157 {
158 46168 *returned = bufferlength;
159 }
160 46168 return GATE_RESULT_OK;
161 }
162 601 gate_result_t gate_memstream_peek_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
163 {
164 601 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
165
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 600 times.
601 if (bufferlength > strm->priv_memlength)
166 {
167 1 bufferlength = strm->priv_memlength;
168 }
169
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 1 times.
601 if (bufferlength != 0)
170 {
171 600 gate_mem_copy(buffer, strm->priv_membuffer, bufferlength);
172 }
173
1/2
✓ Branch 0 taken 601 times.
✗ Branch 1 not taken.
601 if (returned != NULL)
174 {
175 601 *returned = bufferlength;
176 }
177 601 return GATE_RESULT_OK;
178 }
179 104983 gate_result_t gate_memstream_write_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
180 {
181 104983 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
182 104983 gate_result_t result = strm->vtbl->reserve(strm, bufferlength);
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104983 times.
104983 if (GATE_FAILED(result))
184 {
185 return result;
186 }
187
188 104983 gate_mem_copy(&strm->priv_membuffer[strm->priv_memoffset + strm->priv_memlength], buffer, bufferlength);
189 104983 strm->priv_memlength += bufferlength;
190
191
1/2
✓ Branch 0 taken 104983 times.
✗ Branch 1 not taken.
104983 if (written != NULL)
192 {
193 104983 *written = bufferlength;
194 }
195 104983 return GATE_RESULT_OK;
196 }
197 304 gate_result_t gate_memstream_flush_impl(void* self)
198 {
199 (void)self;
200 304 return GATE_RESULT_OK;
201 }
202 105003 static gate_result_t gate_memstream_reserve_impl(void* self, gate_size_t space)
203 {
204 105003 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
205 105003 gate_size_t unusedspace = strm->priv_memcapacity - strm->priv_memlength;
206 105003 gate_size_t freespace = unusedspace - strm->priv_memoffset;
207
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 104851 times.
105003 if (space > freespace)
208 {
209
1/2
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
152 if (space > unusedspace)
210 {
211 /* reallocation is required */
212 152 gate_size_t newcapacity = (strm->priv_memcapacity + space) + (strm->priv_memcapacity / 2);
213 152 char* newbuffer = (char*)gate_mem_alloc(newcapacity);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
152 if (newbuffer == NULL)
215 {
216 return GATE_RESULT_OUTOFMEMORY;
217 }
218
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 43 times.
152 if (strm->priv_memlength != 0)
219 {
220 109 gate_mem_copy(&newbuffer[0], &strm->priv_membuffer[strm->priv_memoffset], strm->priv_memlength);
221 }
222
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 40 times.
152 if (strm->priv_membuffer != NULL)
223 {
224 112 gate_mem_dealloc(strm->priv_membuffer);
225 }
226 152 strm->priv_membuffer = newbuffer;
227 152 strm->priv_memoffset = 0;
228 152 strm->priv_memcapacity = newcapacity;
229 }
230 else
231 {
232 /* moving bytes to origin of buffer */
233 gate_mem_copy(&strm->priv_membuffer[0], &strm->priv_membuffer[strm->priv_memoffset], strm->priv_memlength);
234 strm->priv_memoffset = 0;
235 }
236 }
237 105003 return GATE_RESULT_OK;
238 }
239 28 static gate_size_t gate_memstream_size_impl(void* self)
240 {
241 28 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
242 28 return strm->priv_memlength;
243 }
244 1 static gate_result_t gate_memstream_fill_impl(void* self, char fillitem, gate_size_t fillsize)
245 {
246 1 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
247 gate_size_t ndx;
248 char* ptr;
249 1 gate_result_t result = strm->vtbl->reserve(strm, fillsize);
250
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(result))
252 {
253 return result;
254 }
255
256 1 ptr = &strm->priv_membuffer[strm->priv_memoffset + strm->priv_memlength];
257
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (ndx = 0; ndx < fillsize; ++ndx, ++ptr)
258 {
259 5 *ptr = fillitem;
260 }
261 1 strm->priv_memlength += fillsize;
262 1 return GATE_RESULT_OK;
263 }
264 4 static gate_size_t gate_memstream_discard_impl(void* self, gate_size_t bytestodiscard)
265 {
266 4 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
267 gate_size_t ret;
268
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (bytestodiscard >= strm->priv_memlength)
269 {
270 1 ret = strm->priv_memlength;
271 1 strm->priv_memoffset = 0;
272 1 strm->priv_memlength = 0;
273 }
274 else
275 {
276 3 ret = bytestodiscard;
277 3 strm->priv_memoffset += bytestodiscard;
278 3 strm->priv_memlength -= bytestodiscard;
279 }
280 4 return ret;
281 }
282 2 static gate_size_t gate_memstream_discard_back_impl(void* self, gate_size_t bytestodiscard)
283 {
284 2 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
285 gate_size_t ret;
286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (bytestodiscard >= strm->priv_memlength)
287 {
288 ret = strm->priv_memlength;
289 strm->priv_memoffset = 0;
290 strm->priv_memlength = 0;
291 }
292 else
293 {
294 2 ret = bytestodiscard;
295 2 strm->priv_memlength -= bytestodiscard;
296 }
297 2 return ret;
298 }
299 23 static char const* gate_memstream_get_data_impl(void* self)
300 {
301 23 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
302 23 return &strm->priv_membuffer[strm->priv_memoffset];
303 }
304
305 static gate_result_t gate_memstream_reset_impl(void* self)
306 {
307 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
308 strm->priv_memoffset = 0;
309 strm->priv_memlength = 0;
310 return GATE_RESULT_OK;
311 }
312
313 static GATE_INTERFACE_VTBL(gate_memstream) gate_memstream_vtbl;
314
315 42 void gate_init_memstream_vtbl()
316 {
317
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 35 times.
42 if (!gate_memstream_vtbl.get_interface_name)
318 {
319 GATE_INTERFACE_VTBL(gate_memstream) const local_vtbl =
320 {
321 &gate_memstream_interface_name_impl,
322 &gate_memstream_release_impl,
323 &gate_memstream_retain_impl,
324
325 &gate_memstream_read_impl,
326 &gate_memstream_peek_impl,
327 &gate_memstream_write_impl,
328 &gate_memstream_flush_impl,
329
330 &gate_memstream_get_data_impl,
331 &gate_memstream_size_impl,
332 &gate_memstream_reserve_impl,
333 &gate_memstream_fill_impl,
334 &gate_memstream_discard_impl,
335 &gate_memstream_discard_back_impl,
336 &gate_memstream_reset_impl
337 };
338 7 gate_memstream_vtbl = local_vtbl;
339 }
340 42 }
341
342 42 gate_memstream_t* gate_memstream_create(gate_size_t capacity)
343 {
344 gate_result_t result;
345 42 gate_memstream_impl_t* ret = (gate_memstream_impl_t*)gate_mem_alloc(sizeof(gate_memstream_impl_t));
346
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if (ret != NULL)
347 {
348 42 gate_init_memstream_vtbl();
349 42 ret->vtbl = &gate_memstream_vtbl;
350 42 gate_atomic_int_set(&ret->ref_counter, 1);
351 42 ret->priv_membuffer = NULL;
352 42 ret->priv_memcapacity = 0;
353 42 ret->priv_memoffset = 0;
354 42 ret->priv_memlength = 0;
355
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 24 times.
42 if (capacity > 0)
356 {
357 18 result = ret->vtbl->reserve(ret, capacity);
358 (void)result;
359 }
360
361 }
362 42 return (gate_memstream_t*)ret;
363 }
364
365
366 4 static void gate_memstream_release_static_impl(void* self)
367 {
368 4 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
369
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (0 == gate_atomic_int_dec(&strm->ref_counter))
370 {
371 2 gate_mem_dealloc(self);
372 }
373 4 }
374 3 static int gate_memstream_retain_static_impl(void* self)
375 {
376 3 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
377 3 return (int)gate_atomic_int_inc(&strm->ref_counter);
378 }
379 236 static gate_result_t gate_memstream_write_static_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
380 {
381 236 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
382 236 gate_result_t ret = GATE_RESULT_OK;
383 gate_size_t avail;
384
1/2
✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
236 if (bufferlength > 0)
385 {
386 236 avail = strm->priv_memcapacity - strm->priv_memlength;
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if (bufferlength > avail)
388 {
389 if (bufferlength < strm->priv_memcapacity)
390 {
391 avail = strm->priv_memcapacity - bufferlength;
392 if (avail > strm->priv_memlength) avail = strm->priv_memlength;
393 gate_mem_copy(
394 &strm->priv_membuffer[0],
395 &strm->priv_membuffer[strm->priv_memoffset + strm->priv_memlength - avail],
396 avail);
397 strm->priv_memoffset = 0;
398 strm->priv_memlength = avail;
399 gate_mem_copy(&strm->priv_membuffer[strm->priv_memlength], buffer, bufferlength);
400 strm->priv_memlength += bufferlength;
401 }
402 else
403 {
404 gate_mem_copy(
405 &strm->priv_membuffer[0],
406 &buffer[bufferlength - strm->priv_memcapacity],
407 strm->priv_memcapacity);
408 strm->priv_memoffset = 0;
409 strm->priv_memlength = strm->priv_memcapacity;
410 }
411 }
412 else
413 {
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if (strm->priv_memoffset != 0)
415 {
416 gate_mem_copy(&strm->priv_membuffer[0], &strm->priv_membuffer[strm->priv_memoffset], strm->priv_memlength);
417 strm->priv_memoffset = 0;
418 }
419 236 gate_mem_copy(&strm->priv_membuffer[strm->priv_memlength], buffer, bufferlength);
420 236 strm->priv_memlength += bufferlength;
421 }
422 }
423
1/2
✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
236 if (written != NULL) *written = bufferlength;
424 236 return ret;
425 }
426 static gate_result_t gate_memstream_write_disabled_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
427 {
428 (void)self;
429 (void)buffer;
430 (void)bufferlength;
431 (void)written;
432 return GATE_RESULT_NOTSUPPORTED;
433 }
434 static gate_result_t gate_memstream_reserve_disabled_impl(void* self, gate_size_t space)
435 {
436 (void)self;
437 (void)space;
438 return GATE_RESULT_NOTSUPPORTED;
439 }
440 static gate_result_t gate_memstream_fill_disabled_impl(void* self, char fillitem, gate_size_t fillsize)
441 {
442 (void)self;
443 (void)fillitem;
444 (void)fillsize;
445 return GATE_RESULT_NOTSUPPORTED;
446 }
447
448 static gate_result_t gate_memstream_reserve_static_impl(void* self, gate_size_t space)
449 {
450 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
451 if (strm->priv_memoffset != 0)
452 {
453 gate_mem_copy(&strm->priv_membuffer[0], &strm->priv_membuffer[strm->priv_memoffset], strm->priv_memlength);
454 strm->priv_memoffset = 0;
455 }
456 return (space > strm->priv_memcapacity) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
457 }
458 static gate_result_t gate_memstream_fill_static_impl(void* self, char fillitem, gate_size_t fillsize)
459 {
460 gate_result_t ret = GATE_RESULT_OK;
461 if (fillsize != 0)
462 {
463 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
464 gate_size_t avail;
465 gate_size_t index;
466 char* ptr;
467 if (strm->priv_memoffset != 0)
468 {
469 gate_mem_copy(&strm->priv_membuffer[0], &strm->priv_membuffer[strm->priv_memoffset], strm->priv_memlength);
470 strm->priv_memoffset = 0;
471 }
472 avail = strm->priv_memcapacity - strm->priv_memlength;
473 if (fillsize > avail)
474 {
475 if (fillsize >= strm->priv_memcapacity)
476 {
477 ptr = &strm->priv_membuffer[0];
478 fillsize = strm->priv_memcapacity;
479 strm->priv_memoffset = 0;
480 strm->priv_memlength = 0;
481 }
482 else
483 {
484 gate_size_t preserve = strm->priv_memcapacity - fillsize;
485 gate_mem_copy(&strm->priv_membuffer[0], &strm->priv_membuffer[strm->priv_memoffset + strm->priv_memlength - preserve], preserve);
486 strm->priv_memoffset = 0;
487 strm->priv_memlength = preserve;
488 ptr = &strm->priv_membuffer[preserve];
489 }
490 }
491 else
492 {
493 ptr = &strm->priv_membuffer[strm->priv_memoffset + strm->priv_memlength];
494 }
495 for (index = 0; index != fillsize; ++index)
496 {
497 *ptr = fillitem;
498 ++ptr;
499 }
500 strm->priv_memlength += fillsize;
501 }
502 return ret;
503 }
504
505
506 4 static void gate_memstream_release_static_unmanaged_impl(void* self)
507 {
508 4 gate_memstream_impl_t* strm = (gate_memstream_impl_t*)self;
509 4 if (0 == gate_atomic_int_dec(&strm->ref_counter))
510 {
511 /* do nothing */
512 }
513 4 }
514
515 static GATE_INTERFACE_VTBL(gate_memstream) gate_memstream_static_unmanaged_vtbl;
516
517 1 void gate_init_memstream_static_unmanaged_vtbl()
518 {
519
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!gate_memstream_static_unmanaged_vtbl.get_interface_name)
520 {
521 GATE_INTERFACE_VTBL(gate_memstream) const local_vtbl =
522 {
523 &gate_memstream_interface_name_impl,
524 &gate_memstream_release_static_unmanaged_impl,
525 &gate_memstream_retain_static_impl,
526
527 &gate_memstream_read_impl,
528 &gate_memstream_peek_impl,
529 &gate_memstream_write_static_impl,
530 &gate_memstream_flush_impl,
531
532 &gate_memstream_get_data_impl,
533 &gate_memstream_size_impl,
534 &gate_memstream_reserve_static_impl,
535 &gate_memstream_fill_static_impl,
536 &gate_memstream_discard_impl,
537 &gate_memstream_discard_back_impl,
538 &gate_memstream_reset_impl
539 };
540 1 gate_memstream_static_unmanaged_vtbl = local_vtbl;
541 }
542 1 }
543
544 1 gate_memstream_t* gate_memstream_create_static_unmanaged(gate_memstream_impl_t* impl, void* buffer, gate_size_t capacity, gate_size_t used)
545 {
546 1 gate_init_memstream_static_unmanaged_vtbl();
547 1 impl->vtbl = &gate_memstream_static_unmanaged_vtbl;
548 1 gate_atomic_int_init(&impl->ref_counter, 1);
549 1 impl->priv_memoffset = 0;
550 1 impl->priv_membuffer = (char*)buffer;
551 1 impl->priv_memcapacity = capacity;
552 1 impl->priv_memlength = used;
553 1 return (gate_memstream_t*)impl;
554 }
555
556 static GATE_INTERFACE_VTBL(gate_memstream) gate_memstream_static_vtbl;
557 2 void gate_init_memstream_static_vtbl()
558 {
559
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (!gate_memstream_static_vtbl.get_interface_name)
560 {
561 GATE_INTERFACE_VTBL(gate_memstream) const local_vtbl =
562 {
563 &gate_memstream_interface_name_impl,
564 &gate_memstream_release_static_impl,
565 &gate_memstream_retain_static_impl,
566
567 &gate_memstream_read_impl,
568 &gate_memstream_peek_impl,
569 &gate_memstream_write_static_impl,
570 &gate_memstream_flush_impl,
571
572 &gate_memstream_get_data_impl,
573 &gate_memstream_size_impl,
574 &gate_memstream_reserve_static_impl,
575 &gate_memstream_fill_static_impl,
576 &gate_memstream_discard_impl,
577 &gate_memstream_discard_back_impl,
578 &gate_memstream_reset_impl
579 };
580 1 gate_memstream_static_vtbl = local_vtbl;
581 }
582 2 }
583
584 2 gate_memstream_t* gate_memstream_create_static(void* buffer, gate_size_t capacity, gate_size_t used)
585 {
586 2 gate_memstream_impl_t* impl = (gate_memstream_impl_t*)gate_mem_alloc(sizeof(gate_memstream_impl_t));
587
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (impl != NULL)
588 {
589 2 gate_init_memstream_static_vtbl();
590 2 impl->vtbl = &gate_memstream_static_vtbl;
591 2 gate_atomic_int_init(&impl->ref_counter, 1);
592 2 impl->priv_memoffset = 0;
593 2 impl->priv_membuffer = (char*)buffer;
594 2 impl->priv_memcapacity = capacity;
595 2 impl->priv_memlength = used;
596 }
597 2 return (gate_memstream_t*)impl;
598 }
599
600 4 gate_memstream_t* gate_memstream_create_static_unmanaged_readonly(gate_memstream_impl_t* impl, void const* buffer, gate_size_t capacity, gate_size_t used)
601 {
602 4 gate_init_memstream_static_unmanaged_readonly_vtbl();
603 4 impl->vtbl = &gate_memstream_static_unmanaged_readonly_vtbl;
604 4 gate_atomic_int_init(&impl->ref_counter, 1);
605 4 impl->priv_memoffset = 0;
606 4 impl->priv_membuffer = (char*)buffer;
607 4 impl->priv_memcapacity = capacity;
608 4 impl->priv_memlength = used;
609 4 return (gate_memstream_t*)impl;
610 }
611
612
613
614 /*****************************************
615 * control-memstream-view implementation *
616 *****************************************/
617
618 typedef struct memview_class
619 {
620 GATE_INTERFACE_VTBL(gate_controlstream)* vtbl;
621
622 gate_atomic_int_t ref_counter;
623 char const* ptr_buffer;
624 gate_size_t buffer_len;
625 gate_size_t buffer_offset;
626 gate_bool_t closed; /* true, when stream is closed */
627 gate_object_t* ptr_container; /* container holding mem-allocation, released on close*/
628 } memview_t;
629
630 1 static void memview_destroy(memview_t* self)
631 {
632
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (self->ptr_container)
633 {
634 gate_object_release(self->ptr_container);
635 }
636 1 gate_mem_dealloc(self);
637 1 }
638
639 static char const* memview_get_interface_name(void* obj)
640 {
641 GATE_UNUSED_ARG(obj);
642 return GATE_INTERFACE_NAME_CONTROLSTREAM;
643 }
644 1 static void memview_release(void* obj)
645 {
646 1 memview_t* const self = (memview_t*)obj;
647
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (0 == gate_atomic_int_dec(&self->ref_counter))
648 {
649 1 memview_destroy(self);
650 }
651 1 }
652 static int memview_retain(void* obj)
653 {
654 memview_t* const self = (memview_t*)obj;
655 return (int)gate_atomic_int_inc(&self->ref_counter);
656 }
657
658 4 static gate_result_t memview_peek(void* obj, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
659 {
660 4 memview_t* const self = (memview_t*)obj;
661 4 gate_result_t result = GATE_RESULT_FAILED;
662 4 gate_size_t copied = 0;
663 gate_size_t available;
664
665 do
666 {
667
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (!buffer || !obj)
668 {
669 result = GATE_RESULT_NULLPOINTER;
670 break;
671 }
672
673 4 available = self->buffer_len - self->buffer_offset;
674
675
3/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 if (self->closed || (available == 0))
676 {
677 /* react as end of stream */
678 2 result = GATE_RESULT_OK;
679 2 break;
680 }
681
682 2 copied = (bufferlength > available) ? available : bufferlength;
683 2 gate_mem_copy(buffer, &self->ptr_buffer[self->buffer_offset], copied);
684 2 result = GATE_RESULT_OK;
685 } while (0);
686
687
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (returned)
688 {
689 4 *returned = copied;
690 }
691
692 4 return result;
693 }
694
695 4 static gate_result_t memview_read(void* obj, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
696 {
697 4 memview_t* const self = (memview_t*)obj;
698 4 gate_result_t result = GATE_RESULT_FAILED;
699 4 gate_size_t copied = 0;
700
701 4 result = memview_peek(obj, buffer, bufferlength, &copied);
702
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (GATE_SUCCEEDED(result))
703 {
704 4 self->buffer_offset += copied;
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (self->buffer_offset > self->buffer_len)
706 {
707 self->buffer_offset = self->buffer_len;
708 }
709 }
710
711
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (returned)
712 {
713 4 *returned = copied;
714 }
715
716 4 return result;
717 }
718
719 static gate_result_t memview_write(void* obj, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
720 {
721 GATE_UNUSED_ARG(obj);
722 GATE_UNUSED_ARG(buffer);
723 GATE_UNUSED_ARG(bufferlength);
724 GATE_UNUSED_ARG(written);
725 return GATE_RESULT_NOTSUPPORTED;
726 }
727 static gate_result_t memview_flush(void* obj)
728 {
729 GATE_UNUSED_ARG(obj);
730 return GATE_RESULT_NOTSUPPORTED;
731 }
732
733 1 static gate_result_t memview_get_resource(void* obj, gate_enumint_t resource_type, gate_uintptr_t* resource)
734 {
735 1 memview_t* const self = (memview_t*)obj;
736
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 switch (resource_type)
737 {
738 1 case GATE_STREAM_RESOURCE_INPUT:
739 case GATE_STREAM_RESOURCE_DEFAULT:
740
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (resource)
741 {
742 1 *resource = (gate_uintptr_t)self->ptr_buffer;
743 }
744 1 return GATE_RESULT_OK;
745 default:
746 {
747 return GATE_RESULT_NOTAVAILABLE;
748 }
749 }
750 }
751
752 static gate_result_t memview_can_read(void* obj, gate_bool_t* return_value)
753 {
754 memview_t* const self = (memview_t*)obj;
755 if (return_value)
756 {
757 *return_value = !self->closed;
758 }
759 return GATE_RESULT_OK;
760 }
761 static gate_result_t memview_can_write(void* obj, gate_bool_t* return_value)
762 {
763 GATE_UNUSED_ARG(obj);
764 if (return_value)
765 {
766 *return_value = false;
767 }
768 return GATE_RESULT_OK;
769 }
770 static gate_result_t memview_get_size(void* obj, gate_int64_t* return_value)
771 {
772 memview_t* const self = (memview_t*)obj;
773 if (return_value)
774 {
775 *return_value = self->buffer_len;
776 }
777 return GATE_RESULT_OK;
778 }
779 1 static gate_result_t memview_get_available(void* obj, gate_int64_t* return_value)
780 {
781 1 memview_t* const self = (memview_t*)obj;
782
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (return_value)
783 {
784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 *return_value = self->closed ? 0 : (gate_int64_t)(self->buffer_len - self->buffer_offset);
785 }
786 1 return GATE_RESULT_OK;
787 }
788 1 static gate_result_t memview_seek(void* obj, gate_int64_t position, gate_enumint_t origin, gate_int64_t* final_position)
789 {
790 1 memview_t* const self = (memview_t*)obj;
791 1 gate_result_t result = GATE_RESULT_FAILED;
792 gate_size_t shift;
793
794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (self->closed)
795 {
796 return GATE_RESULT_NOTAVAILABLE;
797 }
798
799
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 switch (origin)
800 {
801 1 case GATE_STREAM_SEEK_BEGIN:
802 {
803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (position < 0)
804 {
805 result = GATE_RESULT_INVALIDARG;
806 break;
807 }
808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (position > (gate_int64_t)self->buffer_len)
809 {
810 result = GATE_RESULT_NOTSUPPORTED;
811 break;
812 }
813 1 self->buffer_offset = (gate_size_t)(gate_uint64_t)position;
814 1 result = GATE_RESULT_OK;
815 1 break;
816 }
817 case GATE_STREAM_SEEK_CURRENT:
818 {
819 if (position < 0)
820 {
821 shift = (gate_size_t)(gate_uint64_t)(-position);
822 if (shift > self->buffer_offset)
823 {
824 result = GATE_RESULT_NOTSUPPORTED;
825 break;
826 }
827 self->buffer_offset -= shift;
828 }
829 else
830 {
831 shift = (gate_size_t)(gate_uint64_t)position;
832 if (self->buffer_offset + shift > self->buffer_len)
833 {
834 result = GATE_RESULT_NOTSUPPORTED;
835 break;
836 }
837 self->buffer_offset += shift;
838 }
839 result = GATE_RESULT_OK;
840 break;
841 }
842 case GATE_STREAM_SEEK_END:
843 {
844 if (position > 0)
845 {
846 result = GATE_RESULT_NOTSUPPORTED;
847 break;
848 }
849 shift = (gate_size_t)(-position);
850 if (shift > self->buffer_len)
851 {
852 result = GATE_RESULT_INVALIDARG;
853 break;
854 }
855 self->buffer_offset = self->buffer_len - shift;
856 result = GATE_RESULT_OK;
857 break;
858 }
859 default:
860 {
861 result = GATE_RESULT_INVALIDARG;
862 break;
863 }
864 }
865
866
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (final_position)
867 {
868 1 *final_position = (gate_int64_t)(gate_uint64_t)self->buffer_offset;
869 }
870 1 return result;
871 }
872 1 static gate_result_t memview_reset(void* obj)
873 {
874 1 memview_t* const self = (memview_t*)obj;
875 1 self->buffer_offset = 0;
876 1 return GATE_RESULT_OK;
877 }
878 static gate_result_t memview_close(void* obj, gate_enumint_t close_type)
879 {
880 memview_t* const self = (memview_t*)obj;
881 switch (close_type)
882 {
883 case GATE_STREAM_CLOSE_DEFAULT:
884 case GATE_STREAM_CLOSE_INPUT:
885 self->closed = true;
886 return GATE_RESULT_OK;
887 default:
888 return GATE_RESULT_NOTSUPPORTED;
889 }
890 }
891
892 static GATE_INTERFACE_VTBL(gate_controlstream) memview_vtbl;
893
894 1 static void init_memview_vtbl()
895 {
896
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (memview_vtbl.get_interface_name == NULL)
897 {
898 1 GATE_INTERFACE_VTBL(gate_controlstream) local_vtbl =
899 {
900 &memview_get_interface_name,
901 &memview_release,
902 &memview_retain,
903
904 &memview_read,
905 &memview_peek,
906 &memview_write,
907 &memview_flush,
908
909 &memview_get_resource,
910
911 &memview_can_read,
912 &memview_can_write,
913 &memview_get_size,
914 &memview_get_available,
915 &memview_seek,
916 &memview_reset,
917 &memview_close
918 };
919 1 memview_vtbl = local_vtbl;
920 }
921 1 }
922
923 1 gate_controlstream_t* gate_memstream_create_view(void const* buffer, gate_size_t length, gate_size_t offset, gate_object_t* ptr_container)
924 {
925 1 gate_controlstream_t* ret = NULL;
926 1 memview_t* newstrm = NULL;
927
928 do
929 {
930 1 newstrm = (memview_t*)gate_mem_alloc(sizeof(memview_t));
931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!newstrm)
932 {
933 break;
934 }
935 1 gate_mem_clear(newstrm, sizeof(memview_t));
936 1 init_memview_vtbl();
937 1 newstrm->vtbl = &memview_vtbl;
938 1 gate_atomic_int_init(&newstrm->ref_counter, 1);
939 1 newstrm->closed = false;
940 1 newstrm->ptr_buffer = (char const*)buffer;
941 1 newstrm->buffer_len = length;
942 1 newstrm->buffer_offset = (offset > length) ? length : offset;
943 1 newstrm->ptr_container = ptr_container;
944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (newstrm->ptr_container)
945 {
946 gate_object_retain(newstrm->ptr_container);
947 }
948 /* success case */
949 1 ret = (gate_controlstream_t*)newstrm;
950 1 newstrm = NULL;
951 } while (0);
952
953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (newstrm)
954 {
955 memview_destroy(newstrm);
956 }
957 1 return ret;
958 }
959
960
961
962 /*****************************************
963 * control-memstream-file implementation *
964 *****************************************/
965
966 typedef struct memfile_class
967 {
968 GATE_INTERFACE_VTBL(gate_controlstream)* vtbl;
969
970 gate_atomic_int_t ref_counter;
971 gate_arraylist_t storage;
972 gate_size_t storage_offset; /* current read/write position */
973 gate_bool_t closed; /* true, when stream is closed */
974 } memfile_t;
975
976 11 static void memfile_destroy(memfile_t* self)
977 {
978 11 gate_arraylist_release(self->storage);
979 11 gate_mem_dealloc(self);
980 11 }
981
982 23 static char const* memfile_get_interface_name(void* obj)
983 {
984 GATE_UNUSED_ARG(obj);
985 23 return GATE_INTERFACE_NAME_MEMFILE;
986 }
987 22 static void memfile_release(void* obj)
988 {
989 22 memfile_t* const self = (memfile_t*)obj;
990
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
22 if (0 == gate_atomic_int_dec(&self->ref_counter))
991 {
992 11 memfile_destroy(self);
993 }
994 22 }
995 11 static int memfile_retain(void* obj)
996 {
997 11 memfile_t* const self = (memfile_t*)obj;
998 11 return (int)gate_atomic_int_inc(&self->ref_counter);
999 }
1000
1001 619 static gate_result_t memfile_peek(void* obj, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1002 {
1003 619 memfile_t* const self = (memfile_t*)obj;
1004 619 gate_result_t result = GATE_RESULT_FAILED;
1005 619 gate_size_t copied = 0;
1006 gate_size_t available;
1007 gate_size_t storage_length;
1008 619 char const* ptr_storage_data = NULL;
1009
1010 do
1011 {
1012
2/4
✓ Branch 0 taken 619 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 619 times.
619 if (!buffer || !obj)
1013 {
1014 result = GATE_RESULT_NULLPOINTER;
1015 break;
1016 }
1017
1018 619 storage_length = gate_arraylist_length(self->storage);
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 619 times.
619 GATE_DEBUG_ASSERT(self->storage_offset <= storage_length);
1020 619 available = storage_length - self->storage_offset;
1021
1022
3/4
✓ Branch 0 taken 619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 614 times.
619 if (self->closed || (available == 0))
1023 {
1024 /* react as end of stream */
1025 5 result = GATE_RESULT_OK;
1026 5 break;
1027 }
1028
1029 614 ptr_storage_data = (char const*)gate_arraylist_get(self->storage, self->storage_offset);
1030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 614 times.
614 if (!ptr_storage_data)
1031 {
1032 result = GATE_RESULT_NOTAVAILABLE;
1033 break;
1034 }
1035 614 copied = (bufferlength > available) ? available : bufferlength;
1036 614 gate_mem_copy(buffer, ptr_storage_data, copied);
1037 614 result = GATE_RESULT_OK;
1038 } while (0);
1039
1040
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 2 times.
619 if (returned)
1041 {
1042 617 *returned = copied;
1043 }
1044
1045 619 return result;
1046 }
1047
1048 416 static gate_result_t memfile_read(void* obj, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1049 {
1050 416 memfile_t* const self = (memfile_t*)obj;
1051 416 gate_result_t result = GATE_RESULT_FAILED;
1052 416 gate_size_t copied = 0;
1053
1054 416 result = memfile_peek(obj, buffer, bufferlength, &copied);
1055
1/2
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
416 if (GATE_SUCCEEDED(result))
1056 {
1057 416 self->storage_offset += copied;
1058 }
1059
1060
1/2
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
416 if (returned)
1061 {
1062 416 *returned = copied;
1063 }
1064
1065 416 return result;
1066 }
1067
1068 164 static gate_result_t memfile_write(void* obj, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
1069 {
1070 164 memfile_t* const self = (memfile_t*)obj;
1071 164 gate_result_t ret = GATE_RESULT_FAILED;
1072 164 gate_size_t stored_bytes = 0;
1073 gate_size_t storage_length;
1074 gate_size_t available;
1075 char* ptr_storage_data;
1076
1077 do
1078 {
1079 164 storage_length = gate_arraylist_length(self->storage);
1080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 164 times.
164 GATE_DEBUG_ASSERT(self->storage_offset <= storage_length);
1081 164 available = storage_length - self->storage_offset;
1082
1083
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 158 times.
164 if (available > 0)
1084 {
1085 6 ptr_storage_data = (char*)gate_arraylist_get(self->storage, self->storage_offset);
1086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ptr_storage_data)
1087 {
1088 ret = GATE_RESULT_NOTAVAILABLE;
1089 break;
1090 }
1091 6 stored_bytes = (bufferlength <= available) ? bufferlength : available;
1092 6 gate_mem_copy(ptr_storage_data, buffer, stored_bytes);
1093 6 self->storage_offset += stored_bytes;
1094 6 bufferlength -= stored_bytes;
1095 6 buffer += stored_bytes;
1096 }
1097
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 6 times.
164 if (bufferlength > 0)
1098 {
1099
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
158 if (NULL == gate_arraylist_insert(self->storage, storage_length, buffer, bufferlength))
1100 {
1101 ret = (stored_bytes > 0) ? GATE_RESULT_OK : GATE_RESULT_OUTOFMEMORY;
1102 break;
1103 }
1104 158 self->storage_offset += bufferlength;
1105 158 stored_bytes += bufferlength;
1106 }
1107 164 ret = GATE_RESULT_OK;
1108 } while (0);
1109
1110
1/2
✓ Branch 0 taken 164 times.
✗ Branch 1 not taken.
164 if (written)
1111 {
1112 164 *written = stored_bytes;
1113 }
1114 164 return ret;
1115 }
1116 107 static gate_result_t memfile_flush(void* obj)
1117 {
1118 GATE_UNUSED_ARG(obj);
1119 107 return GATE_RESULT_OK;
1120 }
1121
1122 static gate_result_t memfile_get_resource(void* obj, gate_enumint_t resource_type, gate_uintptr_t* resource)
1123 {
1124 memfile_t* const self = (memfile_t*)obj;
1125 switch (resource_type)
1126 {
1127 case GATE_STREAM_RESOURCE_INPUT:
1128 case GATE_STREAM_RESOURCE_OUTPUT:
1129 case GATE_STREAM_RESOURCE_DEFAULT:
1130 if (resource)
1131 {
1132 *resource = (gate_uintptr_t)gate_arraylist_get(self->storage, 0);
1133 }
1134 return GATE_RESULT_OK;
1135 default:
1136 {
1137 return GATE_RESULT_NOTAVAILABLE;
1138 }
1139 }
1140 }
1141 3 static gate_result_t memfile_can_read(void* obj, gate_bool_t* return_value)
1142 {
1143 3 memfile_t* const self = (memfile_t*)obj;
1144
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (return_value)
1145 {
1146 3 *return_value = !self->closed;
1147 }
1148 3 return GATE_RESULT_OK;
1149 }
1150 1 static gate_result_t memfile_can_write(void* obj, gate_bool_t* return_value)
1151 {
1152 1 memfile_t* const self = (memfile_t*)obj;
1153
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (return_value)
1154 {
1155 1 *return_value = !self->closed;
1156 }
1157 1 return GATE_RESULT_OK;
1158 }
1159 1 static gate_result_t memfile_get_size(void* obj, gate_int64_t* return_value)
1160 {
1161 1 memfile_t* const self = (memfile_t*)obj;
1162
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (return_value)
1163 {
1164 1 *return_value = (gate_int64_t)gate_arraylist_length(self->storage);
1165 }
1166 1 return GATE_RESULT_OK;
1167 }
1168 2 static gate_result_t memfile_get_available(void* obj, gate_int64_t* return_value)
1169 {
1170 2 memfile_t* const self = (memfile_t*)obj;
1171
1172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (self->closed)
1173 {
1174 return GATE_RESULT_INVALIDSTATE;
1175 }
1176
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if (return_value)
1177 {
1178 2 gate_size_t storage_length = gate_arraylist_length(self->storage);
1179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(self->storage_offset <= storage_length);
1180 2 *return_value = (gate_int64_t)(storage_length - self->storage_offset);
1181 }
1182 2 return GATE_RESULT_OK;
1183 }
1184 62 static gate_result_t memfile_seek(void* obj, gate_int64_t position, gate_enumint_t origin, gate_int64_t* final_position)
1185 {
1186 62 memfile_t* const self = (memfile_t*)obj;
1187 62 gate_result_t result = GATE_RESULT_FAILED;
1188 gate_size_t shift;
1189 gate_size_t storage_length;
1190
1191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (self->closed)
1192 {
1193 return GATE_RESULT_NOTAVAILABLE;
1194 }
1195
1196 62 storage_length = gate_arraylist_length(self->storage);
1197
1198
3/4
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
62 switch (origin)
1199 {
1200 43 case GATE_STREAM_SEEK_BEGIN:
1201 {
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (position < 0)
1203 {
1204 result = GATE_RESULT_INVALIDARG;
1205 break;
1206 }
1207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (position > (gate_int64_t)storage_length)
1208 {
1209 result = GATE_RESULT_NOTSUPPORTED;
1210 break;
1211 }
1212 43 self->storage_offset = (gate_size_t)(gate_uint64_t)position;
1213 43 result = GATE_RESULT_OK;
1214 43 break;
1215 }
1216 13 case GATE_STREAM_SEEK_CURRENT:
1217 {
1218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (position < 0)
1219 {
1220 shift = (gate_size_t)(gate_uint64_t)(-position);
1221 if (shift > self->storage_offset)
1222 {
1223 result = GATE_RESULT_NOTSUPPORTED;
1224 break;
1225 }
1226 self->storage_offset -= shift;
1227 }
1228 else
1229 {
1230 13 shift = (gate_size_t)(gate_uint64_t)position;
1231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (self->storage_offset + shift > storage_length)
1232 {
1233 result = GATE_RESULT_NOTSUPPORTED;
1234 break;
1235 }
1236 13 self->storage_offset += shift;
1237 }
1238 13 result = GATE_RESULT_OK;
1239 13 break;
1240 }
1241 6 case GATE_STREAM_SEEK_END:
1242 {
1243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (position > 0)
1244 {
1245 result = GATE_RESULT_NOTSUPPORTED;
1246 break;
1247 }
1248 6 shift = (gate_size_t)(-position);
1249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (shift > storage_length)
1250 {
1251 result = GATE_RESULT_INVALIDARG;
1252 break;
1253 }
1254 6 self->storage_offset = storage_length - shift;
1255 6 result = GATE_RESULT_OK;
1256 6 break;
1257 }
1258 default:
1259 {
1260 result = GATE_RESULT_INVALIDARG;
1261 break;
1262 }
1263 }
1264
1265
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 4 times.
62 if (final_position)
1266 {
1267 58 *final_position = (gate_int64_t)(gate_uint64_t)self->storage_offset;
1268 }
1269 62 return result;
1270 }
1271 1 static gate_result_t memfile_reset(void* obj)
1272 {
1273 1 memfile_t* const self = (memfile_t*)obj;
1274 1 self->storage_offset = 0;
1275 1 return GATE_RESULT_OK;
1276 }
1277 4 static gate_result_t memfile_close(void* obj, gate_enumint_t close_type)
1278 {
1279 4 memfile_t* const self = (memfile_t*)obj;
1280
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 switch (close_type)
1281 {
1282 4 case GATE_STREAM_CLOSE_DEFAULT:
1283 case GATE_STREAM_CLOSE_INPUT:
1284 case GATE_STREAM_CLOSE_OUTPUT:
1285 4 self->closed = true;
1286 4 return GATE_RESULT_OK;
1287 default:
1288 return GATE_RESULT_NOTSUPPORTED;
1289 }
1290 }
1291
1292 static GATE_INTERFACE_VTBL(gate_controlstream) memfile_vtbl;
1293
1294 11 static void init_memfile_vtbl()
1295 {
1296
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 if (memfile_vtbl.get_interface_name == NULL)
1297 {
1298 3 GATE_INTERFACE_VTBL(gate_controlstream) local_vtbl =
1299 {
1300 &memfile_get_interface_name,
1301 &memfile_release,
1302 &memfile_retain,
1303
1304 &memfile_read,
1305 &memfile_peek,
1306 &memfile_write,
1307 &memfile_flush,
1308
1309 &memfile_get_resource,
1310
1311 &memfile_can_read,
1312 &memfile_can_write,
1313 &memfile_get_size,
1314 &memfile_get_available,
1315 &memfile_seek,
1316 &memfile_reset,
1317 &memfile_close
1318 };
1319 3 memfile_vtbl = local_vtbl;
1320 }
1321 11 }
1322
1323 7 gate_controlstream_t* gate_memfilestream_create(gate_size_t prealloc)
1324 {
1325 7 gate_controlstream_t* ret = NULL;
1326 7 memfile_t* newstrm = NULL;
1327
1328 do
1329 {
1330 7 newstrm = (memfile_t*)gate_mem_alloc(sizeof(memfile_t));
1331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!newstrm)
1332 {
1333 break;
1334 }
1335 7 gate_mem_clear(newstrm, sizeof(memfile_t));
1336 7 init_memfile_vtbl();
1337 7 newstrm->vtbl = &memfile_vtbl;
1338 7 gate_atomic_int_init(&newstrm->ref_counter, 1);
1339 7 newstrm->storage = gate_arraylist_create(sizeof(char), NULL, prealloc, NULL, NULL);
1340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!newstrm->storage)
1341 {
1342 break;
1343 }
1344 7 newstrm->closed = false;
1345 7 newstrm->storage_offset = 0;
1346
1347 /* success case */
1348 7 ret = (gate_controlstream_t*)newstrm;
1349 7 newstrm = NULL;
1350 } while (0);
1351
1352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (newstrm)
1353 {
1354 memfile_destroy(newstrm);
1355 }
1356 7 return ret;
1357 }
1358
1359 4 gate_controlstream_t* gate_memfilestream_share(gate_controlstream_t* ptr_memfile)
1360 {
1361 4 gate_controlstream_t* ret = NULL;
1362 4 memfile_t* other_memfile = NULL;
1363 4 memfile_t* newstrm = NULL;
1364
1365 do
1366 {
1367
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (!gate_object_implements_interface((gate_object_t*)ptr_memfile, GATE_INTERFACE_NAME_MEMFILE))
1368 {
1369 /* given stream is not a mem-file */
1370 break;
1371 }
1372 4 other_memfile = (memfile_t*)ptr_memfile;
1373
1374 4 newstrm = (memfile_t*)gate_mem_alloc(sizeof(memfile_t));
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!newstrm)
1376 {
1377 break;
1378 }
1379 4 gate_mem_clear(newstrm, sizeof(memfile_t));
1380 4 init_memfile_vtbl();
1381 4 newstrm->vtbl = &memfile_vtbl;
1382 4 gate_atomic_int_init(&newstrm->ref_counter, 1);
1383 4 newstrm->storage = other_memfile->storage;
1384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!newstrm->storage)
1385 {
1386 break;
1387 }
1388 4 gate_arraylist_retain(newstrm->storage);
1389 4 newstrm->closed = false;
1390 4 newstrm->storage_offset = 0;
1391
1392 /* success case */
1393 4 ret = (gate_controlstream_t*)newstrm;
1394 4 newstrm = NULL;
1395 } while (0);
1396
1397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (newstrm)
1398 {
1399 memfile_destroy(newstrm);
1400 }
1401 4 return ret;
1402 }
1403
1404
1405
1406 /********************************
1407 * string stream implementation *
1408 ********************************/
1409
1410 static void gate_stringstream_release_impl(void* thisptr);
1411 static int gate_stringstream_retain_impl(void* thisptr);
1412 static char const* gate_stringstream_get_interface_name_impl(void* thisptr);
1413 static gate_result_t gate_stringstream_read_impl(void* thisptr, char* buffer, gate_size_t bufferlength, gate_size_t* returned);
1414 static gate_result_t gate_stringstream_peek_impl(void* thisptr, char* buffer, gate_size_t bufferlength, gate_size_t* returned);
1415 static gate_result_t gate_stringstream_write_impl(void* thisptr, char const* buffer, gate_size_t bufferlength, gate_size_t* written);
1416 static gate_result_t gate_stringstream_flush_impl(void* thisptr);
1417
1418 static char const* gate_stringstream_get_data_impl(void* thisptr);
1419 static gate_size_t gate_stringstream_size_impl(void* thisptr);
1420
1421 static gate_result_t gate_stringstream_get_current_view_impl(void*, gate_string_t* ptr_output);
1422 static gate_result_t gate_stringstream_to_string_impl(void*, gate_string_t* ptr_output);
1423
1424
1425 static GATE_INTERFACE_VTBL(gate_stringstream) gate_stringstream_vtbl;
1426 110 static void gate_init_stringstream_vtbl()
1427 {
1428
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 101 times.
110 if (!gate_stringstream_vtbl.get_interface_name)
1429 {
1430 9 GATE_INTERFACE_VTBL(gate_stringstream) local_vtbl =
1431 {
1432 &gate_stringstream_get_interface_name_impl,
1433 &gate_stringstream_release_impl,
1434 &gate_stringstream_retain_impl,
1435
1436 &gate_stringstream_read_impl,
1437 &gate_stringstream_peek_impl,
1438 &gate_stringstream_write_impl,
1439 &gate_stringstream_flush_impl,
1440
1441 &gate_stringstream_get_data_impl,
1442 &gate_stringstream_size_impl,
1443 &gate_stringstream_get_current_view_impl,
1444 &gate_stringstream_to_string_impl
1445 };
1446 9 gate_stringstream_vtbl = local_vtbl;
1447 }
1448 110 }
1449
1450 typedef struct gate_stringstream_impl
1451 {
1452 GATE_INTERFACE_VTBL(gate_stringstream)* vtbl;
1453
1454 gate_atomic_int_t ref_counter;
1455 gate_strbuilder_t* ptr_builder;
1456 gate_strbuilder_t str_builder;
1457 } gate_stringstream_impl_t;
1458
1459
1460 110 gate_stringstream_t* gate_stringstream_create(gate_size_t capacity)
1461 {
1462 110 gate_stringstream_impl_t* ret = gate_mem_alloc(sizeof(gate_stringstream_impl_t));
1463
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if (ret != NULL)
1464 {
1465 110 gate_mem_clear(ret, sizeof(gate_stringstream_impl_t));
1466 110 gate_init_stringstream_vtbl();
1467 110 ret->vtbl = &gate_stringstream_vtbl;
1468 110 gate_atomic_int_init(&ret->ref_counter, 1);
1469 110 gate_strbuilder_create(&ret->str_builder, capacity);
1470 110 ret->ptr_builder = &ret->str_builder;
1471 }
1472 110 return (gate_stringstream_t*)ret;
1473 }
1474
1475 gate_stringstream_t* gate_stringstream_create_builder(gate_strbuilder_t* external_strbuilder)
1476 {
1477 gate_stringstream_impl_t* ret = gate_mem_alloc(sizeof(gate_stringstream_impl_t));
1478 if (ret != NULL)
1479 {
1480 gate_mem_clear(ret, sizeof(gate_stringstream_impl_t));
1481 gate_init_stringstream_vtbl();
1482 ret->vtbl = &gate_stringstream_vtbl;
1483 gate_atomic_int_init(&ret->ref_counter, 1);
1484 ret->ptr_builder = external_strbuilder;
1485 }
1486 return (gate_stringstream_t*)ret;
1487 }
1488
1489
1490 111 static void gate_stringstream_release_impl(void* ptr)
1491 {
1492 111 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1493
2/2
✓ Branch 1 taken 110 times.
✓ Branch 2 taken 1 times.
111 if (gate_atomic_int_dec(&thisptr->ref_counter) == 0)
1494 {
1495
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if (&thisptr->str_builder == thisptr->ptr_builder)
1496 {
1497 110 gate_strbuilder_release(thisptr->ptr_builder);
1498 }
1499 110 gate_mem_dealloc(thisptr);
1500 }
1501 111 }
1502 1 static int gate_stringstream_retain_impl(void* ptr)
1503 {
1504 1 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1505 1 return (int)gate_atomic_int_inc(&thisptr->ref_counter);
1506 }
1507 2 static char const* gate_stringstream_get_interface_name_impl(void* ptr)
1508 {
1509 (void)ptr;
1510 2 return GATE_INTERFACE_NAME_STRINGSTREAM;
1511 }
1512 324 static gate_result_t gate_stringstream_read_impl(void* ptr, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1513 {
1514 324 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1515 324 gate_size_t bytesread = 0;
1516 324 gate_result_t result = gate_stringstream_peek_impl(ptr, buffer, bufferlength, &bytesread);
1517
1518
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 if (GATE_SUCCEEDED(result))
1519 {
1520 324 gate_strbuilder_discard(thisptr->ptr_builder, bytesread);
1521
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 if (returned != NULL)
1522 {
1523 324 *returned = bytesread;
1524 }
1525 }
1526 324 return result;
1527 }
1528 524 static gate_result_t gate_stringstream_peek_impl(void* ptr, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1529 {
1530 524 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1531 524 char const* dataptr = gate_strbuilder_ptr(thisptr->ptr_builder, 0);
1532 524 gate_size_t datalen = gate_strbuilder_length(thisptr->ptr_builder);
1533
2/4
✓ Branch 0 taken 524 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 524 times.
524 if ((bufferlength > 0) && (buffer == NULL))
1534 {
1535 return GATE_RESULT_INVALIDARG;
1536 }
1537
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 440 times.
524 if (bufferlength > datalen)
1538 {
1539 84 bufferlength = datalen;
1540 }
1541
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 49 times.
524 if (bufferlength > 0)
1542 {
1543
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 475 times.
475 if (NULL == gate_mem_copy(buffer, dataptr, bufferlength))
1544 {
1545 return GATE_RESULT_FAILED;
1546 }
1547 }
1548
1/2
✓ Branch 0 taken 524 times.
✗ Branch 1 not taken.
524 if (returned != NULL)
1549 {
1550 524 *returned = bufferlength;
1551 }
1552 524 return GATE_RESULT_OK;
1553 }
1554 525 static gate_result_t gate_stringstream_write_impl(void* ptr, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
1555 {
1556 525 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1557 gate_size_t lenwritten;
1558 gate_result_t ret;
1559 525 lenwritten = gate_strbuilder_append_text(thisptr->ptr_builder, buffer, bufferlength);
1560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 ret = (lenwritten == 0) ? GATE_RESULT_FAILED : GATE_RESULT_OK;
1561
1562
1/2
✓ Branch 0 taken 525 times.
✗ Branch 1 not taken.
525 if (written != NULL)
1563 {
1564 525 *written = lenwritten;
1565 }
1566 525 return ret;
1567 }
1568 103 static gate_result_t gate_stringstream_flush_impl(void* ptr)
1569 {
1570 (void)ptr;
1571 103 return GATE_RESULT_OK;
1572 }
1573
1574 3 static char const* gate_stringstream_get_data_impl(void* ptr)
1575 {
1576 3 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1577 3 return gate_strbuilder_ptr(thisptr->ptr_builder, 0);
1578 }
1579 3 static gate_size_t gate_stringstream_size_impl(void* ptr)
1580 {
1581 3 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1582 3 return gate_strbuilder_length(thisptr->ptr_builder);
1583 }
1584 18 static gate_result_t gate_stringstream_get_current_view_impl(void* ptr, gate_string_t* ptr_output)
1585 {
1586 18 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1587
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 if (NULL != gate_string_create_static_len(ptr_output,
1588 18 gate_strbuilder_ptr(thisptr->ptr_builder, 0), gate_strbuilder_length(thisptr->ptr_builder)))
1589 {
1590 18 return GATE_RESULT_OK;
1591 }
1592 else
1593 {
1594 return GATE_RESULT_OUTOFMEMORY;
1595 }
1596 }
1597 48 static gate_result_t gate_stringstream_to_string_impl(void* ptr, gate_string_t* ptr_output)
1598 {
1599 48 gate_stringstream_impl_t* thisptr = (gate_stringstream_impl_t*)ptr;
1600
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if (NULL == gate_strbuilder_to_string(thisptr->ptr_builder, ptr_output))
1601 {
1602 return GATE_RESULT_FAILED;
1603 }
1604 else
1605 {
1606 48 return GATE_RESULT_OK;
1607 }
1608 }
1609
1610
1611
1612 /********************************
1613 * null stream implementation *
1614 ********************************/
1615
1616 18 static void gate_nullstream_release_impl(void* self)
1617 {
1618 (void)self;
1619 18 }
1620 9 static int gate_nullstream_retain_impl(void* self)
1621 {
1622 (void)self;
1623 9 return 1;
1624 }
1625 static char const* gate_nullstream_get_interface_name_impl(void* self)
1626 {
1627 (void)self;
1628 return GATE_INTERFACE_NAME_STREAM;
1629 }
1630 static gate_result_t gate_nullstream_read_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1631 {
1632 (void)self;
1633 (void)buffer;
1634 (void)bufferlength;
1635 if (returned != NULL)
1636 {
1637 *returned = 0;
1638 }
1639 return GATE_RESULT_OK;
1640 }
1641 static gate_result_t gate_nullstream_peek_impl(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1642 {
1643 (void)self;
1644 (void)buffer;
1645 (void)bufferlength;
1646 if (returned != NULL)
1647 {
1648 *returned = 0;
1649 }
1650 return GATE_RESULT_OK;
1651 }
1652 static gate_result_t gate_nullstream_write_impl(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
1653 {
1654 (void)self;
1655 (void)buffer;
1656 if (written != NULL)
1657 {
1658 *written = bufferlength;
1659 }
1660 return GATE_RESULT_OK;
1661 }
1662 static gate_result_t gate_nullstream_flush_impl(void* self)
1663 {
1664 (void)self;
1665 return GATE_RESULT_OK;
1666 }
1667
1668 static GATE_INTERFACE_VTBL(gate_stream) gate_nullstream_vtbl;
1669 static gate_stream_t global_null_stream =
1670 {
1671 &gate_nullstream_vtbl
1672 };
1673 9 static void gate_nullstream_vtbl_init()
1674 {
1675
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (!gate_nullstream_vtbl.get_interface_name)
1676 {
1677
1678 2 GATE_INTERFACE_VTBL(gate_stream) local_vtbl =
1679 {
1680 &gate_nullstream_get_interface_name_impl,
1681 &gate_nullstream_release_impl,
1682 &gate_nullstream_retain_impl,
1683 &gate_nullstream_read_impl,
1684 &gate_nullstream_peek_impl,
1685 &gate_nullstream_write_impl,
1686 &gate_nullstream_flush_impl
1687 };
1688 2 gate_nullstream_vtbl = local_vtbl;
1689 }
1690 9 }
1691
1692 #define GATE_INTERFACE_VTBL_INIT(ifname, vtbl_instance, vtbl_block) \
1693 if(! ( vtbl_instance . get_interface_name ) ) { \
1694 GATE_INTERFACE_VTBL(gate_stream) local_vtbl = { GATE_STRIP_PARENTHESES vtbl_block }; \
1695 vtbl_instance = local_vtbl; \
1696 }
1697
1698
1699 9 gate_stream_t* gate_nullstream()
1700 {
1701 9 gate_nullstream_vtbl_init();
1702
1703 9 return &global_null_stream;
1704 }
1705
1706
1707
1708 1474 gate_result_t gate_stream_read_block(gate_stream_t* stream, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1709 {
1710 1474 gate_result_t result = GATE_RESULT_OK;
1711 1474 gate_size_t totalread = 0;
1712 gate_size_t blockread;
1713
2/2
✓ Branch 0 taken 1490 times.
✓ Branch 1 taken 1434 times.
2924 while (totalread < bufferlength)
1714 {
1715 1490 blockread = 0;
1716 1490 result = gate_stream_read(stream, &buffer[totalread], bufferlength - totalread, &blockread);
1717
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1489 times.
1490 if (GATE_FAILED(result))
1718 {
1719 1 break;
1720 }
1721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1489 times.
1489 GATE_DEBUG_ASSERT(blockread <= (bufferlength - totalread));
1722
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1450 times.
1489 if (blockread == 0)
1723 {
1724 39 break;
1725 }
1726 1450 totalread += blockread;
1727 }
1728
1/2
✓ Branch 0 taken 1474 times.
✗ Branch 1 not taken.
1474 if (returned != NULL)
1729 {
1730 1474 *returned = totalread;
1731 }
1732 1474 return result;
1733 }
1734
1735 1883 gate_result_t gate_stream_read_line(gate_stream_t* stream, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
1736 {
1737 1883 gate_result_t ret = GATE_RESULT_OK;
1738 1883 gate_size_t pos = 0;
1739 gate_size_t lenread;
1740
1741
1/2
✓ Branch 0 taken 50702 times.
✗ Branch 1 not taken.
50702 while (pos != bufferlength)
1742 {
1743 50702 ret = gate_stream_read(stream, &buffer[pos], 1, &lenread);
1744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50702 times.
50702 GATE_BREAK_IF_FAILED(ret);
1745
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 50669 times.
50702 if (lenread == 0)
1746 {
1747 /* end of stream */
1748 33 break;
1749 }
1750
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50669 times.
50669 if (buffer[pos] == '\b')
1751 {
1752 if (pos > 0)
1753 {
1754 --pos;
1755 }
1756 continue;
1757 }
1758
1759
2/2
✓ Branch 0 taken 1850 times.
✓ Branch 1 taken 48819 times.
50669 if (buffer[pos] == '\n')
1760 {
1761 /* end of line */
1762 1850 ++pos;
1763 1850 break;
1764 }
1765 48819 ++pos;
1766 }
1767
1/2
✓ Branch 0 taken 1883 times.
✗ Branch 1 not taken.
1883 if (returned != NULL)
1768 {
1769 1883 *returned = pos;
1770 }
1771 1883 return ret;
1772 }
1773
1774
1775 117681 gate_result_t gate_stream_write_block(gate_stream_t* stream, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
1776 {
1777 117681 gate_result_t result = GATE_RESULT_OK;
1778 117681 gate_size_t totalwritten = 0;
1779 gate_size_t blockwritten;
1780
2/2
✓ Branch 0 taken 114413 times.
✓ Branch 1 taken 117681 times.
232094 while (totalwritten < bufferlength)
1781 {
1782 114413 blockwritten = 0;
1783 114413 result = gate_stream_write(stream, &buffer[totalwritten], bufferlength - totalwritten, &blockwritten);
1784 /*result = stream->vtbl->write(stream, &buffer[totalwritten], bufferlength - totalwritten, &blockwritten);*/
1785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114413 times.
114413 if (GATE_FAILED(result))
1786 {
1787 break;
1788 }
1789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114413 times.
114413 GATE_DEBUG_ASSERT(blockwritten <= (bufferlength - totalwritten));
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114413 times.
114413 if (blockwritten == 0)
1791 {
1792 result = GATE_RESULT_CANCELED;
1793 break;
1794 }
1795 114413 totalwritten += blockwritten;
1796 }
1797
1/2
✓ Branch 0 taken 117681 times.
✗ Branch 1 not taken.
117681 if (GATE_SUCCEEDED(result))
1798 {
1799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117681 times.
117681 GATE_DEBUG_ASSERT(bufferlength == totalwritten);
1800 }
1801
2/2
✓ Branch 0 taken 114810 times.
✓ Branch 1 taken 2871 times.
117681 if (written != NULL)
1802 {
1803 114810 *written = totalwritten;
1804 }
1805 117681 return result;
1806 }
1807
1808
1809 2692 gate_result_t gate_stream_print_cstr(gate_stream_t* stream, gate_cstr_t text)
1810 {
1811 2692 gate_size_t textlength = gate_str_length(text);
1812 gate_size_t written;
1813 2692 return gate_stream_write_block(stream, text, textlength, &written);
1814 }
1815 gate_result_t gate_stream_print_wstr(gate_stream_t* stream, gate_wstr_t wstr, gate_size_t wstr_len)
1816 {
1817 gate_result_t ret = GATE_RESULT_FAILED;
1818 char buffer[8192 + 4096];
1819 char* ptr_buffer = &buffer[0];
1820 gate_size_t max_utf8_length = wstr_len * 3 + 1;
1821 gate_size_t buffer_used;
1822 gate_string_t tmp = GATE_STRING_INIT_EMPTY;
1823
1824 do
1825 {
1826 if (max_utf8_length >= sizeof(buffer))
1827 {
1828 ptr_buffer = (char*)gate_mem_alloc(max_utf8_length);
1829 if (ptr_buffer == NULL)
1830 {
1831 ret = GATE_RESULT_OUTOFMEMORY;
1832 break;
1833 }
1834 }
1835
1836 buffer_used = gate_wstr_to_cstr(wstr, wstr_len, ptr_buffer, max_utf8_length);
1837 gate_string_create_static_len(&tmp, ptr_buffer, buffer_used);
1838 ret = gate_stream_print_string(stream, &tmp);
1839 } while (0);
1840
1841 if ((ptr_buffer != NULL) && (ptr_buffer != &buffer[0]))
1842 {
1843 gate_mem_dealloc(ptr_buffer);
1844 }
1845 return ret;
1846 }
1847
1848 1038 gate_result_t gate_stream_println_cstr(gate_stream_t* stream, char const* text)
1849 {
1850 1038 gate_size_t textlength = gate_str_length(text);
1851 1038 gate_result_t result = GATE_RESULT_OK;
1852
2/2
✓ Branch 0 taken 955 times.
✓ Branch 1 taken 83 times.
1038 if (textlength > 0)
1853 {
1854 955 result = gate_stream_write_block(stream, text, textlength, NULL);
1855 }
1856
1/2
✓ Branch 0 taken 1038 times.
✗ Branch 1 not taken.
1038 if (GATE_SUCCEEDED(result))
1857 {
1858 1038 result = gate_stream_write_block(stream, GATE_STR_NEWLINE, GATE_STR_NEWLINE_LENGTH, NULL);
1859 }
1860 1038 return result;
1861 }
1862 18 gate_result_t gate_stream_print_int(gate_stream_t* stream, gate_int32_t num)
1863 {
1864 gate_char8_t buffer[24];
1865 18 gate_size_t bufferlength = gate_str_print_int32(buffer, sizeof(buffer), num);
1866 18 return gate_stream_write_block(stream, buffer, bufferlength, NULL);
1867 }
1868 536 gate_result_t gate_stream_print_uint(gate_stream_t* stream, gate_uint32_t num)
1869 {
1870 gate_char8_t buffer[24];
1871 536 gate_size_t bufferlength = gate_str_print_uint32(buffer, sizeof(buffer), num);
1872 536 return gate_stream_write_block(stream, buffer, bufferlength, NULL);
1873 }
1874 18 gate_result_t gate_stream_print_int64(gate_stream_t* stream, gate_int64_t num)
1875 {
1876 gate_char8_t buffer[48];
1877 18 gate_size_t bufferlength = gate_str_print_int64(buffer, sizeof(buffer), num);
1878 18 return gate_stream_write_block(stream, buffer, bufferlength, NULL);
1879 }
1880 6 gate_result_t gate_stream_print_uint64(gate_stream_t* stream, gate_uint64_t num)
1881 {
1882 gate_char8_t buffer[48];
1883 6 gate_size_t bufferlength = gate_str_print_uint64(buffer, sizeof(buffer), num);
1884 6 return gate_stream_write_block(stream, buffer, bufferlength, NULL);
1885 }
1886 258 gate_result_t gate_stream_print_real(gate_stream_t* stream, gate_real64_t num, unsigned intlen, unsigned decimallen, unsigned grouplen)
1887 {
1888 gate_char8_t buffer[64];
1889 258 gate_size_t bufferlength = gate_str_print_real(buffer, sizeof(buffer), num, intlen, decimallen, grouplen);
1890 258 return gate_stream_write_block(stream, buffer, bufferlength, NULL);
1891 }
1892 40 gate_result_t gate_stream_print_string(gate_stream_t* stream, gate_string_t const* text)
1893 {
1894
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 if (text != NULL)
1895 {
1896 40 return gate_stream_write_block(stream, text->str, text->length, NULL);
1897 }
1898 else
1899 {
1900 return GATE_RESULT_OK;
1901 }
1902 }
1903
1904
1905 3232 gate_result_t gate_stream_print(gate_stream_t* stream, ...)
1906 {
1907 3232 gate_result_t ret = GATE_RESULT_OK;
1908 3232 gate_bool_t continue_loop = true;
1909 char buffer[512];
1910 va_list vl;
1911 3232 va_start(vl, stream);
1912
1913 /* INFO: types small than [int] are converted to [int]
1914 https://stackoverflow.com/questions/23983471/char-is-promoted-to-int-when-passed-through-in-c
1915 */
1916
1917
2/2
✓ Branch 0 taken 10672 times.
✓ Branch 1 taken 3232 times.
13904 while (continue_loop)
1918 {
1919 10672 gate_size_t text_len = 0;
1920 10672 char const* ptr_text = NULL;
1921 10672 int print_type = va_arg(vl, int);
1922
1923
8/25
✓ Branch 0 taken 3232 times.
✓ Branch 1 taken 4180 times.
✓ Branch 2 taken 588 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2078 times.
✓ Branch 7 taken 117 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 247 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 224 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
10672 switch (print_type)
1924 {
1925 3232 case GATE_PRINT_END:
1926 {
1927 3232 text_len = 0;
1928 3232 continue_loop = false;
1929 3232 break;
1930 }
1931 4180 case GATE_PRINT_CHAR:
1932 {
1933 4180 buffer[0] = (char)va_arg(vl, int);
1934 4180 ptr_text = &buffer[0];
1935 4180 text_len = 1;
1936 4180 break;
1937 }
1938 588 case GATE_PRINT_NEWLINE:
1939 {
1940 588 ptr_text = GATE_STR_NEWLINE;
1941 588 text_len = GATE_STR_NEWLINE_LENGTH;
1942 588 break;
1943 }
1944 case GATE_PRINT_CR:
1945 {
1946 ptr_text = GATE_STR_CR;
1947 text_len = 1;
1948 break;
1949 }
1950 case GATE_PRINT_LF:
1951 {
1952 ptr_text = GATE_STR_LF;
1953 text_len = 1;
1954 break;
1955 }
1956 case GATE_PRINT_CRLF:
1957 {
1958 ptr_text = GATE_STR_CRLF;
1959 text_len = 2;
1960 break;
1961 }
1962 2078 case GATE_PRINT_CSTR:
1963 {
1964 2078 char const* val_cstr = va_arg(vl, char const*);
1965 2078 ptr_text = val_cstr;
1966 2078 text_len = gate_str_length(val_cstr);
1967 2078 break;
1968 }
1969 117 case GATE_PRINT_STRING:
1970 {
1971 117 gate_string_t const* val_str = va_arg(vl, gate_string_t const*);
1972 117 ptr_text = val_str->str;
1973 117 text_len = val_str->length;
1974 117 break;
1975 }
1976 case GATE_PRINT_BOOL:
1977 {
1978 gate_bool_t val_bool = (gate_bool_t)va_arg(vl, int);
1979 ptr_text = val_bool ? "true" : "false";
1980 text_len = val_bool ? 4 : 5;
1981 break;
1982 }
1983 case GATE_PRINT_I8:
1984 {
1985 gate_int8_t val_i8 = (gate_int8_t)va_arg(vl, int);
1986 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i8);
1987 ptr_text = buffer;
1988 break;
1989 }
1990 case GATE_PRINT_UI8:
1991 {
1992 gate_uint8_t val_ui8 = (gate_uint8_t)va_arg(vl, int);
1993 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui8);
1994 ptr_text = buffer;
1995 break;
1996 }
1997 case GATE_PRINT_I16:
1998 {
1999 gate_int16_t val_i16 = (gate_int16_t)va_arg(vl, int);
2000 text_len = gate_str_print_int16(buffer, sizeof(buffer), val_i16);
2001 ptr_text = buffer;
2002 break;
2003 }
2004 247 case GATE_PRINT_UI16:
2005 {
2006 247 gate_uint16_t val_ui16 = (gate_uint16_t)va_arg(vl, int);
2007 247 text_len = gate_str_print_uint16(buffer, sizeof(buffer), val_ui16);
2008 247 ptr_text = buffer;
2009 247 break;
2010 }
2011 case GATE_PRINT_I32:
2012 {
2013 gate_int32_t val_i32 = va_arg(vl, gate_int32_t);
2014 text_len = gate_str_print_int32(buffer, sizeof(buffer), val_i32);
2015 ptr_text = buffer;
2016 break;
2017 }
2018 224 case GATE_PRINT_UI32:
2019 {
2020 224 gate_uint32_t val_ui32 = va_arg(vl, gate_uint32_t);
2021 224 text_len = gate_str_print_uint32(buffer, sizeof(buffer), val_ui32);
2022 224 ptr_text = buffer;
2023 224 break;
2024 }
2025 case GATE_PRINT_I64:
2026 {
2027 gate_int64_t val_i64 = va_arg(vl, gate_int64_t);
2028 text_len = gate_str_print_int64(buffer, sizeof(buffer), val_i64);
2029 ptr_text = buffer;
2030 break;
2031 }
2032 case GATE_PRINT_UI64:
2033 {
2034 gate_uint64_t val_ui64 = va_arg(vl, gate_uint64_t);
2035 text_len = gate_str_print_uint64(buffer, sizeof(buffer), val_ui64);
2036 ptr_text = buffer;
2037 break;
2038 }
2039 6 case GATE_PRINT_H8:
2040 {
2041 6 gate_uint8_t val_ui8 = (gate_uint8_t)va_arg(vl, unsigned int);
2042 6 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui8, 1, false);
2043 6 ptr_text = buffer;
2044 6 break;
2045 }
2046 case GATE_PRINT_H16:
2047 {
2048 gate_uint16_t val_ui16 = (gate_uint16_t)va_arg(vl, unsigned int);
2049 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui16, 2, false);
2050 ptr_text = buffer;
2051 break;
2052 }
2053 case GATE_PRINT_H32:
2054 {
2055 gate_uint32_t val_ui32 = (gate_uint32_t)va_arg(vl, gate_uint32_t);
2056 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui32, 4, false);
2057 ptr_text = buffer;
2058 break;
2059 }
2060 case GATE_PRINT_H64:
2061 {
2062 gate_uint64_t val_ui64 = (gate_uint64_t)va_arg(vl, gate_uint64_t);
2063 text_len = gate_str_print_hex(buffer, sizeof(buffer), val_ui64, 8, false);
2064 ptr_text = buffer;
2065 break;
2066 }
2067 case GATE_PRINT_R32:
2068 {
2069 gate_real32_t val_r32 = (gate_real32_t)va_arg(vl, double);
2070 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r32, 0, 6, 0);
2071 ptr_text = buffer;
2072 break;
2073 }
2074 case GATE_PRINT_R64:
2075 {
2076 gate_real64_t val_r64 = va_arg(vl, gate_real64_t);
2077 text_len = gate_str_print_real(buffer, sizeof(buffer), val_r64, 0, 6, 0);
2078 ptr_text = buffer;
2079 break;
2080 }
2081 case GATE_PRINT_ADDRESS:
2082 {
2083 void* val_ptr = va_arg(vl, void*);
2084 if (sizeof(void*) == 2)
2085 {
2086 text_len = gate_str_print_hex_uint16(buffer, sizeof(buffer), (gate_uint16_t)(gate_uintptr_t)val_ptr, true);
2087 }
2088 else if (sizeof(void*) == 4)
2089 {
2090 text_len = gate_str_print_hex_uint32(buffer, sizeof(buffer), (gate_uint32_t)(gate_uintptr_t)val_ptr, true);
2091 }
2092 else
2093 {
2094 text_len = gate_str_print_hex_uint64(buffer, sizeof(buffer), (gate_uint64_t)(gate_uintptr_t)val_ptr, true);
2095 }
2096 ptr_text = buffer;
2097 break;
2098 }
2099 default:
2100 {
2101 ret = GATE_RESULT_INVALIDARG;
2102 continue_loop = false;
2103 break;
2104 }
2105 }
2106
2107 10672 ret = gate_stream_write_block(stream, ptr_text, text_len, &text_len);
2108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10672 times.
10672 GATE_BREAK_IF_FAILED(ret);
2109 }
2110 3232 va_end(vl);
2111 3232 return ret;
2112 }
2113
2114 static gate_result_t gate_stream_peek_utf8_char(gate_stream_t* stream, gate_char32_t* chr, gate_size_t* decoded)
2115 {
2116 char utf8_buffer[16];
2117 gate_size_t bytes_returned = 0;
2118 gate_size_t bytes_decoded = 0;
2119 gate_result_t ret = GATE_RESULT_FAILED;
2120
2121 ret = gate_stream_peek(stream, utf8_buffer, sizeof(utf8_buffer), &bytes_returned);
2122 if (GATE_SUCCEEDED(ret))
2123 {
2124 if (bytes_returned == 0)
2125 {
2126 /* end of stream reached */
2127 *chr = 0;
2128 *decoded = 0;
2129 }
2130 else
2131 {
2132 bytes_decoded = gate_char_read_utf8(utf8_buffer, bytes_returned, chr);
2133 if (bytes_decoded == 0)
2134 {
2135 /* utf8 error, return byte value instead */
2136 *chr = (gate_char32_t)(gate_uint8_t)utf8_buffer[0];
2137 *decoded = 1;
2138 }
2139 else
2140 {
2141 *decoded = bytes_decoded;
2142 }
2143 }
2144 }
2145 return ret;
2146 }
2147
2148 gate_size_t gate_stream_scan_char32(gate_stream_t* stream, gate_char32_t* chr)
2149 {
2150 /* TODO */
2151 return 0;
2152 }
2153 gate_size_t gate_stream_scan_char16(gate_stream_t* stream, gate_char16_t* chr)
2154 {
2155 /* TODO */
2156 return 0;
2157 }
2158 gate_size_t gate_stream_scan_char8(gate_stream_t* stream, gate_char8_t* chr)
2159 {
2160 /* TODO */
2161 return 0;
2162 }
2163
2164
2165 gate_size_t gate_stream_scan_int(gate_stream_t* stream, gate_int32_t* num)
2166 {
2167 /* TODO */
2168 return 0;
2169 }
2170 gate_size_t gate_stream_scan_uint(gate_stream_t* stream, gate_uint32_t* num)
2171 {
2172 /* TODO */
2173 return 0;
2174 }
2175 gate_size_t gate_stream_scan_int64(gate_stream_t* stream, gate_int64_t* num)
2176 {
2177 /* TODO */
2178 return 0;
2179 }
2180 gate_size_t gate_stream_scan_uint64(gate_stream_t* stream, gate_uint64_t* num)
2181 {
2182 /* TODO */
2183 return 0;
2184 }
2185 gate_size_t gate_stream_scan_real(gate_stream_t* stream, gate_real64_t* num)
2186 {
2187 /* TODO */
2188 return 0;
2189 }
2190 gate_size_t gate_stream_scan_string(gate_stream_t* stream, gate_string_t* text)
2191 {
2192 /* TODO */
2193 return 0;
2194 }
2195
2196
2197
2198
2199 39922 gate_result_t gate_stream_transfer_buffer(gate_stream_t* src, gate_stream_t* dst, char* buffer, gate_size_t buffersize)
2200 {
2201 gate_size_t bytes_read;
2202 gate_size_t bytes_written;
2203 gate_result_t result;
2204 for (;;)
2205 {
2206 39922 result = gate_stream_read(src, buffer, buffersize, &bytes_read);
2207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39922 times.
39922 if (GATE_FAILED(result))
2208 {
2209 break;
2210 }
2211
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 39894 times.
39922 if (bytes_read == 0)
2212 {
2213 /* end of stream reached */
2214 28 break;
2215 }
2216 39894 result = gate_stream_write_block(dst, buffer, bytes_read, &bytes_written);
2217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39894 times.
39894 if (GATE_FAILED(result))
2218 {
2219 break;
2220 }
2221 }
2222 28 return result;
2223 }
2224
2225 5 gate_result_t gate_stream_transfer_limit(gate_stream_t* src, gate_uint64_t limit, gate_stream_t* dst, gate_uint64_t* transferred)
2226 {
2227 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
2228 static gate_size_t const buffer_size = sizeof(buffer);
2229 gate_size_t next_size;
2230 gate_size_t bytes_read;
2231 gate_size_t bytes_written;
2232 5 gate_result_t result = GATE_RESULT_OK;
2233 5 gate_uint64_t counter = 0;
2234
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 while (limit > 0)
2235 {
2236 5 next_size = (limit > buffer_size) ? buffer_size : (gate_size_t)limit;
2237 5 result = gate_stream_read(src, buffer, next_size, &bytes_read);
2238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
2239 {
2240 break;
2241 }
2242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (bytes_read == 0)
2243 {
2244 /* end of stream reached */
2245 break;
2246 }
2247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_DEBUG_ASSERT(limit >= bytes_read);
2248 5 limit -= bytes_read;
2249 5 result = gate_stream_write_block(dst, buffer, bytes_read, &bytes_written);
2250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
2251 {
2252 break;
2253 }
2254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_DEBUG_ASSERT(bytes_read == bytes_written);
2255 5 counter += bytes_written;
2256 }
2257
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (transferred)
2258 {
2259 5 *transferred = counter;
2260 }
2261 5 return result;
2262 }
2263
2264
2265 19 gate_result_t gate_stream_transfer(gate_stream_t* src, gate_stream_t* dst)
2266 {
2267 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
2268 19 return gate_stream_transfer_buffer(src, dst, buffer, sizeof(buffer));
2269 }
2270
2271 5 gate_result_t gate_stream_skip(gate_stream_t* src, gate_uint64_t count, gate_uint64_t* bytes_skipped)
2272 {
2273 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
2274 gate_size_t nextlen;
2275 5 gate_size_t returned = 1;
2276 5 gate_result_t result = GATE_RESULT_OK;
2277 5 gate_uint64_t actual_skipped = 0;
2278
2279
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 while ((count != 0) && (returned != 0))
2280 {
2281 5 nextlen = (count > GATE_MAX_COPYBUFFER_LENGTH) ? GATE_MAX_COPYBUFFER_LENGTH : (gate_size_t)count;
2282 5 result = gate_stream_read_block(src, buffer, nextlen, &returned);
2283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_BREAK_IF_FAILED(result);
2284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_DEBUG_ASSERT(returned <= nextlen);
2285 5 actual_skipped += returned;
2286 5 count -= returned;
2287 }
2288
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (bytes_skipped)
2289 {
2290 2 *bytes_skipped = actual_skipped;
2291 }
2292 5 return result;
2293 }
2294
2295