GCC Code Coverage Report


Directory: src/gate/
File: src/gate/blobs.c
Date: 2025-12-12 23:40:09
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 70 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 66 times.
70 if (length == 0)
38 {
39 4 return gate_blob_create_empty(blob);
40 }
41
42 66 ptr_buffer = gate_mem_alloc(sizeof(gate_blobbuffer_t) + length);
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (ptr_buffer == NULL)
44 {
45 return NULL;
46 }
47 66 gate_atomic_int_set(&ptr_buffer->refcount, 1);
48
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 if (data)
49 {
50 66 gate_mem_copy(&ptr_buffer->data[0], data, length);
51 }
52 66 blob->data = &ptr_buffer->data[0];
53 66 blob->length = length;
54 66 blob->buffer = ptr_buffer;
55 66 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 154 gate_blob_t* gate_blob_create_empty(gate_blob_t* blob)
65 {
66 154 blob->data = NULL;
67 154 blob->length = 0;
68 154 blob->buffer = NULL;
69 154 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 17 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 17 times.
17 if (!srcblob)
108 {
109 return gate_blob_create_empty(blob);
110 }
111 else
112 {
113 17 blob->data = srcblob->data;
114 17 blob->length = srcblob->length;
115 17 blob->buffer = srcblob->buffer;
116
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
17 if (blob->buffer)
117 {
118 9 gate_atomic_int_inc(&blob->buffer->refcount);
119 }
120 17 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 132 void gate_blob_release(gate_blob_t* blob)
149 {
150
1/2
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
132 if (blob)
151 {
152
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 54 times.
132 if (blob->buffer)
153 {
154
2/2
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 12 times.
78 if (gate_atomic_int_dec(&blob->buffer->refcount) == 0)
155 {
156 66 gate_mem_dealloc(blob->buffer);
157 }
158 }
159 132 gate_blob_create_empty(blob);
160 }
161 132 }
162
163 129 gate_size_t gate_blob_length(gate_blob_t const* blob)
164 {
165 129 gate_size_t ret = 0;
166
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
129 if (blob)
167 {
168 129 ret = blob->length;
169 }
170 129 return ret;
171 }
172 56 void const* gate_blob_data(gate_blob_t const* blob)
173 {
174 56 void const* data = NULL;
175
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (blob)
176 {
177 56 data = blob->data;
178 }
179 56 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
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))
210 {
211 5 gate_uint8_t* data = (gate_uint8_t*)blob->buffer->data;
212
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (index < length)
213 {
214 4 data[index] = content;
215 4 ret = GATE_RESULT_OK;
216 }
217 else
218 {
219 1 ret = GATE_RESULT_OUTOFBOUNDS;
220 }
221 }
222 5 return ret;
223 }
224 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)
225 {
226 1 gate_size_t length = gate_blob_length(blob);
227 gate_uint8_t const* ptr_data;
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (index >= length)
229 {
230 return 0;
231 }
232
233 1 length -= index;
234
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (dest_length < length)
235 {
236 1 length = dest_length;
237 }
238 1 ptr_data = (gate_uint8_t const*)blob->data;
239 1 gate_mem_copy(ptr_dest, &ptr_data[index], length);
240 1 return length;
241 }
242 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)
243 {
244 1 gate_size_t length = gate_blob_length(blob);
245 gate_uint8_t* ptr_data;
246
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))
247 {
248 return 0;
249 }
250
251 1 length -= index;
252
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (src_length < length)
253 {
254 1 length = src_length;
255 }
256 1 ptr_data = &blob->buffer->data[0];
257 1 gate_mem_copy(&ptr_data[index], ptr_src, length);
258 1 return length;
259 }
260
261 1 gate_result_t gate_blob_copy_constructor(void* dest_mem, void const* src_mem)
262 {
263 1 gate_blob_t* dst = (gate_blob_t*)dest_mem;
264 1 gate_blob_t const* src = (gate_blob_t const*)src_mem;
265
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_blob_create_clone(dst, src))
266 {
267 return GATE_RESULT_OUTOFMEMORY;
268 }
269 else
270 {
271 1 return GATE_RESULT_OK;
272 }
273 }
274
275 1 gate_result_t gate_blob_duplicate_constructor(void* dest_mem, void const* src_mem)
276 {
277 1 gate_blob_t* dst = (gate_blob_t*)dest_mem;
278 1 gate_blob_t const* src = (gate_blob_t const*)src_mem;
279
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_blob_create_duplicate(dst, src))
280 {
281 return GATE_RESULT_OUTOFMEMORY;
282 }
283 else
284 {
285 1 return GATE_RESULT_OK;
286 }
287 }
288
289 1 void gate_blob_destructor(void* dest)
290 {
291 1 gate_blob_t* dst = (gate_blob_t*)dest;
292 1 gate_blob_release(dst);
293 1 }
294
295 /*****************************
296 * *
297 * BitField implementation *
298 * *
299 *****************************/
300
301 28 gate_bool_t gate_bit_is_set(void const* data, gate_size_t bitindex)
302 {
303 28 unsigned char const* ptr = (unsigned char const*)data;
304 28 gate_size_t byte_index = bitindex / 8;
305 28 gate_size_t bit_pos = bitindex % 8;
306 28 return (ptr[byte_index] & (1 << bit_pos)) == 0 ? false : true;
307 }
308 11 void gate_bit_set(void* data, gate_size_t bitindex)
309 {
310 11 unsigned char* ptr = (unsigned char*)data;
311 11 gate_size_t byte_index = bitindex / 8;
312 11 gate_size_t bit_pos = bitindex % 8;
313
314 11 ptr[byte_index] |= (unsigned char)(1 << bit_pos);
315 11 }
316 11 void gate_bit_clear(void* data, gate_size_t bitindex)
317 {
318 11 unsigned char* ptr = (unsigned char*)data;
319 11 gate_size_t byte_index = bitindex / 8;
320 11 gate_size_t bit_pos = bitindex % 8;
321
322 11 ptr[byte_index] &= ~(unsigned char)(1 << bit_pos);
323 11 }
324