Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | Copyright 2022, 2023 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_i24(lbm_value *args, lbm_uint argn); | ||
34 | static lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn); | ||
35 | static lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn); | ||
36 | static lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn); | ||
37 | static lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn); | ||
38 | static lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn); | ||
39 | static lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn); | ||
40 | |||
41 | static lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn); | ||
42 | static lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn); | ||
43 | static lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn); | ||
44 | static lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn); | ||
45 | static lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn); | ||
46 | static lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn); | ||
47 | static lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn); | ||
48 | static lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn); | ||
49 | |||
50 | static lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn); | ||
51 | |||
52 | static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn); | ||
53 | static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn); | ||
54 | static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn); | ||
55 | |||
56 | 17444 | bool lbm_array_extensions_init(void) { | |
57 | |||
58 |
1/2✓ Branch 1 taken 17444 times.
✗ Branch 2 not taken.
|
17444 | if (!lbm_get_symbol_by_name("little-endian", &little_endian)) { |
59 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17444 times.
|
17444 | if (!lbm_add_symbol_const("little-endian", &little_endian)) { |
60 | ✗ | return false; | |
61 | } | ||
62 | } | ||
63 |
1/2✓ Branch 1 taken 17444 times.
✗ Branch 2 not taken.
|
17444 | if (!lbm_get_symbol_by_name("big-endian", &big_endian)) { |
64 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17444 times.
|
17444 | if (!lbm_add_symbol_const("big-endian", &big_endian)) { |
65 | ✗ | return false; | |
66 | } | ||
67 | } | ||
68 | 17444 | bool res = true; | |
69 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("free", array_extension_unsafe_free_array); |
70 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-i8", array_extension_buffer_append_i8); |
71 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-i16", array_extension_buffer_append_i16); |
72 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-i24", array_extension_buffer_append_i24); |
73 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-i32", array_extension_buffer_append_i32); |
74 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-u8", array_extension_buffer_append_u8); |
75 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-u16", array_extension_buffer_append_u16); |
76 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-u24", array_extension_buffer_append_u24); |
77 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-u32", array_extension_buffer_append_u32); |
78 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-f32", array_extension_buffer_append_f32); |
79 | |||
80 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-i8", array_extension_buffer_get_i8); |
81 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-i16", array_extension_buffer_get_i16); |
82 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-i32", array_extension_buffer_get_i32); |
83 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-u8", array_extension_buffer_get_u8); |
84 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-u16", array_extension_buffer_get_u16); |
85 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-u24", array_extension_buffer_get_u24); |
86 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-u32", array_extension_buffer_get_u32); |
87 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufget-f32", array_extension_buffer_get_f32); |
88 | |||
89 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("buflen", array_extension_buffer_length); |
90 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufclear", array_extensions_bufclear); |
91 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufcpy", array_extensions_bufcpy); |
92 |
2/4✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17444 times.
✗ Branch 4 not taken.
|
17444 | res = res && lbm_add_extension("bufset-bit", array_extensions_bufset_bit); |
93 | |||
94 | 17444 | return res; | |
95 | } | ||
96 | |||
97 | 28 | lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn) { | |
98 | |||
99 | 28 | lbm_value res = ENC_SYM_EERROR; | |
100 |
2/4✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
|
56 | if (argn != 1 || |
101 | 28 | lbm_type_of(args[0]) != LBM_TYPE_ARRAY) { | |
102 | ✗ | return res; | |
103 | } | ||
104 | 28 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
105 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | if (lbm_memory_ptr_inside(array->data)) { |
106 | 28 | lbm_memory_free((lbm_uint *)array->data); | |
107 | 28 | lbm_uint ptr = lbm_dec_ptr(args[0]); | |
108 | 28 | lbm_value cons_ptr = lbm_enc_cons_ptr(ptr); | |
109 | 28 | lbm_set_car(cons_ptr,ENC_SYM_NIL); | |
110 | 28 | lbm_set_cdr(cons_ptr,ENC_SYM_NIL); | |
111 | 28 | res = ENC_SYM_TRUE; | |
112 | } | ||
113 | 28 | lbm_memory_free((lbm_uint *)array); | |
114 | 28 | return res; | |
115 | } | ||
116 | |||
117 | 364 | lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn) { | |
118 | |||
119 | 364 | lbm_value res = ENC_SYM_EERROR; | |
120 | |||
121 |
1/2✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
|
364 | if (argn == 3) { |
122 |
1/2✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
|
364 | if(!lbm_is_array_rw(args[0]) || |
123 |
1/2✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
|
364 | !lbm_is_number(args[1]) || |
124 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 364 times.
|
364 | !lbm_is_number(args[2])) { |
125 | ✗ | return res; | |
126 | } | ||
127 | 364 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
128 | 364 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
129 | 364 | lbm_int value = lbm_dec_as_i32(args[2]); | |
130 | |||
131 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
|
364 | if (index >= array->size) { |
132 | ✗ | return res; | |
133 | } | ||
134 | |||
135 | 364 | uint8_t *data = (uint8_t*)array->data; | |
136 | 364 | data[index] = (uint8_t) value; | |
137 | 364 | res = ENC_SYM_TRUE; | |
138 | } | ||
139 | 364 | return res; | |
140 | } | ||
141 | |||
142 | ✗ | lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn) { | |
143 | |||
144 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
145 | ✗ | bool be = true; | |
146 | |||
147 | ✗ | switch(argn) { | |
148 | |||
149 | ✗ | case 4: | |
150 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
151 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
152 | ✗ | be = false; | |
153 | } | ||
154 | /* fall through */ | ||
155 | case 3: { | ||
156 | ✗ | if(!lbm_is_array_rw(args[0]) || | |
157 | ✗ | !lbm_is_number(args[1]) || | |
158 | ✗ | !lbm_is_number(args[2])) { | |
159 | ✗ | return res; | |
160 | } | ||
161 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
162 | |||
163 | ✗ | lbm_uint index = lbm_dec_as_u32(args[1]); | |
164 | ✗ | lbm_int value = lbm_dec_as_i32(args[2]); | |
165 | |||
166 | ✗ | if (index+1 >= array->size) { | |
167 | ✗ | return res; | |
168 | } | ||
169 | |||
170 | ✗ | uint8_t *data = (uint8_t*)array->data; | |
171 | |||
172 | ✗ | if (be) { | |
173 | ✗ | data[index+1] = (uint8_t)value; | |
174 | ✗ | data[index] = (uint8_t)(value >> 8); | |
175 | } else { | ||
176 | ✗ | data[index] = (uint8_t)value; | |
177 | ✗ | data[index +1] = (uint8_t)(value >> 8); | |
178 | } | ||
179 | ✗ | res = ENC_SYM_TRUE; | |
180 | ✗ | } break; | |
181 | ✗ | default: | |
182 | ✗ | break; | |
183 | } | ||
184 | ✗ | return res; | |
185 | } | ||
186 | |||
187 | ✗ | lbm_value array_extension_buffer_append_i24(lbm_value *args, lbm_uint argn) { | |
188 | |||
189 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
190 | ✗ | bool be = true; | |
191 | |||
192 | ✗ | switch(argn) { | |
193 | |||
194 | ✗ | case 4: | |
195 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
196 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
197 | ✗ | be = false; | |
198 | } | ||
199 | /* fall through */ | ||
200 | case 3: { | ||
201 | ✗ | if(!lbm_is_array_rw(args[0]) || | |
202 | ✗ | !lbm_is_number(args[1]) || | |
203 | ✗ | !lbm_is_number(args[2])) { | |
204 | ✗ | return res; | |
205 | } | ||
206 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
207 | |||
208 | ✗ | lbm_uint index = lbm_dec_as_u32(args[1]); | |
209 | ✗ | lbm_int value = lbm_dec_as_i32(args[2]); | |
210 | |||
211 | ✗ | if (index+2 >= array->size) { | |
212 | ✗ | return res; | |
213 | } | ||
214 | |||
215 | ✗ | uint8_t *data = (uint8_t*)array->data; | |
216 | |||
217 | ✗ | if (be) { | |
218 | ✗ | data[index+2] = (uint8_t)value; | |
219 | ✗ | data[index+1] = (uint8_t)(value >> 8); | |
220 | ✗ | data[index] = (uint8_t)(value >> 16); | |
221 | } else { | ||
222 | ✗ | data[index] = (uint8_t)value; | |
223 | ✗ | data[index+1] = (uint8_t)(value >> 8); | |
224 | ✗ | data[index+2] = (uint8_t)(value >> 16); | |
225 | } | ||
226 | ✗ | res = ENC_SYM_TRUE; | |
227 | ✗ | } break; | |
228 | ✗ | default: | |
229 | ✗ | break; | |
230 | } | ||
231 | ✗ | return res; | |
232 | } | ||
233 | |||
234 | 140 | lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn) { | |
235 | |||
236 | 140 | lbm_value res = ENC_SYM_EERROR; | |
237 | 140 | bool be = true; | |
238 | |||
239 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | switch(argn) { |
240 | |||
241 | ✗ | case 4: | |
242 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
243 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
244 | ✗ | be = false; | |
245 | } | ||
246 | /* fall through */ | ||
247 | case 3: { | ||
248 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | if(!lbm_is_array_rw(args[0]) || |
249 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | !lbm_is_number(args[1]) || |
250 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
|
140 | !lbm_is_number(args[2])) { |
251 | ✗ | return res; | |
252 | } | ||
253 | 140 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
254 | |||
255 | 140 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
256 | 140 | lbm_int value = lbm_dec_as_i32(args[2]); | |
257 | |||
258 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (index+3 >= array->size) { |
259 | ✗ | return res; | |
260 | } | ||
261 | |||
262 | 140 | uint8_t *data = (uint8_t*)array->data; | |
263 | |||
264 |
1/2✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
|
140 | if (be) { |
265 | 140 | data[index+3] = (uint8_t) value; | |
266 | 140 | data[index+2] = (uint8_t) (value >> 8); | |
267 | 140 | data[index+1] = (uint8_t) (value >> 16); | |
268 | 140 | data[index] = (uint8_t) (value >> 24); | |
269 | } else { | ||
270 | ✗ | data[index] = (uint8_t) value; | |
271 | ✗ | data[index+1] = (uint8_t) (value >> 8); | |
272 | ✗ | data[index+2] = (uint8_t) (value >> 16); | |
273 | ✗ | data[index+3] = (uint8_t) (value >> 24); | |
274 | } | ||
275 | 140 | res = ENC_SYM_TRUE; | |
276 | 140 | } break; | |
277 | ✗ | default: | |
278 | ✗ | break; | |
279 | } | ||
280 | 140 | return res; | |
281 | } | ||
282 | |||
283 | 364 | lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn) { | |
284 | |||
285 | 364 | lbm_value res = ENC_SYM_EERROR; | |
286 | |||
287 |
1/2✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
|
364 | switch(argn) { |
288 | |||
289 | 364 | case 3: { | |
290 |
1/2✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
|
364 | if(!lbm_is_array_rw(args[0]) || |
291 |
1/2✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
|
364 | !lbm_is_number(args[1]) || |
292 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 364 times.
|
364 | !lbm_is_number(args[2])) { |
293 | ✗ | return res; | |
294 | } | ||
295 | 364 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
296 | |||
297 | 364 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
298 | 364 | lbm_uint value = lbm_dec_as_u32(args[2]); | |
299 | |||
300 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 364 times.
|
364 | if (index >= array->size) { |
301 | ✗ | return res; | |
302 | } | ||
303 | |||
304 | 364 | uint8_t *data = (uint8_t*)array->data; | |
305 | 364 | data[index] = (uint8_t)value; | |
306 | 364 | res = ENC_SYM_TRUE; | |
307 | 364 | } break; | |
308 | ✗ | default: | |
309 | ✗ | break; | |
310 | } | ||
311 | 364 | return res; | |
312 | } | ||
313 | |||
314 | 84 | lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn) { | |
315 | |||
316 | 84 | lbm_value res = ENC_SYM_EERROR; | |
317 | 84 | bool be = true; | |
318 | |||
319 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | switch(argn) { |
320 | |||
321 | ✗ | case 4: | |
322 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
323 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
324 | ✗ | be = false; | |
325 | } | ||
326 | /* fall through */ | ||
327 | case 3: { | ||
328 |
1/2✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | if(!lbm_is_array_rw(args[0]) || |
329 |
1/2✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | !lbm_is_number(args[1]) || |
330 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
|
84 | !lbm_is_number(args[2])) { |
331 | ✗ | return res; | |
332 | } | ||
333 | 84 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
334 | |||
335 | 84 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
336 | 84 | lbm_uint value = lbm_dec_as_u32(args[2]); | |
337 | |||
338 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
|
84 | if (index+1 >= array->size) { |
339 | ✗ | return res; | |
340 | } | ||
341 | |||
342 | 84 | uint8_t *data = (uint8_t*)array->data; | |
343 | |||
344 |
1/2✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
|
84 | if (be) { |
345 | 84 | data[index+1] = (uint8_t)value; | |
346 | 84 | data[index] = (uint8_t)(value >> 8); | |
347 | } else { | ||
348 | ✗ | data[index] = (uint8_t)value; | |
349 | ✗ | data[index +1] = (uint8_t)(value >> 8); | |
350 | } | ||
351 | 84 | res = ENC_SYM_TRUE; | |
352 | 84 | } break; | |
353 | ✗ | default: | |
354 | ✗ | break; | |
355 | } | ||
356 | 84 | return res; | |
357 | } | ||
358 | |||
359 | ✗ | lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn) { | |
360 | |||
361 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
362 | ✗ | bool be = true; | |
363 | |||
364 | ✗ | switch(argn) { | |
365 | |||
366 | ✗ | case 4: | |
367 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
368 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
369 | ✗ | be = false; | |
370 | } | ||
371 | /* fall through */ | ||
372 | case 3: { | ||
373 | ✗ | if(!lbm_is_array_rw(args[0]) || | |
374 | ✗ | !lbm_is_number(args[1]) || | |
375 | ✗ | !lbm_is_number(args[2])) { | |
376 | ✗ | return res; | |
377 | } | ||
378 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
379 | |||
380 | ✗ | lbm_uint index = lbm_dec_as_u32(args[1]); | |
381 | ✗ | lbm_uint value = lbm_dec_as_u32(args[2]); | |
382 | |||
383 | ✗ | if (index+2 >= array->size) { | |
384 | ✗ | return res; | |
385 | } | ||
386 | |||
387 | ✗ | uint8_t *data = (uint8_t*)array->data; | |
388 | |||
389 | ✗ | if (be) { | |
390 | ✗ | data[index+2] = (uint8_t)value; | |
391 | ✗ | data[index+1] = (uint8_t)(value >> 8); | |
392 | ✗ | data[index] = (uint8_t)(value >> 16); | |
393 | } else { | ||
394 | ✗ | data[index] = (uint8_t)value; | |
395 | ✗ | data[index +1] = (uint8_t)(value >> 8); | |
396 | ✗ | data[index +2] = (uint8_t)(value >> 16); | |
397 | } | ||
398 | ✗ | res = ENC_SYM_TRUE; | |
399 | ✗ | } break; | |
400 | ✗ | default: | |
401 | ✗ | break; | |
402 | } | ||
403 | ✗ | return res; | |
404 | } | ||
405 | |||
406 | 140 | lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn) { | |
407 | |||
408 | 140 | lbm_value res = ENC_SYM_EERROR; | |
409 | 140 | bool be = true; | |
410 | |||
411 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | switch(argn) { |
412 | |||
413 | ✗ | case 4: | |
414 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
415 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
416 | ✗ | be = false; | |
417 | } | ||
418 | /* fall through */ | ||
419 | case 3: { | ||
420 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | if(!lbm_is_array_rw(args[0]) || |
421 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | !lbm_is_number(args[1]) || |
422 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
|
140 | !lbm_is_number(args[2])) { |
423 | ✗ | return res; | |
424 | } | ||
425 | 140 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
426 | |||
427 | 140 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
428 | 140 | lbm_uint value = lbm_dec_as_u32(args[2]); | |
429 | |||
430 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (index+3 >= array->size) { |
431 | ✗ | return res; | |
432 | } | ||
433 | |||
434 | 140 | uint8_t *data = (uint8_t*)array->data; | |
435 | |||
436 |
1/2✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
|
140 | if (be) { |
437 | 140 | data[index+3] = (uint8_t)value; | |
438 | 140 | data[index+2] = (uint8_t)(value >> 8); | |
439 | 140 | data[index+1] = (uint8_t)(value >> 16); | |
440 | 140 | data[index] = (uint8_t)(value >> 24); | |
441 | } else { | ||
442 | ✗ | data[index] = (uint8_t)value; | |
443 | ✗ | data[index+1] = (uint8_t)(value >> 8); | |
444 | ✗ | data[index+2] = (uint8_t)(value >> 16); | |
445 | ✗ | data[index+3] = (uint8_t)(value >> 24); | |
446 | } | ||
447 | 140 | res = ENC_SYM_TRUE; | |
448 | 140 | } break; | |
449 | ✗ | default: | |
450 | ✗ | break; | |
451 | } | ||
452 | 140 | return res; | |
453 | } | ||
454 | |||
455 | 168 | static lbm_uint float_to_u(float number) { | |
456 | // Set subnormal numbers to 0 as they are not handled properly | ||
457 | // using this method. | ||
458 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | if (fabsf(number) < 1.5e-38) { |
459 | ✗ | number = 0.0; | |
460 | } | ||
461 | |||
462 | 168 | int e = 0; | |
463 | 168 | float sig = frexpf(number, &e); | |
464 | 168 | float sig_abs = fabsf(sig); | |
465 | 168 | uint32_t sig_i = 0; | |
466 | |||
467 |
1/2✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
|
168 | if (sig_abs >= 0.5) { |
468 | 168 | sig_i = (uint32_t)((sig_abs - 0.5f) * 2.0f * 8388608.0f); | |
469 | 168 | e += 126; | |
470 | } | ||
471 | |||
472 | 168 | uint32_t res = ((e & 0xFF) << 23) | (sig_i & 0x7FFFFF); | |
473 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | if (sig < 0) { |
474 | ✗ | res |= 1U << 31; | |
475 | } | ||
476 | |||
477 | 168 | return res; | |
478 | } | ||
479 | |||
480 | 168 | static lbm_float u_to_float(uint32_t v) { | |
481 | |||
482 | 168 | int e = (v >> 23) & 0xFF; | |
483 | 168 | uint32_t sig_i = v & 0x7FFFFF; | |
484 | 168 | bool neg = v & (1U << 31); | |
485 | |||
486 | 168 | float sig = 0.0; | |
487 |
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) { |
488 | 168 | sig = (float)sig_i / (8388608.0f * 2.0f) + 0.5f; | |
489 | 168 | e -= 126; | |
490 | } | ||
491 | |||
492 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | if (neg) { |
493 | ✗ | sig = -sig; | |
494 | } | ||
495 | |||
496 | 168 | return ldexpf(sig, e); | |
497 | } | ||
498 | |||
499 | 168 | lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn) { | |
500 | |||
501 | 168 | lbm_value res = ENC_SYM_EERROR; | |
502 | 168 | bool be = true; | |
503 | |||
504 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
|
168 | switch(argn) { |
505 | |||
506 | ✗ | case 4: | |
507 | ✗ | if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL && | |
508 | ✗ | lbm_dec_sym(args[3]) == little_endian) { | |
509 | ✗ | be = false; | |
510 | } | ||
511 | /* fall through */ | ||
512 | case 3: { | ||
513 |
1/2✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
|
168 | if(!lbm_is_array_rw(args[0]) || |
514 |
1/2✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
|
168 | !lbm_is_number(args[1]) || |
515 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 168 times.
|
168 | !lbm_is_number(args[2])) { |
516 | ✗ | return res; | |
517 | } | ||
518 | 168 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
519 | |||
520 | 168 | float f_value = (float)lbm_dec_as_float(args[2]); | |
521 | 168 | lbm_value value = float_to_u(f_value); | |
522 | 168 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
523 | |||
524 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | if (index+3 >= array->size) { |
525 | ✗ | return res; | |
526 | } | ||
527 | |||
528 | 168 | uint8_t *data = (uint8_t*)array->data; | |
529 | |||
530 |
1/2✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
|
168 | if (be) { |
531 | 168 | data[index+3] = (uint8_t)value; | |
532 | 168 | data[index+2] = (uint8_t)(value >> 8); | |
533 | 168 | data[index+1] = (uint8_t)(value >> 16); | |
534 | 168 | data[index] = (uint8_t)(value >> 24); | |
535 | } else { | ||
536 | ✗ | data[index] = (uint8_t)value; | |
537 | ✗ | data[index+1] = (uint8_t)(value >> 8); | |
538 | ✗ | data[index+2] = (uint8_t)(value >> 16); | |
539 | ✗ | data[index+3] = (uint8_t)(value >> 24); | |
540 | } | ||
541 | 168 | res = ENC_SYM_TRUE; | |
542 | 168 | } break; | |
543 | ✗ | default: | |
544 | ✗ | break; | |
545 | } | ||
546 | 168 | return res; | |
547 | } | ||
548 | |||
549 | /* (buffer-get-i8 buffer index) */ | ||
550 | /* (buffer-get-i16 buffer index little-endian) */ | ||
551 | |||
552 | 504 | lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn) { | |
553 | 504 | lbm_value res = ENC_SYM_EERROR; | |
554 | |||
555 |
1/2✓ Branch 0 taken 504 times.
✗ Branch 1 not taken.
|
504 | if (argn == 2) { |
556 |
1/2✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
|
504 | if(!lbm_is_array_r(args[0]) || |
557 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 504 times.
|
504 | !lbm_is_number(args[1])) { |
558 | ✗ | return res; | |
559 | } | ||
560 | 504 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
561 | |||
562 | 504 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
563 | 504 | lbm_uint value = 0; | |
564 | |||
565 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 504 times.
|
504 | if (index >= array->size) { |
566 | ✗ | return res; | |
567 | } | ||
568 | 504 | uint8_t *data = (uint8_t*)array->data; | |
569 | |||
570 | 504 | value = data[index]; | |
571 | 504 | res = lbm_enc_i((int8_t)value); | |
572 | } | ||
573 | 504 | return res; | |
574 | } | ||
575 | |||
576 | ✗ | lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn) { | |
577 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
578 | ✗ | bool be = true; | |
579 | |||
580 | ✗ | switch(argn) { | |
581 | |||
582 | ✗ | case 3: | |
583 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
584 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
585 | ✗ | be = false; | |
586 | } | ||
587 | /* fall through */ | ||
588 | case 2: { | ||
589 | ✗ | if (!lbm_is_array_r(args[0]) || | |
590 | ✗ | !lbm_is_number(args[1])) { | |
591 | ✗ | return res; | |
592 | } | ||
593 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
594 | |||
595 | ✗ | lbm_uint index = lbm_dec_as_u32(args[1]); | |
596 | ✗ | lbm_uint value = 0; | |
597 | |||
598 | ✗ | if (index+1 >= array->size) { | |
599 | ✗ | return res; | |
600 | } | ||
601 | ✗ | uint8_t *data = (uint8_t*)array->data; | |
602 | |||
603 | ✗ | if (be) { | |
604 | ✗ | value = | |
605 | ✗ | (lbm_uint) data[index+1] | | |
606 | ✗ | (lbm_uint) data[index] << 8; | |
607 | } else { | ||
608 | ✗ | value = | |
609 | ✗ | (lbm_uint) data[index] | | |
610 | ✗ | (lbm_uint) data[index+1] << 8; | |
611 | } | ||
612 | |||
613 | ✗ | res = lbm_enc_i((int16_t)value); | |
614 | ✗ | } break; | |
615 | ✗ | default: | |
616 | ✗ | break; | |
617 | } | ||
618 | ✗ | return res; | |
619 | } | ||
620 | |||
621 | 140 | lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn) { | |
622 | 140 | lbm_value res = ENC_SYM_EERROR; | |
623 | 140 | bool be = true; | |
624 | |||
625 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | switch(argn) { |
626 | |||
627 | ✗ | case 3: | |
628 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
629 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
630 | ✗ | be = false; | |
631 | } | ||
632 | /* fall through */ | ||
633 | case 2: { | ||
634 |
1/2✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
|
140 | if (!lbm_is_array_r(args[0]) || |
635 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
|
140 | !lbm_is_number(args[1])) { |
636 | ✗ | return res; | |
637 | } | ||
638 | 140 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
639 | |||
640 | 140 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
641 | 140 | uint32_t value = 0; | |
642 | |||
643 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (index+3 >= array->size) { |
644 | ✗ | return res; | |
645 | } | ||
646 | 140 | uint8_t *data = (uint8_t*)array->data; | |
647 | |||
648 |
1/2✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
|
140 | if (be) { |
649 | 140 | value = | |
650 | 140 | (uint32_t) data[index+3] | | |
651 | 140 | (uint32_t) data[index+2] << 8 | | |
652 | 140 | (uint32_t) data[index+1] << 16 | | |
653 | 140 | (uint32_t) data[index] << 24; | |
654 | } else { | ||
655 | ✗ | value = | |
656 | ✗ | (uint32_t) data[index] | | |
657 | ✗ | (uint32_t) data[index+1] << 8 | | |
658 | ✗ | (uint32_t) data[index+2] << 16 | | |
659 | ✗ | (uint32_t) data[index+3] << 24; | |
660 | } | ||
661 | |||
662 | 140 | res = lbm_enc_i32((int32_t)value); | |
663 | 140 | } break; | |
664 | ✗ | default: | |
665 | ✗ | break; | |
666 | } | ||
667 | 140 | return res; | |
668 | } | ||
669 | |||
670 | |||
671 | 728 | lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn) { | |
672 | 728 | lbm_value res = ENC_SYM_EERROR; | |
673 | |||
674 |
1/2✓ Branch 0 taken 728 times.
✗ Branch 1 not taken.
|
728 | if (argn == 2) { |
675 |
1/2✓ Branch 1 taken 728 times.
✗ Branch 2 not taken.
|
728 | if(!lbm_is_array_r(args[0])|| |
676 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 728 times.
|
728 | !lbm_is_number(args[1])) { |
677 | ✗ | return res; | |
678 | } | ||
679 | 728 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
680 | |||
681 | 728 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
682 | 728 | lbm_int value = 0; | |
683 | |||
684 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 728 times.
|
728 | if (index >= array->size) { |
685 | ✗ | return res; | |
686 | } | ||
687 | 728 | uint8_t *data = (uint8_t*)array->data; | |
688 | |||
689 | 728 | value = (lbm_int)data[index]; | |
690 | 728 | res = lbm_enc_i(value); | |
691 | } | ||
692 | 728 | return res; | |
693 | } | ||
694 | |||
695 | |||
696 | 84 | lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn) { | |
697 | 84 | lbm_value res = ENC_SYM_EERROR; | |
698 | 84 | bool be = true; | |
699 | |||
700 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | switch(argn) { |
701 | |||
702 | ✗ | case 3: | |
703 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
704 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
705 | ✗ | be = false; | |
706 | } | ||
707 | /* fall through */ | ||
708 | case 2: { | ||
709 |
1/2✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | if (!lbm_is_array_r(args[0]) || |
710 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
|
84 | !lbm_is_number(args[1])) { |
711 | ✗ | return res; | |
712 | } | ||
713 | 84 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
714 | |||
715 | 84 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
716 | 84 | lbm_int value = 0; | |
717 | |||
718 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
|
84 | if (index+1 >= array->size) { |
719 | ✗ | return res; | |
720 | } | ||
721 | 84 | uint8_t *data = (uint8_t*)array->data; | |
722 | |||
723 |
1/2✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
|
84 | if (be) { |
724 | 84 | value = (lbm_int)( | |
725 | 84 | (lbm_uint) data[index+1] | | |
726 | 84 | (lbm_uint) data[index] << 8); | |
727 | } else { | ||
728 | ✗ | value = (lbm_int)( | |
729 | ✗ | (lbm_uint) data[index] | | |
730 | ✗ | (lbm_uint) data[index+1] << 8); | |
731 | } | ||
732 | |||
733 | 84 | res = lbm_enc_i(value); | |
734 | 84 | } break; | |
735 | ✗ | default: | |
736 | ✗ | break; | |
737 | } | ||
738 | 84 | return res; | |
739 | } | ||
740 | |||
741 | ✗ | lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn) { | |
742 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
743 | ✗ | bool be = true; | |
744 | |||
745 | ✗ | switch(argn) { | |
746 | |||
747 | ✗ | case 3: | |
748 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
749 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
750 | ✗ | be = false; | |
751 | } | ||
752 | /* fall through */ | ||
753 | case 2: { | ||
754 | ✗ | if (!lbm_is_array_r(args[0]) || | |
755 | ✗ | !lbm_is_number(args[1])) { | |
756 | ✗ | return res; | |
757 | } | ||
758 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
759 | |||
760 | ✗ | lbm_uint index = lbm_dec_as_u32(args[1]); | |
761 | ✗ | lbm_int value = 0; | |
762 | |||
763 | ✗ | if (index+2 >= array->size) { | |
764 | ✗ | return res; | |
765 | } | ||
766 | ✗ | uint8_t *data = (uint8_t*)array->data; | |
767 | |||
768 | ✗ | if (be) { | |
769 | ✗ | value = (lbm_int)( | |
770 | ✗ | (lbm_uint) data[index+2] | | |
771 | ✗ | (lbm_uint) data[index+1] << 8 | | |
772 | ✗ | (lbm_uint) data[index] << 16); | |
773 | } else { | ||
774 | ✗ | value = (lbm_int)( | |
775 | ✗ | (lbm_uint) data[index] | | |
776 | ✗ | (lbm_uint) data[index+1] << 8 | | |
777 | ✗ | (lbm_uint) data[index+2] << 16); | |
778 | } | ||
779 | |||
780 | ✗ | res = lbm_enc_i(value); | |
781 | ✗ | } break; | |
782 | ✗ | default: | |
783 | ✗ | break; | |
784 | } | ||
785 | ✗ | return res; | |
786 | } | ||
787 | |||
788 | |||
789 | 224 | lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn) { | |
790 | 224 | lbm_value res = ENC_SYM_EERROR; | |
791 | 224 | bool be = true; | |
792 | |||
793 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
|
224 | switch(argn) { |
794 | |||
795 | ✗ | case 3: | |
796 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
797 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
798 | ✗ | be = false; | |
799 | } | ||
800 | /* fall through */ | ||
801 | case 2: { | ||
802 |
1/2✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
|
224 | if (!lbm_is_array_r(args[0]) || |
803 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 224 times.
|
224 | !lbm_is_number(args[1])) { |
804 | ✗ | return res; | |
805 | } | ||
806 | 224 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
807 | |||
808 | 224 | lbm_uint index = lbm_dec_as_u32(args[1]); | |
809 | 224 | uint32_t value = 0; | |
810 | |||
811 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
|
224 | if (index+3 >= array->size) { |
812 | ✗ | return res; | |
813 | } | ||
814 | 224 | uint8_t *data = (uint8_t*)array->data; | |
815 | |||
816 |
1/2✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
|
224 | if (be) { |
817 | 224 | value = | |
818 | 224 | (uint32_t) data[index+3] | | |
819 | 224 | (uint32_t) data[index+2] << 8 | | |
820 | 224 | (uint32_t) data[index+1] << 16 | | |
821 | 224 | (uint32_t) data[index] << 24; | |
822 | } else { | ||
823 | ✗ | value = | |
824 | ✗ | (uint32_t) data[index] | | |
825 | ✗ | (uint32_t) data[index+1] << 8 | | |
826 | ✗ | (uint32_t) data[index+2] << 16 | | |
827 | ✗ | (uint32_t) data[index+3] << 24; | |
828 | } | ||
829 | |||
830 | 224 | res = lbm_enc_u32(value); | |
831 | 224 | } break; | |
832 | ✗ | default: | |
833 | ✗ | break; | |
834 | } | ||
835 | 224 | return res; | |
836 | } | ||
837 | |||
838 | 168 | lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn) { | |
839 | 168 | lbm_value res = ENC_SYM_EERROR; | |
840 | 168 | bool be = true; | |
841 | |||
842 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
|
168 | switch(argn) { |
843 | |||
844 | ✗ | case 3: | |
845 | ✗ | if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL && | |
846 | ✗ | lbm_dec_sym(args[2]) == little_endian) { | |
847 | ✗ | be = false; | |
848 | } | ||
849 | /* fall through */ | ||
850 | case 2: { | ||
851 |
1/2✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
|
168 | if (!lbm_is_array_r(args[0]) || |
852 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 168 times.
|
168 | !lbm_is_number(args[1])) { |
853 | ✗ | return res; | |
854 | } | ||
855 | 168 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
856 | |||
857 | 168 | uint32_t index = (uint32_t)lbm_dec_as_u32(args[1]); | |
858 | 168 | uint32_t value = 0; | |
859 | |||
860 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | if (index+3 >= array->size) { |
861 | ✗ | return res; | |
862 | } | ||
863 | 168 | uint8_t *data = (uint8_t*)array->data; | |
864 | |||
865 |
1/2✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
|
168 | if (be) { |
866 | 168 | value = | |
867 | 168 | (uint32_t) data[index+3] | | |
868 | 168 | (uint32_t) data[index+2] << 8 | | |
869 | 168 | (uint32_t) data[index+1] << 16 | | |
870 | 168 | (uint32_t) data[index] << 24; | |
871 | } else { | ||
872 | ✗ | value = | |
873 | ✗ | (uint32_t) data[index] | | |
874 | ✗ | (uint32_t) data[index+1] << 8 | | |
875 | ✗ | (uint32_t) data[index+2] << 16 | | |
876 | ✗ | (uint32_t) data[index+3] << 24; | |
877 | } | ||
878 | |||
879 | 168 | res = lbm_enc_float((float)u_to_float(value)); | |
880 | 168 | } break; | |
881 | ✗ | default: | |
882 | ✗ | break; | |
883 | } | ||
884 | 168 | return res; | |
885 | } | ||
886 | |||
887 | 252 | lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn) { | |
888 | 252 | lbm_value res = ENC_SYM_EERROR; | |
889 |
2/4✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 252 times.
✗ Branch 3 not taken.
|
504 | if (argn == 1 && |
890 | 252 | lbm_is_array_r(args[0])) { | |
891 | 252 | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
892 | 252 | res = lbm_enc_i((lbm_int)array->size); | |
893 | } | ||
894 | 252 | return res; | |
895 | } | ||
896 | |||
897 | //TODO: Have to think about 32 vs 64 bit here | ||
898 | ✗ | static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn) { | |
899 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
900 | |||
901 | ✗ | if ((argn != 1 && argn != 2 && argn != 3 && argn != 4) || !lbm_is_array_rw(args[0])) { | |
902 | ✗ | return res; | |
903 | } | ||
904 | |||
905 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
906 | |||
907 | ✗ | uint8_t clear_byte = 0; | |
908 | ✗ | if (argn >= 2) { | |
909 | ✗ | if (!lbm_is_number(args[1])) { | |
910 | ✗ | return res; | |
911 | } | ||
912 | ✗ | clear_byte = (uint8_t)lbm_dec_as_u32(args[1]); | |
913 | } | ||
914 | |||
915 | ✗ | uint32_t start = 0; | |
916 | ✗ | if (argn >= 3) { | |
917 | ✗ | if (!lbm_is_number(args[2])) { | |
918 | ✗ | return res; | |
919 | } | ||
920 | ✗ | uint32_t start_new = lbm_dec_as_u32(args[2]); | |
921 | ✗ | if (start_new < array->size) { | |
922 | ✗ | start = start_new; | |
923 | } else { | ||
924 | ✗ | return res; | |
925 | } | ||
926 | } | ||
927 | // Truncates size on 64 bit build | ||
928 | ✗ | uint32_t len = (uint32_t)array->size - start; | |
929 | ✗ | if (argn >= 4) { | |
930 | ✗ | if (!lbm_is_number(args[3])) { | |
931 | ✗ | return res; | |
932 | } | ||
933 | ✗ | uint32_t len_new = lbm_dec_as_u32(args[3]); | |
934 | ✗ | if (len_new <= len) { | |
935 | ✗ | len = len_new; | |
936 | } | ||
937 | } | ||
938 | |||
939 | ✗ | memset((char*)array->data + start, clear_byte, len); | |
940 | ✗ | res = ENC_SYM_TRUE; | |
941 | |||
942 | ✗ | return res; | |
943 | } | ||
944 | |||
945 | ✗ | static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn) { | |
946 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
947 | |||
948 | ✗ | if (argn != 5 || !lbm_is_array_rw(args[0]) || !lbm_is_number(args[1]) | |
949 | ✗ | || !lbm_is_array_r(args[2]) || !lbm_is_number(args[3]) || !lbm_is_number(args[4])) { | |
950 | ✗ | return res; | |
951 | } | ||
952 | |||
953 | ✗ | lbm_array_header_t *array1 = (lbm_array_header_t *)lbm_car(args[0]); | |
954 | |||
955 | ✗ | uint32_t start1 = lbm_dec_as_u32(args[1]); | |
956 | |||
957 | ✗ | lbm_array_header_t *array2 = (lbm_array_header_t *)lbm_car(args[2]); | |
958 | |||
959 | ✗ | uint32_t start2 = lbm_dec_as_u32(args[3]); | |
960 | ✗ | uint32_t len = lbm_dec_as_u32(args[4]); | |
961 | |||
962 | ✗ | if (start1 < array1->size && start2 < array2->size) { | |
963 | ✗ | if (len > (array1->size - start1)) { | |
964 | ✗ | len = ((uint32_t)array1->size - start1); | |
965 | } | ||
966 | ✗ | if (len > (array2->size - start2)) { | |
967 | ✗ | len = ((uint32_t)array2->size - start2); | |
968 | } | ||
969 | |||
970 | ✗ | memcpy((char*)array1->data + start1, (char*)array2->data + start2, len); | |
971 | } | ||
972 | |||
973 | ✗ | res = ENC_SYM_TRUE; | |
974 | |||
975 | ✗ | return res; | |
976 | } | ||
977 | |||
978 | ✗ | static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn) { | |
979 | ✗ | lbm_value res = ENC_SYM_EERROR; | |
980 | |||
981 | ✗ | if (argn != 3 || !lbm_is_array_rw(args[0]) || | |
982 | ✗ | !lbm_is_number(args[1]) || !lbm_is_number(args[2])) { | |
983 | ✗ | return res; | |
984 | } | ||
985 | |||
986 | ✗ | lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]); | |
987 | |||
988 | ✗ | unsigned int pos = lbm_dec_as_u32(args[1]); | |
989 | ✗ | unsigned int bit = lbm_dec_as_u32(args[2]) ? 1 : 0; | |
990 | |||
991 | ✗ | unsigned int bytepos = pos / 8; | |
992 | ✗ | unsigned int bitpos = pos % 8; | |
993 | |||
994 | ✗ | if (bytepos < array->size) { | |
995 | ✗ | ((uint8_t*)array->data)[bytepos] &= (uint8_t)~(1 << bitpos); | |
996 | ✗ | ((uint8_t*)array->data)[bytepos] |= (uint8_t)(bit << bitpos); | |
997 | } | ||
998 | |||
999 | ✗ | res = ENC_SYM_TRUE; | |
1000 | |||
1001 | ✗ | return res; | |
1002 | } | ||
1003 |