GCC Code Coverage Report


Directory: src/gate/
File: src/gate/blobs.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 140 151 92.7%
Functions: 21 21 100.0%
Branches: 40 64 62.5%

Line Branch Exec Source
1
2 /* GATE PROJECT LICENSE:
3 +----------------------------------------------------------------------------+
4 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
5 | All rights reserved. |
6 | |
7 | Redistribution and use in source and binary forms, with or without |
8 | modification, are permitted provided that the following conditions are met:|
9 | |
10 | 1. Redistributions of source code must retain the above copyright notice, |
11 | this list of conditions and the following disclaimer. |
12 | 2. Redistributions in binary form must reproduce the above copyright |
13 | notice, this list of conditions and the following disclaimer in the |
14 | documentation and/or other materials provided with the distribution. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
26 | THE POSSIBILITY OF SUCH DAMAGE. |
27 +----------------------------------------------------------------------------+
28 */
29 #include "gate/blobs.h"
30 #include "gate/results.h"
31 #include "gate/memalloc.h"
32
33 44 gate_blob_t* gate_blob_create(gate_blob_t* blob, void const* data, gate_size_t length)
34 {
35 gate_blobbuffer_t* ptr_buffer;
36
37
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 40 times.
44 if (length == 0)
38 {
39 4 return gate_blob_create_empty(blob);
40 }
41
42 40 ptr_buffer = gate_mem_alloc(sizeof(gate_blobbuffer_t) + length);
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (ptr_buffer == NULL)
44 {
45 return NULL;
46 }
47 40 gate_atomic_int_set(&ptr_buffer->refcount, 1);
48
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 if (data)
49 {
50 40 gate_mem_copy(&ptr_buffer->data[0], data, length);
51 }
52 40 blob->data = &ptr_buffer->data[0];
53 40 blob->length = length;
54 40 blob->buffer = ptr_buffer;
55 40 return blob;
56 }
57 6 gate_blob_t* gate_blob_create_static(gate_blob_t* blob, void const* data, gate_size_t length)
58 {
59 6 blob->data = data;
60 6 blob->length = length;
61 6 blob->buffer = NULL;
62 6 return blob;
63 }
64 76 gate_blob_t* gate_blob_create_empty(gate_blob_t* blob)
65 {
66 76 blob->data = NULL;
67 76 blob->length = 0;
68 76 blob->buffer = NULL;
69 76 return blob;
70 }
71 2 gate_blob_t* gate_blob_create_copy(gate_blob_t* blob, gate_blob_t const* srcblob)
72 {
73 2 gate_size_t length = gate_blob_length(srcblob);
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (length == 0)
75 {
76 return gate_blob_create_empty(blob);
77 }
78 else
79 {
80 2 return gate_blob_create(blob, gate_blob_data(srcblob), length);
81 }
82 }
83 6 gate_blob_t* gate_blob_create_clone(gate_blob_t* blob, gate_blob_t const* srcblob)
84 {
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!srcblob)
86 {
87 return gate_blob_create_empty(blob);
88 }
89 else
90 {
91
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (srcblob->buffer)
92 {
93 3 blob->data = srcblob->data;
94 3 blob->length = srcblob->length;
95 3 blob->buffer = srcblob->buffer;
96 3 gate_atomic_int_inc(&blob->buffer->refcount);
97 3 return blob;
98 }
99 else
100 {
101 3 return gate_blob_create(blob, gate_blob_data(srcblob), gate_blob_length(srcblob));
102 }
103 }
104 }
105 11 gate_blob_t* gate_blob_create_duplicate(gate_blob_t* blob, gate_blob_t const* srcblob)
106 {
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!srcblob)
108 {
109 return gate_blob_create_empty(blob);
110 }
111 else
112 {
113 11 blob->data = srcblob->data;
114 11 blob->length = srcblob->length;
115 11 blob->buffer = srcblob->buffer;
116
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 if (blob->buffer)
117 {
118 3 gate_atomic_int_inc(&blob->buffer->refcount);
119 }
120 11 return blob;
121 }
122 }
123
124 2 gate_blob_t* gate_blob_create_subset(gate_blob_t* blob, gate_blob_t const* srcblob, gate_size_t offset, gate_size_t length)
125 {
126
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 if (!srcblob || (offset >= srcblob->length) || (length == 0))
127 {
128 return gate_blob_create_empty(blob);
129 }
130 else
131 {
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (offset + length > srcblob->length)
133 {
134 length = srcblob->length - offset;
135 }
136
137 2 blob->data = (void const*)((gate_uint8_t const*)srcblob->data + offset);
138 2 blob->length = length;
139 2 blob->buffer = srcblob->buffer;
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (blob->buffer)
141 {
142 gate_atomic_int_inc(&blob->buffer->refcount);
143 }
144 2 return blob;
145 }
146 }
147
148 59 void gate_blob_release(gate_blob_t* blob)
149 {
150
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if (blob)
151 {
152
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 23 times.
59 if (blob->buffer)
153 {
154
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 6 times.
36 if (gate_atomic_int_dec(&blob->buffer->refcount) == 0)
155 {
156 30 gate_mem_dealloc(blob->buffer);
157 }
158 }
159 59 gate_blob_create_empty(blob);
160 }
161 59 }
162
163 99 gate_size_t gate_blob_length(gate_blob_t const* blob)
164 {
165 99 gate_size_t ret = 0;
166
1/2
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
99 if (blob)
167 {
168 99 ret = blob->length;
169 }
170 99 return ret;
171 }
172 31 void const* gate_blob_data(gate_blob_t const* blob)
173 {
174 31 void const* data = NULL;
175
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (blob)
176 {
177 31 data = blob->data;
178 }
179 31 return data;
180 }
181 1 void* gate_blob_databuffer(gate_blob_t* blob)
182 {
183 1 void* data = NULL;
184
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (blob && blob->buffer)
185 {
186 1 data = &blob->buffer->data[0];
187 }
188 1 return data;
189 }
190 29 gate_uint8_t gate_blob_get_byte(gate_blob_t const* blob, gate_size_t index)
191 {
192 29 gate_uint8_t ret = 0;
193 29 gate_size_t const length = gate_blob_length(blob);
194 gate_uint8_t const* data;
195
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
29 if (length != 0)
196 {
197 28 data = (gate_uint8_t const*)blob->data;
198
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 if (index < length)
199 {
200 27 ret = data[index];
201 }
202 }
203 29 return ret;
204 }
205 5 gate_result_t gate_blob_set_byte(gate_blob_t* blob, gate_size_t index, gate_uint8_t content)
206 {
207 5 gate_result_t ret = GATE_RESULT_FAILED;
208 5 gate_size_t const length = gate_blob_length(blob);
209 gate_uint8_t* data;
210
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if ((length != 0) && (blob->buffer != NULL))
211 {
212 5 data = (gate_uint8_t*)blob->buffer->data;
213
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (index < length)
214 {
215 4 data[index] = content;
216 4 ret = GATE_RESULT_OK;
217 }
218 else
219 {
220 1 ret = GATE_RESULT_OUTOFBOUNDS;
221 }
222 }
223 5 return ret;
224 }
225 1 gate_size_t gate_blob_get_bytes(gate_blob_t const* blob, gate_size_t index, void* ptr_dest, gate_size_t dest_length)
226 {
227 1 gate_size_t length = gate_blob_length(blob);
228 gate_uint8_t const* ptr_data;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (index >= length)
230 {
231 return 0;
232 }
233
234 1 length -= index;
235
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (dest_length < length)
236 {
237 1 length = dest_length;
238 }
239 1 ptr_data = (gate_uint8_t const*)blob->data;
240 1 gate_mem_copy(ptr_dest, &ptr_data[index], length);
241 1 return length;
242 }
243 1 gate_size_t gate_blob_set_bytes(gate_blob_t* blob, gate_size_t index, void const* ptr_src, gate_size_t src_length)
244 {
245 1 gate_size_t length = gate_blob_length(blob);
246 gate_uint8_t* ptr_data;
247
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((index >= length) || (!blob->buffer))
248 {
249 return 0;
250 }
251
252 1 length -= index;
253
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (src_length < length)
254 {
255 1 length = src_length;
256 }
257 1 ptr_data = &blob->buffer->data[0];
258 1 gate_mem_copy(&ptr_data[index], ptr_src, length);
259 1 return length;
260 }
261
262 1 gate_result_t gate_blob_copy_constructor(void* dest_mem, void const* src_mem)
263 {
264 1 gate_blob_t* dst = (gate_blob_t*)dest_mem;
265 1 gate_blob_t const* src = (gate_blob_t const*)src_mem;
266
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_blob_create_clone(dst, src))
267 {
268 return GATE_RESULT_OUTOFMEMORY;
269 }
270 else
271 {
272 1 return GATE_RESULT_OK;
273 }
274 }
275
276 1 gate_result_t gate_blob_duplicate_constructor(void* dest_mem, void const* src_mem)
277 {
278 1 gate_blob_t* dst = (gate_blob_t*)dest_mem;
279 1 gate_blob_t const* src = (gate_blob_t const*)src_mem;
280
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_blob_create_duplicate(dst, src))
281 {
282 return GATE_RESULT_OUTOFMEMORY;
283 }
284 else
285 {
286 1 return GATE_RESULT_OK;
287 }
288 }
289
290 1 void gate_blob_destructor(void* dest)
291 {
292 1 gate_blob_t* dst = (gate_blob_t*)dest;
293 1 gate_blob_release(dst);
294 1 }
295
296 /*****************************
297 * *
298 * BitField implementation *
299 * *
300 *****************************/
301
302 28 gate_bool_t gate_bit_is_set(void const* data, gate_size_t bitindex)
303 {
304 28 unsigned char const* ptr = (unsigned char const*)data;
305 28 gate_size_t byte_index = bitindex / 8;
306 28 gate_size_t bit_pos = bitindex % 8;
307 28 return (ptr[byte_index] & (1 << bit_pos)) == 0 ? false : true;
308 }
309 11 void gate_bit_set(void* data, gate_size_t bitindex)
310 {
311 11 unsigned char* ptr = (unsigned char*)data;
312 11 gate_size_t byte_index = bitindex / 8;
313 11 gate_size_t bit_pos = bitindex % 8;
314
315 11 ptr[byte_index] |= (unsigned char)(1 << bit_pos);
316 11 }
317 11 void gate_bit_clear(void* data, gate_size_t bitindex)
318 {
319 11 unsigned char* ptr = (unsigned char*)data;
320 11 gate_size_t byte_index = bitindex / 8;
321 11 gate_size_t bit_pos = bitindex % 8;
322
323 11 ptr[byte_index] &= ~(unsigned char)(1 << bit_pos);
324 11 }
325