GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/array_extensions.c
Date: 2024-11-05 17:11:09
Exec Total Coverage
Lines: 422 436 96.8%
Functions: 28 28 100.0%
Branches: 133 189 70.4%

Line Branch Exec Source
1 /*
2 Copyright 2022, 2023, 2024 Joel Svensson svenssonjoel@yahoo.se
3 Copyright 2022, 2023 Benjamin Vedder
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "extensions/array_extensions.h"
20
21 #include "extensions.h"
22 #include "symrepr.h"
23 #include "lbm_memory.h"
24
25 #include <math.h>
26
27 static lbm_uint little_endian = 0;
28 static lbm_uint big_endian = 0;
29
30 static lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn);
31 static lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn);
32 static lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn);
33 static lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn);
34 static lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn);
35 static lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn);
36 static lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn);
37 static lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn);
38 static lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn);
39
40 static lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn);
41 static lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn);
42 static lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn);
43 static lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn);
44 static lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn);
45 static lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn);
46 static lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn);
47 static lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn);
48
49 static lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn);
50
51 static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn);
52 static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn);
53 static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn);
54
55 21504 void lbm_array_extensions_init(void) {
56
57 21504 lbm_add_symbol_const("little-endian", &little_endian);
58 21504 lbm_add_symbol_const("big-endian", &big_endian);
59
60 21504 lbm_add_extension("free", array_extension_unsafe_free_array);
61 21504 lbm_add_extension("bufset-i8", array_extension_buffer_append_i8);
62 21504 lbm_add_extension("bufset-i16", array_extension_buffer_append_i16);
63 21504 lbm_add_extension("bufset-i32", array_extension_buffer_append_i32);
64 21504 lbm_add_extension("bufset-u8", array_extension_buffer_append_u8);
65 21504 lbm_add_extension("bufset-u16", array_extension_buffer_append_u16);
66 21504 lbm_add_extension("bufset-u24", array_extension_buffer_append_u24);
67 21504 lbm_add_extension("bufset-u32", array_extension_buffer_append_u32);
68 21504 lbm_add_extension("bufset-f32", array_extension_buffer_append_f32);
69
70 21504 lbm_add_extension("bufget-i8", array_extension_buffer_get_i8);
71 21504 lbm_add_extension("bufget-i16", array_extension_buffer_get_i16);
72 21504 lbm_add_extension("bufget-i32", array_extension_buffer_get_i32);
73 21504 lbm_add_extension("bufget-u8", array_extension_buffer_get_u8);
74 21504 lbm_add_extension("bufget-u16", array_extension_buffer_get_u16);
75 21504 lbm_add_extension("bufget-u24", array_extension_buffer_get_u24);
76 21504 lbm_add_extension("bufget-u32", array_extension_buffer_get_u32);
77 21504 lbm_add_extension("bufget-f32", array_extension_buffer_get_f32);
78
79 21504 lbm_add_extension("buflen", array_extension_buffer_length);
80 21504 lbm_add_extension("bufclear", array_extensions_bufclear);
81 21504 lbm_add_extension("bufcpy", array_extensions_bufcpy);
82 21504 lbm_add_extension("bufset-bit", array_extensions_bufset_bit);
83 21504 }
84
85 112 lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn) {
86 112 lbm_value res = ENC_SYM_EERROR;
87
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (argn == 1) {
88
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 if (lbm_is_array_rw(args[0])) {
89
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 if (lbm_heap_explicit_free_array(args[0])) {
90 112 res = ENC_SYM_TRUE;
91 } else {
92 res = ENC_SYM_NIL;
93 }
94 } else {
95 res = ENC_SYM_TERROR;
96 }
97 }
98 112 return res;
99 }
100
101 3528 static bool decode_append_args(lbm_value *error, lbm_value *args, lbm_uint argn, lbm_uint *index, bool *be, lbm_uint *a_size, uint8_t **a_data) {
102 3528 *be = true;
103 3528 *error = ENC_SYM_EERROR;
104 3528 bool res = false;
105
2/3
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 2548 times.
✗ Branch 2 not taken.
3528 switch(argn) {
106 980 case 4:
107
1/2
✓ Branch 1 taken 980 times.
✗ Branch 2 not taken.
980 if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL &&
108
1/2
✓ Branch 1 taken 980 times.
✗ Branch 2 not taken.
980 lbm_dec_sym(args[3]) == little_endian) {
109 980 *be = false;
110 }
111 /* fall through */
112 case 3:
113
3/4
✓ Branch 1 taken 3444 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 3444 times.
✗ Branch 4 not taken.
6972 if(lbm_is_array_rw(args[0]) &&
114
1/2
✓ Branch 1 taken 3444 times.
✗ Branch 2 not taken.
6888 lbm_is_number(args[1]) &&
115 3444 lbm_is_number(args[2])) {
116 3444 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
117
118 3444 *a_size = array->size;
119 3444 *a_data = (uint8_t*)array->data;
120 3444 *index = lbm_dec_as_u32(args[1]);
121
122 3444 res = true;
123 } else {
124 84 *error = ENC_SYM_TERROR;
125 }
126 }
127 3528 return res;
128 }
129
130 3444 static bool buffer_append_bytes(uint8_t *data, lbm_uint d_size, bool be, lbm_uint index, lbm_uint nbytes, lbm_uint value) {
131
132 3444 lbm_uint last_index = index + (nbytes - 1);
133 3444 bool res = false;
134
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 3220 times.
3444 if (last_index < d_size) {
135 3220 res = true;
136
4/4
✓ Branch 0 taken 1288 times.
✓ Branch 1 taken 644 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 1008 times.
3220 switch(nbytes) {
137 1288 case 1:
138 1288 data[index] = (uint8_t) value;
139 1288 break;
140 644 case 2:
141
2/2
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 280 times.
644 if (be) {
142 364 data[index+1] = (uint8_t)value;
143 364 data[index] = (uint8_t)(value >> 8);
144 } else {
145 280 data[index] = (uint8_t)value;
146 280 data[index +1] = (uint8_t)(value >> 8);
147 }
148 644 break;
149 280 case 3:
150
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 140 times.
280 if (be) {
151 140 data[index+2] = (uint8_t)value;
152 140 data[index+1] = (uint8_t)(value >> 8);
153 140 data[index] = (uint8_t)(value >> 16);
154 } else {
155 140 data[index] = (uint8_t)value;
156 140 data[index+1] = (uint8_t)(value >> 8);
157 140 data[index+2] = (uint8_t)(value >> 16);
158 }
159 280 break;
160 1008 default:
161
2/2
✓ Branch 0 taken 728 times.
✓ Branch 1 taken 280 times.
1008 if (be) {
162 728 data[index+3] = (uint8_t) value;
163 728 data[index+2] = (uint8_t) (value >> 8);
164 728 data[index+1] = (uint8_t) (value >> 16);
165 728 data[index] = (uint8_t) (value >> 24);
166 } else {
167 280 data[index] = (uint8_t) value;
168 280 data[index+1] = (uint8_t) (value >> 8);
169 280 data[index+2] = (uint8_t) (value >> 16);
170 280 data[index+3] = (uint8_t) (value >> 24);
171 }
172 1008 break;
173 }
174 224 }
175 3444 return res;
176 }
177
178 756 lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn) {
179
180 756 lbm_value res = ENC_SYM_EERROR;
181 756 uint8_t *data = NULL;
182 756 lbm_uint d_size = 0;
183 756 bool be = false;
184 756 lbm_uint index = 0;
185 756 lbm_uint nbytes = 1;
186
187
2/2
✓ Branch 1 taken 672 times.
✓ Branch 2 taken 84 times.
756 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
188
2/2
✓ Branch 2 taken 644 times.
✓ Branch 3 taken 28 times.
672 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_i32(args[2]))) {
189 644 res = ENC_SYM_TRUE;
190 }
191 }
192 756 return res;
193 }
194
195 588 lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn) {
196
197 588 lbm_value res = ENC_SYM_EERROR;
198 588 uint8_t *data = NULL;
199 588 lbm_uint d_size = 0;
200 588 bool be = false;
201 588 lbm_uint index = 0;
202 588 lbm_uint nbytes = 2;
203
204
1/2
✓ Branch 1 taken 588 times.
✗ Branch 2 not taken.
588 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
205
2/2
✓ Branch 2 taken 560 times.
✓ Branch 3 taken 28 times.
588 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_i32(args[2]))) {
206 560 res = ENC_SYM_TRUE;
207 }
208 }
209 588 return res;
210 }
211
212 448 lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn) {
213
214 448 lbm_value res = ENC_SYM_EERROR;
215 448 uint8_t *data = NULL;
216 448 lbm_uint d_size = 0;
217 448 bool be = false;
218 448 lbm_uint index = 0;
219 448 lbm_uint nbytes = 4;
220
221
1/2
✓ Branch 1 taken 448 times.
✗ Branch 2 not taken.
448 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
222
2/2
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 28 times.
448 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_i32(args[2]))) {
223 420 res = ENC_SYM_TRUE;
224 }
225 }
226 448 return res;
227 }
228
229
230 672 lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn) {
231
232 672 lbm_value res = ENC_SYM_EERROR;
233 672 uint8_t *data = NULL;
234 672 lbm_uint d_size = 0;
235 672 bool be = false;
236 672 lbm_uint index = 0;
237 672 lbm_uint nbytes = 1;
238
239
1/2
✓ Branch 1 taken 672 times.
✗ Branch 2 not taken.
672 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
240
2/2
✓ Branch 2 taken 644 times.
✓ Branch 3 taken 28 times.
672 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_u32(args[2]))) {
241 644 res = ENC_SYM_TRUE;
242 }
243 }
244 672 return res;
245 }
246
247 112 lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn) {
248
249 112 lbm_value res = ENC_SYM_EERROR;
250 112 uint8_t *data = NULL;
251 112 lbm_uint d_size = 0;
252 112 bool be = false;
253 112 lbm_uint index = 0;
254 112 lbm_uint nbytes = 2;
255
256
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
257
2/2
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 28 times.
112 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_u32(args[2]))) {
258 84 res = ENC_SYM_TRUE;
259 }
260 }
261 112 return res;
262 }
263
264 308 lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn) {
265
266 308 lbm_value res = ENC_SYM_EERROR;
267 308 uint8_t *data = NULL;
268 308 lbm_uint d_size = 0;
269 308 bool be = false;
270 308 lbm_uint index = 0;
271 308 lbm_uint nbytes = 3;
272
273
1/2
✓ Branch 1 taken 308 times.
✗ Branch 2 not taken.
308 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
274
2/2
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 28 times.
308 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_u32(args[2]))) {
275 280 res = ENC_SYM_TRUE;
276 }
277 }
278 308 return res;
279 }
280
281 448 lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn) {
282
283 448 lbm_value res = ENC_SYM_EERROR;
284 448 uint8_t *data = NULL;
285 448 lbm_uint d_size = 0;
286 448 bool be = false;
287 448 lbm_uint index = 0;
288 448 lbm_uint nbytes = 4;
289
290
1/2
✓ Branch 1 taken 448 times.
✗ Branch 2 not taken.
448 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
291
2/2
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 28 times.
448 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)lbm_dec_as_u32(args[2]))) {
292 420 res = ENC_SYM_TRUE;
293 }
294 }
295 448 return res;
296 }
297
298 196 static lbm_uint float_to_u(float number) {
299 // Set subnormal numbers to 0 as they are not handled properly
300 // using this method.
301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
196 if (fabsf(number) < 1.5e-38) {
302 number = 0.0;
303 }
304
305 196 int e = 0;
306 196 float sig = frexpf(number, &e);
307 196 float sig_abs = fabsf(sig);
308 196 uint32_t sig_i = 0;
309
310
1/2
✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
196 if (sig_abs >= 0.5) {
311 196 sig_i = (uint32_t)((sig_abs - 0.5f) * 2.0f * 8388608.0f);
312 196 e += 126;
313 }
314
315 196 uint32_t res = (((uint32_t)e & 0xFFu) << 23) | (uint32_t)(sig_i & 0x7FFFFFu);
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
196 if (sig < 0) {
317 res |= 1U << 31;
318 }
319
320 196 return res;
321 }
322
323 168 static lbm_float u_to_float(uint32_t v) {
324
325 168 int e = (v >> 23) & 0xFF;
326 168 uint32_t sig_i = v & 0x7FFFFF;
327 168 bool neg = v & (1U << 31);
328
329 168 float sig = 0.0;
330
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
168 if (e != 0 || sig_i != 0) {
331 168 sig = (float)sig_i / (8388608.0f * 2.0f) + 0.5f;
332 168 e -= 126;
333 }
334
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (neg) {
336 sig = -sig;
337 }
338
339 168 return ldexpf(sig, e);
340 }
341
342 196 lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn) {
343
344 196 lbm_value res = ENC_SYM_EERROR;
345 196 uint8_t *data = NULL;
346 196 lbm_uint d_size = 0;
347 196 bool be = false;
348 196 lbm_uint index = 0;
349 196 lbm_uint nbytes = 4;
350
351
1/2
✓ Branch 1 taken 196 times.
✗ Branch 2 not taken.
196 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
352
2/2
✓ Branch 3 taken 168 times.
✓ Branch 4 taken 28 times.
196 if (buffer_append_bytes(data, d_size, be, index, nbytes, (lbm_uint)float_to_u(lbm_dec_as_float(args[2])))) {
353 168 res = ENC_SYM_TRUE;
354 }
355 }
356 196 return res;
357 }
358
359 /* (buffer-get-i8 buffer index) */
360 /* (buffer-get-i16 buffer index little-endian) */
361
362 4900 static bool decode_get_args(lbm_value *error, lbm_value *args, lbm_uint argn, lbm_uint *index, bool *be, lbm_uint *a_size, uint8_t **a_data) {
363 4900 bool res = false;
364
365 4900 *be=true;
366
367
2/3
✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 3724 times.
✗ Branch 2 not taken.
4900 switch(argn) {
368 1176 case 3:
369
1/2
✓ Branch 1 taken 1176 times.
✗ Branch 2 not taken.
1176 if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL &&
370
1/2
✓ Branch 1 taken 1176 times.
✗ Branch 2 not taken.
1176 lbm_dec_sym(args[2]) == little_endian) {
371 1176 *be = false;
372 }
373 /* fall through */
374 case 2:
375
2/4
✓ Branch 1 taken 4900 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4900 times.
✗ Branch 4 not taken.
9800 if (lbm_is_array_r(args[0]) &&
376 4900 lbm_is_number(args[1])) {
377 4900 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
378 4900 *a_size = array->size;
379 4900 *a_data = (uint8_t*)array->data;
380 4900 *index = lbm_dec_as_u32(args[1]);
381 4900 res = true;
382 } else {
383 *error = ENC_SYM_TERROR;
384 }
385 }
386 4900 return res;
387 }
388
389 4900 static bool buffer_get_uint(lbm_uint *r_value, uint8_t *data, lbm_uint d_size, bool be, lbm_uint index, lbm_uint nbytes) {
390
391 4900 bool res = false;
392 4900 lbm_uint value = 0;
393 4900 lbm_uint last_index = index + (nbytes - 1);
394
395
2/2
✓ Branch 0 taken 4284 times.
✓ Branch 1 taken 616 times.
4900 if (last_index < d_size) {
396 4284 res = true;
397
4/5
✓ Branch 0 taken 2268 times.
✓ Branch 1 taken 644 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 1092 times.
✗ Branch 4 not taken.
4284 switch(nbytes) {
398 2268 case 1:
399 2268 value = (lbm_uint)data[index];
400 2268 break;
401 644 case 2:
402
2/2
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 280 times.
644 if (be) {
403 364 value =
404 364 (lbm_uint) data[index+1] |
405 364 (lbm_uint) data[index] << 8;
406 } else {
407 280 value =
408 280 (lbm_uint) data[index] |
409 280 (lbm_uint) data[index+1] << 8;
410 }
411 644 break;
412 280 case 3:
413
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 140 times.
280 if (be) {
414 140 value =
415 140 (lbm_uint) data[index+2] |
416 140 (lbm_uint) data[index+1] << 8 |
417 140 (lbm_uint) data[index] << 16;
418 } else {
419 140 value =
420 140 (lbm_uint) data[index] |
421 140 (lbm_uint) data[index+1] << 8 |
422 140 (lbm_uint) data[index+2] << 16;
423 }
424 280 break;
425 1092 case 4:
426
2/2
✓ Branch 0 taken 812 times.
✓ Branch 1 taken 280 times.
1092 if (be) {
427 812 value =
428 812 (uint32_t) data[index+3] |
429 812 (uint32_t) data[index+2] << 8 |
430 812 (uint32_t) data[index+1] << 16 |
431 812 (uint32_t) data[index] << 24;
432 } else {
433 280 value =
434 280 (uint32_t) data[index] |
435 280 (uint32_t) data[index+1] << 8 |
436 280 (uint32_t) data[index+2] << 16 |
437 280 (uint32_t) data[index+3] << 24;
438 }
439 1092 break;
440 default:
441 res = false;
442 }
443 4284 *r_value = value;
444 }
445 4900 return res;
446 }
447
448
449
450 1344 lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn) {
451 1344 lbm_value res = ENC_SYM_EERROR;
452 1344 uint8_t *data = NULL;
453 1344 lbm_uint d_size = 0;
454 1344 bool be = false;
455 1344 lbm_uint index = 0;
456 1344 lbm_uint nbytes = 1;
457 1344 lbm_uint value = 0;
458
459
1/2
✓ Branch 1 taken 1344 times.
✗ Branch 2 not taken.
1344 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
460
2/2
✓ Branch 1 taken 1260 times.
✓ Branch 2 taken 84 times.
1344 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
461 1260 res =lbm_enc_i((int8_t)value);
462 }
463 }
464 1344 return res;
465 }
466
467 700 lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn) {
468 700 lbm_value res = ENC_SYM_EERROR;
469 700 uint8_t *data = NULL;
470 700 lbm_uint d_size = 0;
471 700 bool be = false;
472 700 lbm_uint index = 0;
473 700 lbm_uint nbytes = 2;
474 700 lbm_uint value = 0;
475
476
1/2
✓ Branch 1 taken 700 times.
✗ Branch 2 not taken.
700 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
477
2/2
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 140 times.
700 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
478 560 res =lbm_enc_i((int16_t)value);
479 }
480 }
481 700 return res;
482 }
483
484 504 lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn) {
485 504 lbm_value res = ENC_SYM_EERROR;
486 504 uint8_t *data = NULL;
487 504 lbm_uint d_size = 0;
488 504 bool be = false;
489 504 lbm_uint index = 0;
490 504 lbm_uint nbytes = 4;
491 504 lbm_uint value = 0;
492
493
1/2
✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
504 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
494
2/2
✓ Branch 1 taken 420 times.
✓ Branch 2 taken 84 times.
504 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
495 420 res =lbm_enc_i((int32_t)value);
496 }
497 }
498 504 return res;
499 }
500
501 1092 lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn) {
502 1092 lbm_value res = ENC_SYM_EERROR;
503 1092 uint8_t *data = NULL;
504 1092 lbm_uint d_size = 0;
505 1092 bool be = false;
506 1092 lbm_uint index = 0;
507 1092 lbm_uint nbytes = 1;
508 1092 lbm_uint value = 0;
509
510
1/2
✓ Branch 1 taken 1092 times.
✗ Branch 2 not taken.
1092 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
511
2/2
✓ Branch 1 taken 1008 times.
✓ Branch 2 taken 84 times.
1092 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
512 1008 res = lbm_enc_i((uint8_t)value);
513 }
514 }
515 1092 return res;
516 }
517
518 112 lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn) {
519 112 lbm_value res = ENC_SYM_EERROR;
520 112 uint8_t *data = NULL;
521 112 lbm_uint d_size = 0;
522 112 bool be = false;
523 112 lbm_uint index = 0;
524 112 lbm_uint nbytes = 2;
525 112 lbm_uint value = 0;
526
527
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
528
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 28 times.
112 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
529 84 res = lbm_enc_i((uint16_t)value);
530 }
531 }
532 112 return res;
533 }
534
535 364 lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn) {
536 364 lbm_value res = ENC_SYM_EERROR;
537 364 uint8_t *data = NULL;
538 364 lbm_uint d_size = 0;
539 364 bool be = false;
540 364 lbm_uint index = 0;
541 364 lbm_uint nbytes = 3;
542 364 lbm_uint value = 0;
543
544
1/2
✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
364 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
545
2/2
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 84 times.
364 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
546 280 res = lbm_enc_i((int32_t)value);
547 }
548 }
549 364 return res;
550 }
551
552 588 lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn) {
553 588 lbm_value res = ENC_SYM_EERROR;
554 588 uint8_t *data = NULL;
555 588 lbm_uint d_size = 0;
556 588 bool be = false;
557 588 lbm_uint index = 0;
558 588 lbm_uint nbytes = 4;
559 588 lbm_uint value = 0;
560
561
1/2
✓ Branch 1 taken 588 times.
✗ Branch 2 not taken.
588 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
562
2/2
✓ Branch 1 taken 504 times.
✓ Branch 2 taken 84 times.
588 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
563 504 res = lbm_enc_u32((uint32_t)value);
564 }
565 }
566 588 return res;
567 }
568
569 196 lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn) {
570 196 lbm_value res = ENC_SYM_EERROR;
571 196 uint8_t *data = NULL;
572 196 lbm_uint d_size = 0;
573 196 bool be = false;
574 196 lbm_uint index = 0;
575 196 lbm_uint nbytes = 4;
576 196 lbm_uint value = 0;
577
578
1/2
✓ Branch 1 taken 196 times.
✗ Branch 2 not taken.
196 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
579
2/2
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 28 times.
196 if (buffer_get_uint(&value, data, d_size, be, index, nbytes)) {
580 168 res = lbm_enc_float(u_to_float((uint32_t)value));
581 }
582 }
583 196 return res;
584 }
585
586 252 lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn) {
587 252 lbm_value res = ENC_SYM_EERROR;
588
2/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 252 times.
✗ Branch 3 not taken.
504 if (argn == 1 &&
589
1/2
✓ Branch 1 taken 252 times.
✗ Branch 2 not taken.
504 lbm_is_array_r(args[0]) &&
590 252 lbm_heap_array_valid(args[0])) {
591 252 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
592 252 res = lbm_enc_i((lbm_int)array->size);
593 }
594 252 return res;
595 }
596
597 //TODO: Have to think about 32 vs 64 bit here
598 560 static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn) {
599 560 lbm_value res = ENC_SYM_EERROR;
600
4/4
✓ Branch 0 taken 532 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 504 times.
✓ Branch 3 taken 28 times.
560 if (argn >= 1 && argn <= 4) {
601 504 res = ENC_SYM_TERROR;
602
1/2
✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
504 if (lbm_is_array_rw(args[0])) {
603 504 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
604
605 504 uint8_t clear_byte = 0;
606
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 84 times.
504 if (argn >= 2) {
607
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 420 times.
420 if (!lbm_is_number(args[1])) {
608 return res;
609 }
610 420 clear_byte = (uint8_t)lbm_dec_as_u32(args[1]);
611 }
612
613 504 uint32_t start = 0;
614
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 448 times.
504 if (argn >= 3) {
615
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
56 if (!lbm_is_number(args[2])) {
616 return res;
617 }
618 56 uint32_t start_new = lbm_dec_as_u32(args[2]);
619
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (start_new < array->size) {
620 56 start = start_new;
621 } else {
622 return res;
623 }
624 }
625 // Truncates size on 64 bit build
626 504 uint32_t len = (uint32_t)array->size - start;
627
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 476 times.
504 if (argn >= 4) {
628
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (!lbm_is_number(args[3])) {
629 return res;
630 }
631 28 uint32_t len_new = lbm_dec_as_u32(args[3]);
632
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (len_new <= len) {
633 28 len = len_new;
634 }
635 }
636
637 504 memset((char*)array->data + start, clear_byte, len);
638 504 res = ENC_SYM_TRUE;
639 }
640 }
641 560 return res;
642 }
643
644 140 static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn) {
645 140 lbm_value res = ENC_SYM_EERROR;
646
647
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 28 times.
140 if (argn == 5) {
648 112 res = ENC_SYM_TERROR;
649
4/6
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56 times.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 56 times.
✗ Branch 7 not taken.
168 if (lbm_is_array_rw(args[0]) && lbm_is_number(args[1]) &&
650
2/4
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 56 times.
✗ Branch 6 not taken.
112 lbm_is_array_r(args[2]) && lbm_is_number(args[3]) &&lbm_is_number(args[4])) {
651 56 lbm_array_header_t *array1 = (lbm_array_header_t *)lbm_car(args[0]);
652
653 56 uint32_t start1 = lbm_dec_as_u32(args[1]);
654
655 56 lbm_array_header_t *array2 = (lbm_array_header_t *)lbm_car(args[2]);
656
657 56 uint32_t start2 = lbm_dec_as_u32(args[3]);
658 56 uint32_t len = lbm_dec_as_u32(args[4]);
659
660
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
56 if (start1 < array1->size && start2 < array2->size) {
661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (len > (array1->size - start1)) {
662 len = ((uint32_t)array1->size - start1);
663 }
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (len > (array2->size - start2)) {
665 len = ((uint32_t)array2->size - start2);
666 }
667
668 56 memcpy((char*)array1->data + start1, (char*)array2->data + start2, len);
669 }
670 56 res = ENC_SYM_TRUE;
671 }
672 }
673 140 return res;
674 }
675
676 168 static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn) {
677 168 lbm_value res = ENC_SYM_EERROR;
678
679
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 84 times.
168 if (argn == 3) {
680 84 res = ENC_SYM_TERROR;
681
3/4
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
140 if (lbm_is_array_rw(args[0]) &&
682
1/2
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
112 lbm_is_number(args[1]) && lbm_is_number(args[2])) {
683 56 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
684
685 56 unsigned int pos = lbm_dec_as_u32(args[1]);
686 56 unsigned int bit = lbm_dec_as_u32(args[2]) ? 1 : 0;
687
688 56 unsigned int bytepos = pos / 8;
689 56 unsigned int bitpos = pos % 8;
690
691
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (bytepos < array->size) {
692 56 ((uint8_t*)array->data)[bytepos] &= (uint8_t)~(1 << bitpos);
693 56 ((uint8_t*)array->data)[bytepos] |= (uint8_t)(bit << bitpos);
694 }
695
696 56 res = ENC_SYM_TRUE;
697 }
698 }
699 168 return res;
700 }
701