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 |