@mikrojs/native 0.13.0 → 0.14.0-pr-229.g0d8db1b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,418 @@
1
+ /*
2
+ * SPDX-License-Identifier: CC0-1.0
3
+ */
4
+
5
+ /**
6
+ * @ingroup nanocbor
7
+ * @{
8
+ * @file
9
+ * @brief Minimalistic CBOR encoder implementation
10
+ *
11
+ * @author Koen Zandberg <koen@bergzand.net>
12
+ * @}
13
+ */
14
+
15
+ #include <stddef.h>
16
+ #include <stdint.h>
17
+ #include <stdlib.h>
18
+ #include <string.h>
19
+
20
+ #include "nanocbor/config.h"
21
+ #include "nanocbor/nanocbor.h"
22
+
23
+ #include NANOCBOR_BYTEORDER_HEADER
24
+
25
+ /* memarray functions */
26
+ static bool _encoder_mem_fits(nanocbor_encoder_t *enc, void *ctx, size_t len)
27
+ {
28
+ (void)ctx;
29
+ return ((size_t)(enc->end - enc->cur) >= len);
30
+ }
31
+
32
+ static void _encoder_mem_append(nanocbor_encoder_t *enc, void *ctx, const uint8_t *data, size_t len)
33
+ {
34
+ (void)ctx;
35
+ memcpy(enc->cur, data, len);
36
+ enc->cur += len;
37
+ }
38
+
39
+ void nanocbor_encoder_init(nanocbor_encoder_t *enc, uint8_t *buf, size_t len)
40
+ {
41
+ enc->len = 0;
42
+ enc->cur = buf;
43
+ enc->end = buf + len;
44
+ enc->append = _encoder_mem_append;
45
+ enc->fits = _encoder_mem_fits;
46
+ }
47
+
48
+ void nanocbor_encoder_stream_init(nanocbor_encoder_t *enc, void *ctx,
49
+ nanocbor_encoder_append append_func,
50
+ nanocbor_encoder_fits fits_func)
51
+ {
52
+ enc->len = 0;
53
+ enc->append = append_func;
54
+ enc->fits = fits_func;
55
+ enc->context = ctx;
56
+ }
57
+
58
+ size_t nanocbor_encoded_len(nanocbor_encoder_t *enc)
59
+ {
60
+ return enc->len;
61
+ }
62
+
63
+ static inline void _incr_len(nanocbor_encoder_t *enc, size_t len)
64
+ {
65
+ enc->len += len;
66
+ }
67
+
68
+ static inline void _append(nanocbor_encoder_t *enc, const uint8_t *data, size_t len)
69
+ {
70
+ enc->append(enc, enc->context, data, len);
71
+ }
72
+
73
+ static inline int _fits(nanocbor_encoder_t *enc, size_t len)
74
+ {
75
+ return enc->fits(enc, enc->context, len) ? (int)len : NANOCBOR_ERR_END;
76
+ }
77
+
78
+ static int _fmt_single(nanocbor_encoder_t *enc, uint8_t single)
79
+ {
80
+ _incr_len(enc, 1);
81
+ int res = _fits(enc, 1);
82
+
83
+ if (res == 1) {
84
+ _append(enc, &single, 1);
85
+
86
+ }
87
+ return res;
88
+ }
89
+
90
+ int nanocbor_fmt_bool(nanocbor_encoder_t *enc, bool content)
91
+ {
92
+ uint8_t single = NANOCBOR_MASK_FLOAT
93
+ | (content ? NANOCBOR_SIMPLE_TRUE : NANOCBOR_SIMPLE_FALSE);
94
+
95
+ return _fmt_single(enc, single);
96
+ }
97
+
98
+ static int _fmt_uint64(nanocbor_encoder_t *enc, uint64_t num, uint8_t type)
99
+ {
100
+ unsigned extrabytes = 0;
101
+
102
+ if (num < NANOCBOR_SIZE_BYTE) {
103
+ type |= num;
104
+ }
105
+ else {
106
+ if (num > UINT32_MAX) {
107
+ /* Requires long size */
108
+ type |= NANOCBOR_SIZE_LONG;
109
+ extrabytes = sizeof(uint64_t);
110
+ }
111
+ else if (num > UINT16_MAX) {
112
+ /* At least word size */
113
+ type |= NANOCBOR_SIZE_WORD;
114
+ extrabytes = sizeof(uint32_t);
115
+ }
116
+ else if (num > UINT8_MAX) {
117
+ type |= NANOCBOR_SIZE_SHORT;
118
+ extrabytes = sizeof(uint16_t);
119
+ }
120
+ else {
121
+ type |= NANOCBOR_SIZE_BYTE;
122
+ extrabytes = sizeof(uint8_t);
123
+ }
124
+ }
125
+ _incr_len(enc, extrabytes + 1);
126
+ int res = _fits(enc, extrabytes + 1);
127
+ if (res > 0) {
128
+ _append(enc, &type, 1);
129
+
130
+ /* NOLINTNEXTLINE: user supplied function */
131
+ uint64_t benum = NANOCBOR_HTOBE64_FUNC(num);
132
+
133
+
134
+ _append(enc, (uint8_t *)&benum + sizeof(benum) - extrabytes,
135
+ extrabytes);
136
+ }
137
+ return res;
138
+ }
139
+
140
+ int nanocbor_fmt_uint(nanocbor_encoder_t *enc, uint64_t num)
141
+ {
142
+ return _fmt_uint64(enc, num, NANOCBOR_MASK_UINT);
143
+ }
144
+
145
+ int nanocbor_fmt_tag(nanocbor_encoder_t *enc, uint64_t num)
146
+ {
147
+ return _fmt_uint64(enc, num, NANOCBOR_MASK_TAG);
148
+ }
149
+
150
+ int nanocbor_fmt_int(nanocbor_encoder_t *enc, int64_t num)
151
+ {
152
+ if (num < 0) {
153
+ /* Always negative at this point */
154
+ num = -(num + 1);
155
+ return _fmt_uint64(enc, (uint64_t)num, NANOCBOR_MASK_NINT);
156
+ }
157
+ return nanocbor_fmt_uint(enc, (uint64_t)num);
158
+ }
159
+
160
+ int nanocbor_fmt_simple(nanocbor_encoder_t *enc, uint8_t value)
161
+ {
162
+ /* Exclude assigned or reserved simple values between 20 and 31 */
163
+ if (value >= NANOCBOR_SIMPLE_FALSE && value <= NANOCBOR_SIZE_INDEFINITE) {
164
+ return NANOCBOR_ERR_INVALID_TYPE;
165
+ }
166
+ return _fmt_uint64(enc, value, NANOCBOR_MASK_FLOAT);
167
+ }
168
+
169
+ int nanocbor_fmt_bstr(nanocbor_encoder_t *enc, size_t len)
170
+ {
171
+ return _fmt_uint64(enc, (uint64_t)len, NANOCBOR_MASK_BSTR);
172
+ }
173
+
174
+ int nanocbor_fmt_tstr(nanocbor_encoder_t *enc, size_t len)
175
+ {
176
+ return _fmt_uint64(enc, (uint64_t)len, NANOCBOR_MASK_TSTR);
177
+ }
178
+
179
+ static int _put_bytes(nanocbor_encoder_t *enc, const uint8_t *str, size_t len)
180
+ {
181
+ _incr_len(enc, len);
182
+ int res = _fits(enc, len);
183
+
184
+ if (res >= 0) {
185
+ _append(enc, str, len);
186
+ return NANOCBOR_OK;
187
+ }
188
+ return res;
189
+ }
190
+
191
+ int nanocbor_put_tstr(nanocbor_encoder_t *enc, const char *str)
192
+ {
193
+ size_t len = strlen(str);
194
+
195
+ nanocbor_fmt_tstr(enc, len);
196
+ return _put_bytes(enc, (const uint8_t *)str, len);
197
+ }
198
+
199
+ int nanocbor_put_tstrn(nanocbor_encoder_t *enc, const char *str, size_t len)
200
+ {
201
+ nanocbor_fmt_tstr(enc, len);
202
+ return _put_bytes(enc, (const uint8_t *)str, len);
203
+ }
204
+
205
+ int nanocbor_put_bstr(nanocbor_encoder_t *enc, const uint8_t *str, size_t len)
206
+ {
207
+ nanocbor_fmt_bstr(enc, len);
208
+ return _put_bytes(enc, str, len);
209
+ }
210
+
211
+ int nanocbor_fmt_array(nanocbor_encoder_t *enc, size_t len)
212
+ {
213
+ return _fmt_uint64(enc, (uint64_t)len, NANOCBOR_MASK_ARR);
214
+ }
215
+
216
+ int nanocbor_fmt_map(nanocbor_encoder_t *enc, size_t len)
217
+ {
218
+ return _fmt_uint64(enc, (uint64_t)len, NANOCBOR_MASK_MAP);
219
+ }
220
+
221
+ int nanocbor_fmt_array_indefinite(nanocbor_encoder_t *enc)
222
+ {
223
+ return _fmt_single(enc, NANOCBOR_MASK_ARR | NANOCBOR_SIZE_INDEFINITE);
224
+ }
225
+
226
+ int nanocbor_fmt_map_indefinite(nanocbor_encoder_t *enc)
227
+ {
228
+ return _fmt_single(enc, NANOCBOR_MASK_MAP | NANOCBOR_SIZE_INDEFINITE);
229
+ }
230
+
231
+ int nanocbor_fmt_end_indefinite(nanocbor_encoder_t *enc)
232
+ {
233
+ /* End is marked with float major and indefinite minor number */
234
+ return _fmt_single(enc, NANOCBOR_MASK_FLOAT | NANOCBOR_SIZE_INDEFINITE);
235
+ }
236
+
237
+ int nanocbor_fmt_null(nanocbor_encoder_t *enc)
238
+ {
239
+ return _fmt_single(enc, NANOCBOR_MASK_FLOAT | NANOCBOR_SIMPLE_NULL);
240
+ }
241
+
242
+ int nanocbor_fmt_undefined(nanocbor_encoder_t *enc)
243
+ {
244
+ return _fmt_single(enc, NANOCBOR_MASK_FLOAT | NANOCBOR_SIMPLE_UNDEF);
245
+ }
246
+
247
+ /* Double bit mask related defines */
248
+ #define DOUBLE_EXP_OFFSET (1023U)
249
+ #define DOUBLE_SIZE (64U)
250
+ #define DOUBLE_EXP_POS (52U)
251
+ #define DOUBLE_SIGN_POS (63U)
252
+ #define DOUBLE_EXP_MASK ((uint64_t)0x7FFU)
253
+ #define DOUBLE_SIGN_MASK ((uint64_t)1U << DOUBLE_SIGN_POS)
254
+ #define DOUBLE_EXP_IS_NAN (0x7FFU)
255
+ #define DOUBLE_IS_ZERO (~(DOUBLE_SIGN_MASK))
256
+ #define DOUBLE_FLOAT_LOSS (0x1FFFFFFFU)
257
+
258
+ /* float bit mask related defines */
259
+ #define FLOAT_EXP_OFFSET (127U)
260
+ #define FLOAT_SIZE (32U)
261
+ #define FLOAT_EXP_POS (23U)
262
+ #define FLOAT_EXP_MASK ((uint32_t)0xFFU)
263
+ #define FLOAT_SIGN_POS (31U)
264
+ #define FLOAT_FRAC_MASK (0x7FFFFFU)
265
+ #define FLOAT_SIGN_MASK ((uint32_t)1U << FLOAT_SIGN_POS)
266
+ #define FLOAT_EXP_IS_NAN (0xFFU)
267
+ #define FLOAT_IS_ZERO (~(FLOAT_SIGN_MASK))
268
+ /* Part where a float to halffloat leads to precision loss */
269
+ #define FLOAT_HALF_LOSS (0x1FFFU)
270
+
271
+ /* halffloat bit mask related defines */
272
+ #define HALF_EXP_OFFSET (15U)
273
+ #define HALF_SIZE (16U)
274
+ #define HALF_EXP_POS (10U)
275
+ #define HALF_EXP_MASK (0x1FU)
276
+ #define HALF_SIGN_POS (15U)
277
+ #define HALF_FRAC_MASK (0x3FFU)
278
+ #define HALF_SIGN_MASK ((uint16_t)(1U << HALF_SIGN_POS))
279
+ #define HALF_MASK_HALF (0xFFU)
280
+
281
+ /* Check special cases for single precision floats */
282
+ static bool _single_is_inf_nan(uint8_t exp)
283
+ {
284
+ return exp == FLOAT_EXP_IS_NAN;
285
+ }
286
+
287
+ static bool _single_is_zero(uint32_t num)
288
+ {
289
+ return (num & FLOAT_IS_ZERO) == 0;
290
+ }
291
+
292
+ static bool _single_in_range(uint8_t exp, uint32_t num)
293
+ {
294
+ /* Check if lower 13 bits of fraction are zero, if so we might be able to
295
+ * convert without precision loss */
296
+ if (exp <= (HALF_EXP_OFFSET + FLOAT_EXP_OFFSET)
297
+ && exp >= ((-HALF_EXP_OFFSET + 1) + FLOAT_EXP_OFFSET)
298
+ && ((num & FLOAT_HALF_LOSS) == 0)) {
299
+ return true;
300
+ }
301
+ return false;
302
+ }
303
+
304
+ static int _fmt_halffloat(nanocbor_encoder_t *enc, uint16_t half)
305
+ {
306
+ _incr_len(enc, sizeof(uint16_t) + 1);
307
+ int res = _fits(enc, sizeof(uint16_t) + 1);
308
+ if (res > 0) {
309
+ uint8_t tmp[3] = {
310
+ NANOCBOR_MASK_FLOAT | NANOCBOR_SIZE_SHORT,
311
+ (half >> HALF_SIZE / 2),
312
+ half & HALF_MASK_HALF };
313
+ _append(enc, tmp, sizeof(tmp));
314
+ res = sizeof(uint16_t) + 1;
315
+ }
316
+ return res;
317
+ }
318
+
319
+ #if __SIZEOF_DOUBLE__ != __SIZEOF_FLOAT__
320
+ /* Check special cases for single precision floats */
321
+ static bool _double_is_inf_nan(uint16_t exp)
322
+ {
323
+ return (exp == DOUBLE_EXP_IS_NAN);
324
+ }
325
+
326
+ static bool _double_is_zero(uint64_t num)
327
+ {
328
+ return (num & DOUBLE_IS_ZERO) == 0;
329
+ }
330
+
331
+ static bool _double_in_range(uint16_t exp, uint64_t num)
332
+ {
333
+ /* Check if lower 13 bits of fraction are zero, if so we might be able to
334
+ * convert without precision loss */
335
+ if (exp <= (DOUBLE_EXP_OFFSET + FLOAT_EXP_OFFSET)
336
+ && exp >= (DOUBLE_EXP_OFFSET - FLOAT_EXP_OFFSET + 1)
337
+ && ((num & DOUBLE_FLOAT_LOSS) == 0)) { /* First 29 bits must be zero */
338
+ return true;
339
+ }
340
+ return false;
341
+ }
342
+ #endif
343
+
344
+ int nanocbor_fmt_float(nanocbor_encoder_t *enc, float num)
345
+ {
346
+ /* Allow bitwise access to float */
347
+ uint32_t *unum = (uint32_t *)&num;
348
+
349
+ /* Retrieve exponent */
350
+ uint8_t exp = (*unum >> FLOAT_EXP_POS) & FLOAT_EXP_MASK;
351
+ if (_single_is_inf_nan(exp) || _single_is_zero(*unum)
352
+ || _single_in_range(exp, *unum)) {
353
+ /* Copy sign bit */
354
+ uint16_t half = ((*unum >> (FLOAT_SIZE - HALF_SIZE)) & HALF_SIGN_MASK);
355
+ /* Shift exponent */
356
+ if (exp != FLOAT_EXP_IS_NAN && exp != 0) {
357
+ exp = exp + (uint8_t)(HALF_EXP_OFFSET - FLOAT_EXP_OFFSET);
358
+ }
359
+ /* Add exponent */
360
+ half |= ((exp & HALF_EXP_MASK) << HALF_EXP_POS)
361
+ | ((*unum >> (FLOAT_EXP_POS - HALF_EXP_POS)) & HALF_FRAC_MASK);
362
+ return _fmt_halffloat(enc, half);
363
+ }
364
+ /* normal float */
365
+ _incr_len(enc, sizeof(float) + 1);
366
+ int res = _fits(enc, 1 + sizeof(float));
367
+ if (res > 0) {
368
+ const uint8_t tmp = NANOCBOR_MASK_FLOAT | NANOCBOR_SIZE_WORD;
369
+ _append(enc, &tmp, sizeof(tmp));
370
+ /* NOLINTNEXTLINE: user supplied function */
371
+ uint32_t bnum = NANOCBOR_HTOBE32_FUNC(*unum);
372
+ _append(enc, (uint8_t*)&bnum, sizeof(bnum));
373
+ }
374
+ return res;
375
+ }
376
+
377
+ int nanocbor_fmt_double(nanocbor_encoder_t *enc, double num)
378
+ {
379
+ #if __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__
380
+ return nanocbor_fmt_float(enc, num);
381
+ #else
382
+ uint64_t *unum = (uint64_t *)&num;
383
+ uint16_t exp = (*unum >> DOUBLE_EXP_POS) & DOUBLE_EXP_MASK;
384
+ if (_double_is_inf_nan(exp) || _double_is_zero(*unum)
385
+ || _double_in_range(exp, *unum)) {
386
+ /* copy sign bit over */
387
+ uint32_t single
388
+ = (*unum >> (DOUBLE_SIZE - FLOAT_SIZE)) & (FLOAT_SIGN_MASK);
389
+ /* Shift exponent */
390
+ if (exp != DOUBLE_EXP_IS_NAN && exp != 0) {
391
+ exp = exp + FLOAT_EXP_OFFSET - DOUBLE_EXP_OFFSET;
392
+ }
393
+ single |= ((exp & FLOAT_EXP_MASK) << FLOAT_EXP_POS)
394
+ | ((*unum >> (DOUBLE_EXP_POS - FLOAT_EXP_POS)) & FLOAT_FRAC_MASK);
395
+ float *fsingle = (float *)&single;
396
+ return nanocbor_fmt_float(enc, *fsingle);
397
+ }
398
+ _incr_len(enc, sizeof(double) + 1);
399
+ int res = _fits(enc, 1 + sizeof(double));
400
+ if (res > 0) {
401
+ const uint8_t tmp = NANOCBOR_MASK_FLOAT | NANOCBOR_SIZE_LONG;
402
+ _append(enc, &tmp, 1);
403
+ /* NOLINTNEXTLINE: user supplied function */
404
+ uint64_t bnum = NANOCBOR_HTOBE64_FUNC(*unum);
405
+ _append(enc, (uint8_t*)&bnum, sizeof(bnum));
406
+ }
407
+ return res;
408
+ #endif
409
+ }
410
+
411
+ int nanocbor_fmt_decimal_frac(nanocbor_encoder_t *enc, int32_t e, int32_t m)
412
+ {
413
+ int res = nanocbor_fmt_tag(enc, NANOCBOR_TAG_DEC_FRAC);
414
+ res += nanocbor_fmt_array(enc, 2);
415
+ res += nanocbor_fmt_int(enc, e);
416
+ res += nanocbor_fmt_int(enc, m);
417
+ return res;
418
+ }
@@ -0,0 +1,12 @@
1
+ decoder_source = files('decoder.c')
2
+ encoder_source = files('encoder.c')
3
+
4
+ project_sources += decoder_source
5
+ project_sources += encoder_source
6
+
7
+ encoder_lib = static_library('encoder',
8
+ encoder_source,
9
+ include_directories : inc)
10
+ decoder_lib = static_library('decoder',
11
+ decoder_source,
12
+ include_directories : inc)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikrojs/native",
3
- "version": "0.13.0",
3
+ "version": "0.14.0-pr-229.g0d8db1b",
4
4
  "description": "Mikro.js C++ runtime library and Node.js native addon",
5
5
  "keywords": [
6
6
  "esp32",
@@ -25,6 +25,9 @@
25
25
  "cmake",
26
26
  "cmake.js",
27
27
  "CMakeLists.txt",
28
+ "deps/nanocbor/src",
29
+ "deps/nanocbor/include",
30
+ "deps/nanocbor/LICENSE",
28
31
  "include",
29
32
  "runtime",
30
33
  "scripts",
@@ -80,7 +83,7 @@
80
83
  "cmake-js": "^8.0.0",
81
84
  "node-addon-api": "^8.7.0",
82
85
  "node-gyp-build": "^4.8.4",
83
- "@mikrojs/quickjs": "0.13.0"
86
+ "@mikrojs/quickjs": "0.14.0-pr-229.g0d8db1b"
84
87
  },
85
88
  "devDependencies": {
86
89
  "@swc/core": "^1.15.30",
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) Bjørge Næss
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.