@mikrojs/native 0.12.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,1012 @@
1
+ /*
2
+ * SPDX-License-Identifier: CC0-1.0
3
+ */
4
+
5
+ /**
6
+ * @defgroup NanoCBOR minimalistic CBOR library
7
+ * @brief Provides a minimal CBOR library
8
+ *
9
+ * NanoCBOR is a minimal CBOR encoder. For protocols such as CoAP, OSCORE,
10
+ * SenML and CORECONF a well defined and thus predictable CBOR structure is
11
+ * required. NanoCBOR tries to fill this requirement by providing a very
12
+ * minimal CBOR encoder. Supported is:
13
+ * - All major types
14
+ * - Arrays including indefinite length arrays
15
+ * - Maps including indefinite length maps
16
+ * - Safe for decoding untrusted input
17
+ *
18
+ * Not included:
19
+ * - Date and time
20
+ * - Big numbers (numbers encoded as byte strings)
21
+ *
22
+ * @{
23
+ *
24
+ * @file
25
+ * @see [rfc 7049](https://tools.ietf.org/html/rfc7049)
26
+ *
27
+ * @author Koen Zandberg <koen@bergzand.net>
28
+ */
29
+
30
+ #ifndef NANOCBOR_NANOCBOR_H
31
+ #define NANOCBOR_NANOCBOR_H
32
+
33
+ #include <stdbool.h>
34
+ #include <stdint.h>
35
+ #include <stdlib.h>
36
+
37
+ #ifdef __cplusplus
38
+ extern "C" {
39
+ #endif
40
+
41
+ #define NANOCBOR_TYPE_OFFSET (5U) /**< Bit shift for CBOR major types */
42
+ #define NANOCBOR_TYPE_MASK 0xE0U /**< Mask for CBOR major types */
43
+ #define NANOCBOR_VALUE_MASK 0x1FU /**< Mask for CBOR values */
44
+
45
+ /**
46
+ * @name CBOR type numbers
47
+ * @{
48
+ */
49
+ #define NANOCBOR_TYPE_UINT (0x00U) /**< positive integer type */
50
+ #define NANOCBOR_TYPE_NINT (0x01U) /**< negative integer type */
51
+ #define NANOCBOR_TYPE_BSTR (0x02U) /**< byte string type */
52
+ #define NANOCBOR_TYPE_TSTR (0x03U) /**< text string type */
53
+ #define NANOCBOR_TYPE_ARR (0x04U) /**< array type */
54
+ #define NANOCBOR_TYPE_MAP (0x05U) /**< map type */
55
+ #define NANOCBOR_TYPE_TAG (0x06U) /**< tag type */
56
+ #define NANOCBOR_TYPE_FLOAT (0x07U) /**< float type */
57
+ /** @} */
58
+
59
+ /**
60
+ * @name CBOR major types including the bit shift
61
+ * @{
62
+ */
63
+ #define NANOCBOR_MASK_UINT (NANOCBOR_TYPE_UINT << NANOCBOR_TYPE_OFFSET)
64
+ #define NANOCBOR_MASK_NINT (NANOCBOR_TYPE_NINT << NANOCBOR_TYPE_OFFSET)
65
+ #define NANOCBOR_MASK_BSTR (NANOCBOR_TYPE_BSTR << NANOCBOR_TYPE_OFFSET)
66
+ #define NANOCBOR_MASK_TSTR (NANOCBOR_TYPE_TSTR << NANOCBOR_TYPE_OFFSET)
67
+ #define NANOCBOR_MASK_ARR (NANOCBOR_TYPE_ARR << NANOCBOR_TYPE_OFFSET)
68
+ #define NANOCBOR_MASK_MAP (NANOCBOR_TYPE_MAP << NANOCBOR_TYPE_OFFSET)
69
+ #define NANOCBOR_MASK_TAG (NANOCBOR_TYPE_TAG << NANOCBOR_TYPE_OFFSET)
70
+ #define NANOCBOR_MASK_FLOAT (NANOCBOR_TYPE_FLOAT << NANOCBOR_TYPE_OFFSET)
71
+ /** @} */
72
+
73
+ /**
74
+ * @name CBOR simple data types
75
+ * @{
76
+ */
77
+ #define NANOCBOR_SIMPLE_FALSE 20U /**< False */
78
+ #define NANOCBOR_SIMPLE_TRUE 21U /**< True */
79
+ #define NANOCBOR_SIMPLE_NULL 22U /**< NULL */
80
+ #define NANOCBOR_SIMPLE_UNDEF 23U /**< Undefined */
81
+ /** @} */
82
+
83
+ /**
84
+ * @name CBOR data sizes
85
+ * @{
86
+ */
87
+ #define NANOCBOR_SIZE_BYTE 24U /**< Value contained in a byte */
88
+ #define NANOCBOR_SIZE_SHORT 25U /**< Value contained in a short */
89
+ #define NANOCBOR_SIZE_WORD 26U /**< Value contained in a word */
90
+ #define NANOCBOR_SIZE_LONG 27U /**< Value contained in a long */
91
+ #define NANOCBOR_SIZE_INDEFINITE 31U /**< Indefinite sized container */
92
+ /** @} */
93
+
94
+ /**
95
+ * @name CBOR Tag values
96
+ * @{
97
+ */
98
+ #define NANOCBOR_TAG_DATE_TIME (0x0) /**< Standard date/time string */
99
+ #define NANOCBOR_TAG_EPOCH (0x1) /**< Epoch-based date/time */
100
+ #define NANOCBOR_TAG_BIGNUMS_P (0x2) /**< Positive bignum */
101
+ #define NANOCBOR_TAG_BIGNUMS_N (0x3) /**< Negative bignum */
102
+ #define NANOCBOR_TAG_DEC_FRAC (0x4) /**< Decimal Fraction */
103
+ #define NANOCBOR_TAG_BIGFLOATS (0x5) /**< Bigfloat */
104
+ /** @} */
105
+
106
+ /**
107
+ * @brief NanoCBOR decoder errors
108
+ */
109
+ typedef enum {
110
+ /**
111
+ * @brief No error
112
+ */
113
+ NANOCBOR_OK = 0,
114
+
115
+ /**
116
+ * @brief Overflow in the getter. This can happen due to retrieving a
117
+ * number size larger than the function provides
118
+ */
119
+ NANOCBOR_ERR_OVERFLOW = -1,
120
+
121
+ /**
122
+ * Decoder get function attempts to retrieve the wrong type
123
+ */
124
+ NANOCBOR_ERR_INVALID_TYPE = -2,
125
+
126
+ /**
127
+ * @brief decoder is beyond the end of the buffer
128
+ */
129
+ NANOCBOR_ERR_END = -3,
130
+
131
+ /**
132
+ * @brief Decoder hits the recursion limit
133
+ */
134
+ NANOCBOR_ERR_RECURSION = -4,
135
+
136
+ /**
137
+ * @brief Decoder could not find the requested entry
138
+ */
139
+ NANOCBOR_NOT_FOUND = -5,
140
+
141
+ /**
142
+ * @brief Decoder detected wrong usage, e.g., leaving a container
143
+ * before reaching its end. This is a programming mistake
144
+ * and can be asserted upon by the caller.
145
+ */
146
+ NANOCOBR_PANIC_INVALID_OPERATION = -6,
147
+ } nanocbor_error_t;
148
+
149
+ /**
150
+ * @brief decoder context
151
+ */
152
+ typedef struct nanocbor_value {
153
+ const uint8_t *cur; /**< Current position in the buffer */
154
+ const uint8_t *end; /**< End of the buffer */
155
+ uint64_t remaining; /**< Number of items remaining in the container */
156
+ uint8_t flags; /**< Flags for decoding hints */
157
+ } nanocbor_value_t;
158
+
159
+ /**
160
+ * @brief Encoder context forward declaration
161
+ */
162
+ typedef struct nanocbor_encoder nanocbor_encoder_t;
163
+
164
+ /**
165
+ * @name encoder streaming functions
166
+ * @{
167
+ */
168
+
169
+ /**
170
+ * @brief Fits function for streaming encoder data
171
+ *
172
+ * This function is called to check whether the data that will be supplied can
173
+ * be consumed by the interface.
174
+ *
175
+ * The append function will only be called if this function returns true. The
176
+ * amount of bytes checked by this call can be used by multiple successive
177
+ * @ref nanocbor_encoder_append calls
178
+ *
179
+ * @param enc The encoder context struct
180
+ * @param ctx The context ptr supplied in the
181
+ * @ref nanocbor_encoder_stream_init call
182
+ * @param len Length of the data in bytes that will be supplied
183
+ */
184
+ typedef bool (*nanocbor_encoder_fits)(nanocbor_encoder_t *enc, void *ctx, size_t len);
185
+
186
+ /**
187
+ * @brief Append function for streaming encoder data
188
+ *
189
+ * This is a user supplied function for the polymorphic encoder interface. It
190
+ * will only be called if a previous call to @ref nanocbor_encoder_fits returned
191
+ * true.
192
+ *
193
+ * @param enc The encoder context struct
194
+ * @param ctx The context ptr supplied in the
195
+ * @ref nanocbor_encoder_stream_init call
196
+ * @param data Data emitted by the encoder
197
+ * @param len Length of the data in bytes
198
+ */
199
+ typedef void (*nanocbor_encoder_append)(nanocbor_encoder_t *enc, void *ctx, const uint8_t *data, size_t len);
200
+
201
+ /** @} */
202
+
203
+ /**
204
+ * @brief encoder context
205
+ */
206
+ struct nanocbor_encoder {
207
+ size_t len; /**< Length in bytes of supplied cbor data. Incremented
208
+ * separate from the buffer check */
209
+ nanocbor_encoder_append append; /**< Function used to append encoded data */
210
+ nanocbor_encoder_fits fits; /** Function used to check encoded length */
211
+ union {
212
+ uint8_t *cur; /**< Current position in the buffer, unioned to keep
213
+ * compatibility */
214
+ void *context; /**< Context ptr supplied to the custom functions */
215
+ };
216
+ uint8_t *end; /**< end of the buffer */
217
+ };
218
+
219
+ /**
220
+ * @name decoder flags
221
+ * @{
222
+ */
223
+
224
+ /**
225
+ * @brief decoder value is inside a container
226
+ */
227
+ #define NANOCBOR_DECODER_FLAG_CONTAINER (0x01U)
228
+
229
+ /**
230
+ * @brief decoder value is inside an indefinite length container
231
+ */
232
+ #define NANOCBOR_DECODER_FLAG_INDEFINITE (0x02U)
233
+ /** @} */
234
+
235
+ /**
236
+ * @name NanoCBOR parser functions
237
+ * @{
238
+ */
239
+
240
+ /**
241
+ * @brief Initialize a decoder context decoding the CBOR structure from @p buf
242
+ * with @p len bytes
243
+ *
244
+ * The decoder will attempt to decode CBOR types until the buffer is exhausted
245
+ *
246
+ * @param[in] value decoder value context
247
+ * @param[in] buf Buffer to decode from
248
+ * @param[in] len Length in bytes of the buffer
249
+ */
250
+ void nanocbor_decoder_init(nanocbor_value_t *value, const uint8_t *buf,
251
+ size_t len);
252
+
253
+ /**
254
+ * @brief Retrieve the type of the CBOR value at the current position
255
+ *
256
+ * @param[in] value decoder value context
257
+ *
258
+ * @return major type
259
+ * @return NANOCBOR_ERR_END if the buffer is exhausted
260
+ */
261
+ int nanocbor_get_type(const nanocbor_value_t *value);
262
+
263
+ /**
264
+ * @brief Check if the current buffer or container is exhausted
265
+ *
266
+ * @param[in] it decoder value context
267
+ *
268
+ * @return true if it is exhausted
269
+ * @return false if there are more items
270
+ */
271
+ bool nanocbor_at_end(const nanocbor_value_t *it);
272
+
273
+ /**
274
+ * @brief Retrieve a positive integer as uint8_t from the stream
275
+ *
276
+ * If the value at `cvalue` is greater than 8 bit (> 255), error is returned.
277
+ *
278
+ * The resulting @p value is undefined if the result is an error condition
279
+ *
280
+ * @param[in] cvalue CBOR value to decode from
281
+ * @param[out] value returned positive integer
282
+ *
283
+ * @return number of bytes read
284
+ * @return negative on error
285
+ */
286
+ int nanocbor_get_uint8(nanocbor_value_t *cvalue, uint8_t *value);
287
+
288
+ /**
289
+ * @brief Retrieve a positive integer as uint16_t from the stream
290
+ *
291
+ * If the value at `cvalue` is greater than 16 bit (> 65535), error is returned.
292
+ *
293
+ * The resulting @p value is undefined if the result is an error condition
294
+ *
295
+ * @param[in] cvalue CBOR value to decode from
296
+ * @param[out] value returned positive integer
297
+ *
298
+ * @return number of bytes read
299
+ * @return negative on error
300
+ */
301
+ int nanocbor_get_uint16(nanocbor_value_t *cvalue, uint16_t *value);
302
+
303
+ /**
304
+ * @brief Retrieve a positive integer as uint32_t from the stream
305
+ *
306
+ * If the value at `cvalue` is greater than 32 bit, error is returned.
307
+ *
308
+ * The resulting @p value is undefined if the result is an error condition
309
+ *
310
+ * @param[in] cvalue CBOR value to decode from
311
+ * @param[out] value returned positive integer
312
+ *
313
+ * @return number of bytes read
314
+ * @return negative on error
315
+ */
316
+ int nanocbor_get_uint32(nanocbor_value_t *cvalue, uint32_t *value);
317
+
318
+ /**
319
+ * @brief Retrieve a positive integer as uint64_t from the stream
320
+ *
321
+ * If the value at `cvalue` is greater than 64 bit, error is returned.
322
+ *
323
+ * The resulting @p value is undefined if the result is an error condition
324
+ *
325
+ * @param[in] cvalue CBOR value to decode from
326
+ * @param[out] value returned positive integer
327
+ *
328
+ * @return number of bytes read
329
+ * @return negative on error
330
+ */
331
+ int nanocbor_get_uint64(nanocbor_value_t *cvalue, uint64_t *value);
332
+
333
+ /**
334
+ * @brief Retrieve a signed integer as int8_t from the stream
335
+ *
336
+ * If the value at `cvalue` is greater than 8 bit (< -128 or > 127),
337
+ * error is returned.
338
+ *
339
+ * The resulting @p value is undefined if the result is an error condition
340
+ *
341
+ * @param[in] cvalue CBOR value to decode from
342
+ * @param[out] value returned signed integer
343
+ *
344
+ * @return number of bytes read
345
+ * @return negative on error
346
+ */
347
+ int nanocbor_get_int8(nanocbor_value_t *cvalue, int8_t *value);
348
+
349
+ /**
350
+ * @brief Retrieve a signed integer as int16_t from the stream
351
+ *
352
+ * If the value at `cvalue` is greater than 16 bit (< -32768 or > 32767),
353
+ * error is returned.
354
+ *
355
+ * The resulting @p value is undefined if the result is an error condition
356
+ *
357
+ * @param[in] cvalue CBOR value to decode from
358
+ * @param[out] value returned signed integer
359
+ *
360
+ * @return number of bytes read
361
+ * @return negative on error
362
+ */
363
+ int nanocbor_get_int16(nanocbor_value_t *cvalue, int16_t *value);
364
+
365
+ /**
366
+ * @brief Retrieve a signed integer as int32_t from the stream
367
+ *
368
+ * If the value at `cvalue` is greater than 32 bit, error is returned.
369
+ *
370
+ * The resulting @p value is undefined if the result is an error condition
371
+ *
372
+ * @param[in] cvalue CBOR value to decode from
373
+ * @param[out] value returned signed integer
374
+ *
375
+ * @return number of bytes read
376
+ * @return negative on error
377
+ */
378
+ int nanocbor_get_int32(nanocbor_value_t *cvalue, int32_t *value);
379
+
380
+ /**
381
+ * @brief Retrieve a signed integer as int64_t from the stream
382
+ *
383
+ * If the value at `cvalue` is greater than 64 bit, error is returned.
384
+ *
385
+ * The resulting @p value is undefined if the result is an error condition
386
+ *
387
+ * @param[in] cvalue CBOR value to decode from
388
+ * @param[out] value returned signed integer
389
+ *
390
+ * @return number of bytes read
391
+ * @return negative on error
392
+ */
393
+ int nanocbor_get_int64(nanocbor_value_t *cvalue, int64_t *value);
394
+
395
+ /**
396
+ * @brief Retrieve a decimal fraction from the stream as a int32_t mantisa and
397
+ * int32_t exponent
398
+ *
399
+ * If the value at `cvalue` is greater than 32 bit, error is returned.
400
+ *
401
+ * The resulting @p value is undefined if the result is an error condition
402
+ *
403
+ * @param[in] cvalue CBOR value to decode from
404
+ * @param[out] m returned mantisa
405
+ * @param[out] e returned exponent
406
+ *
407
+ * @return NANOCBOR_OK on success
408
+ * @return negative on error
409
+ */
410
+ int nanocbor_get_decimal_frac(nanocbor_value_t *cvalue, int32_t *e, int32_t *m);
411
+
412
+ /**
413
+ * @brief Retrieve a byte string from the stream
414
+ *
415
+ * The resulting @p buf and @p len are undefined if the result is an error
416
+ * condition
417
+ *
418
+ * @param[in] cvalue CBOR value to decode from
419
+ * @param[out] buf pointer to the byte string
420
+ * @param[out] len length of the byte string
421
+ *
422
+ * @return NANOCBOR_OK on success
423
+ * @return negative on error
424
+ */
425
+ int nanocbor_get_bstr(nanocbor_value_t *cvalue, const uint8_t **buf,
426
+ size_t *len);
427
+
428
+ /**
429
+ * @brief Retrieve a text string from the stream
430
+ *
431
+ * The resulting @p buf and @p len are undefined if the result is an error
432
+ * condition
433
+ *
434
+ * @param[in] cvalue CBOR value to decode from
435
+ * @param[out] buf pointer to the text string
436
+ * @param[out] len length of the text string
437
+ *
438
+ * @return NANOCBOR_OK on success
439
+ * @return negative on error
440
+ */
441
+ int nanocbor_get_tstr(nanocbor_value_t *cvalue, const uint8_t **buf,
442
+ size_t *len);
443
+
444
+ /**
445
+ * @brief Search for a tstr key in a map.
446
+ *
447
+ * The resulting @p value is undefined if @p key was not found.
448
+ *
449
+ * @pre @p start is inside a map
450
+ *
451
+ * @param[in] start pointer to the map to search
452
+ * @param[in] key pointer to the text string key
453
+ * @param[out] value pointer to the tstr value containing @p key if found
454
+ *
455
+ * @return NANOCBOR_OK if @p key was found
456
+ * @return negative on error / not found
457
+ */
458
+ int nanocbor_get_key_tstr(nanocbor_value_t *start, const char *key,
459
+ nanocbor_value_t *value);
460
+
461
+ /**
462
+ * @brief Enter a array type
463
+ *
464
+ * @param[in] it CBOR value to decode from
465
+ * @param[out] array CBOR value to decode the array members with
466
+ *
467
+ * @return NANOCBOR_OK on success
468
+ * @return negative on error
469
+ */
470
+ int nanocbor_enter_array(const nanocbor_value_t *it, nanocbor_value_t *array);
471
+
472
+ /**
473
+ * @brief Enter a map type
474
+ *
475
+ * @param[in] it CBOR value to decode from
476
+ * @param[out] map CBOR value to decode the map members with
477
+ *
478
+ * @return NANOCBOR_OK on success
479
+ * @return negative on error
480
+ */
481
+ int nanocbor_enter_map(const nanocbor_value_t *it, nanocbor_value_t *map);
482
+
483
+ /**
484
+ * @brief leave the container
485
+ *
486
+ * This must be called with the same @ref nanocbor_value_t struct that was used
487
+ * to enter the container. Furthermore, the @p container must be at the end of
488
+ * the container.
489
+ *
490
+ * @param[in] it parent CBOR structure
491
+ * @param[in] container exhausted CBOR container
492
+ *
493
+ * @return NANOCBOR_OK on success
494
+ * @return NANOCBOR_PANIC_INVALID_OPERATION on detection of wrong usage
495
+ */
496
+ int nanocbor_leave_container(nanocbor_value_t *it,
497
+ nanocbor_value_t *container);
498
+
499
+ /**
500
+ * @brief Retrieve a tag as positive uint32_t from the stream
501
+ *
502
+ * The resulting @p value is undefined if the result is an error condition
503
+ *
504
+ * @param[in] cvalue CBOR value to decode from
505
+ * @param[out] tag returned tag as positive integer
506
+ *
507
+ * @return NANOCBOR_OK on success
508
+ */
509
+ int nanocbor_get_tag(nanocbor_value_t *cvalue, uint32_t *tag);
510
+
511
+ /**
512
+ * @brief Retrieve a tag as positive uint64_t from the stream
513
+ *
514
+ * The resulting @p value is undefined if the result is an error condition
515
+ *
516
+ * @param[in] cvalue CBOR value to decode from
517
+ * @param[out] tag returned tag as positive integer
518
+ *
519
+ * @return NANOCBOR_OK on success
520
+ */
521
+ int nanocbor_get_tag64(nanocbor_value_t *cvalue, uint64_t *tag);
522
+
523
+ /**
524
+ * @brief Retrieve a null value from the stream
525
+ *
526
+ * This function checks if the next CBOR value is a NULL value and advances to
527
+ * the next value if no error is detected
528
+ *
529
+ * @param[in] cvalue CBOR value to decode from
530
+ *
531
+ * @return NANOCBOR_OK on success
532
+ * @return negative on error
533
+ */
534
+ int nanocbor_get_null(nanocbor_value_t *cvalue);
535
+
536
+ /**
537
+ * @brief Retrieve a boolean value from the stream
538
+ *
539
+ * @param[in] cvalue CBOR value to decode from
540
+ * @param[out] value Boolean value retrieved from the stream
541
+ *
542
+ * @return NANOCBOR_OK on success
543
+ * @return negative on error
544
+ */
545
+ int nanocbor_get_bool(nanocbor_value_t *cvalue, bool *value);
546
+
547
+ /**
548
+ * @brief Retrieve a simple value of undefined from the stream
549
+ *
550
+ * @param[in] cvalue CBOR value to decode from
551
+ *
552
+ * @return NANOCBOR_OK on success
553
+ * @return negative on error
554
+ */
555
+ int nanocbor_get_undefined(nanocbor_value_t *cvalue);
556
+
557
+ /**
558
+ * @brief Retrieve a simple value as integer from the stream
559
+ *
560
+ * This function returns the simple value as uint8_t value and skips decoding
561
+ * the meaning of the values. For example, a CBOR true is returned as value 21.
562
+ *
563
+ * @param[in] cvalue CBOR value to decode from
564
+ * @param[out] value Simple value retrieved from the stream
565
+ *
566
+ * @return NANOCBOR_OK on success
567
+ * @return negative on error
568
+ */
569
+ int nanocbor_get_simple(nanocbor_value_t *cvalue, uint8_t *value);
570
+
571
+ /**
572
+ * @brief Retrieve a float value from the stream.
573
+ *
574
+ * This function automatically converts CBOR half floats into 32 bit floating
575
+ * points.
576
+ *
577
+ * @note This function assumes the host uses ieee754 to represent floating point
578
+ * numbers
579
+ *
580
+ * @param[in] cvalue CBOR value to decode from
581
+ * @param[out] value Simple value retrieved from the stream
582
+ *
583
+ * @return number of bytes read on success
584
+ * @return negative on error
585
+ */
586
+ int nanocbor_get_float(nanocbor_value_t *cvalue, float *value);
587
+
588
+ /**
589
+ * @brief Retrieve a double-sized floating point value from the stream.
590
+ *
591
+ * This function automatically converts CBOR half floats and 32 bit floats into
592
+ * into 64 bit floating points.
593
+ *
594
+ * @note This function assumes the host uses ieee754 to represent floating point
595
+ * numbers
596
+ *
597
+ * @param[in] cvalue CBOR value to decode from
598
+ * @param[out] value Simple value retrieved from the stream
599
+ *
600
+ * @return number of bytes read on success
601
+ * @return negative on error
602
+ */
603
+ int nanocbor_get_double(nanocbor_value_t *cvalue, double *value);
604
+
605
+ /**
606
+ * @brief Skip to the next value in the CBOR stream
607
+ *
608
+ * This function is able to skip over nested structures in the CBOR stream
609
+ * such as (nested) arrays and maps. For indefinite length containers,
610
+ * it resorts to limited recursion to do so.
611
+ *
612
+ * Recursion is limited with @ref NANOCBOR_RECURSION_MAX
613
+ *
614
+ * @param[in] it CBOR stream to skip a value from
615
+ *
616
+ * @return NANOCBOR_OK on success
617
+ * @return negative on error
618
+ */
619
+ int nanocbor_skip(nanocbor_value_t *it);
620
+
621
+ /**
622
+ * @brief Skip a single simple value in the CBOR stream
623
+ *
624
+ * This is a cheaper version of @ref nanocbor_skip, the downside is that this
625
+ * function is unable to skip nested structures, i.e., tags, maps and arrays.
626
+ *
627
+ * @param[in] it CBOR value to skip
628
+ *
629
+ * @return NANOCBOR_OK on success
630
+ * @return negative on error
631
+ */
632
+ int nanocbor_skip_simple(nanocbor_value_t *it);
633
+
634
+ /**
635
+ * @brief Retrieve part of the CBOR stream for separate parsing
636
+ *
637
+ * This function retrieves the pointer and length of a single CBOR item. This
638
+ * item can be stored for later processing.
639
+ *
640
+ * @param[in] it CBOR value to retrieve
641
+ * @param[out] start start of the CBOR item
642
+ * @param[out] len length of the CBOR item
643
+ *
644
+ * @return NANOCBOR_OK on success
645
+ * @return negative on error
646
+ */
647
+ int nanocbor_get_subcbor(nanocbor_value_t *it, const uint8_t **start,
648
+ size_t *len);
649
+
650
+ /**
651
+ * @brief Retrieve the number of remaining values in a CBOR container: either array or map
652
+ *
653
+ * The returned value is undefined when not inside a container or when the
654
+ * container is of indefinite length. For a map, the number is the full number
655
+ * of CBOR items remaining (twice the number of key/value pairs).
656
+ *
657
+ * See also nanocbor_array_items_remaining and nanocbor_map_items_remaining
658
+ *
659
+ * @param[in] value value inside a CBOR container
660
+ *
661
+ * @return number of items remaining
662
+ */
663
+ static inline uint32_t
664
+ nanocbor_container_remaining(const nanocbor_value_t *value)
665
+ {
666
+ return value->remaining;
667
+ }
668
+
669
+ /**
670
+ * @brief Retrieve the number of remaining items in a CBOR array
671
+ *
672
+ * The returned value is undefined when not inside an array or when the
673
+ * array is of indefinite length.
674
+ *
675
+ * @param[in] value nanocbor value inside a CBOR array
676
+ *
677
+ * @return number of array items remaining
678
+ */
679
+ static inline uint32_t
680
+ nanocbor_array_items_remaining(const nanocbor_value_t *value)
681
+ {
682
+ return nanocbor_container_remaining(value);
683
+ }
684
+
685
+ /**
686
+ * @brief Retrieve the number of remaining values in a CBOR map
687
+ *
688
+ * The returned value is undefined when not inside a map or when the
689
+ * container is of indefinite length.
690
+ *
691
+ * @param[in] value nanocbor value inside a CBOR map
692
+ *
693
+ * @return number of key/value pairs remaining
694
+ */
695
+ static inline uint32_t
696
+ nanocbor_map_items_remaining(const nanocbor_value_t *value)
697
+ {
698
+ return nanocbor_container_remaining(value)/2;
699
+ }
700
+
701
+ /**
702
+ * @brief Check whether a container is an indefinite-length container
703
+ *
704
+ * @param[in] container value inside a CBOR container
705
+ *
706
+ * @return True when the container is indefinite in length
707
+ * @return False when not indefinite-length or not in a
708
+ * container
709
+ */
710
+ static inline bool
711
+ nanocbor_container_indefinite(const nanocbor_value_t *container)
712
+ {
713
+ return (container->flags
714
+ == (NANOCBOR_DECODER_FLAG_INDEFINITE
715
+ | NANOCBOR_DECODER_FLAG_CONTAINER));
716
+ }
717
+
718
+ static inline bool nanocbor_in_container(const nanocbor_value_t *container)
719
+ {
720
+ return container->flags & (NANOCBOR_DECODER_FLAG_CONTAINER);
721
+ }
722
+
723
+ /** @} */
724
+
725
+ /**
726
+ * @name NanoCBOR encoder functions
727
+ * @{
728
+ */
729
+
730
+ /**
731
+ * @brief Initializes an encoder context with a memory buffer.
732
+ *
733
+ * It is safe to pass `NULL` to @p buf with @p len is `0` to determine the size
734
+ * of a CBOR structure.
735
+ *
736
+ * @param[in] enc Encoder context
737
+ * @param[in] buf Buffer to write into
738
+ * @param[in] len length of the buffer
739
+ */
740
+ void nanocbor_encoder_init(nanocbor_encoder_t *enc, uint8_t *buf, size_t len);
741
+
742
+ /**
743
+ * @brief Initializes an encoder context with custom append and fits functions.
744
+ *
745
+ * @param[in] enc Encoder context
746
+ * @param[in] ctx Context pointer
747
+ * @param[in] append_func Called to append emitted encoder data
748
+ * @param[in] fits_func Called to check if data can be consumed
749
+ */
750
+ void nanocbor_encoder_stream_init(nanocbor_encoder_t *enc, void *ctx,
751
+ nanocbor_encoder_append append_func,
752
+ nanocbor_encoder_fits fits_func);
753
+
754
+ /**
755
+ * @brief Retrieve the encoded length of the CBOR structure
756
+ *
757
+ * This function doesn't take the length of the buffer supplied to
758
+ * @ref nanocbor_encoder_init into account, it only returns the number of bytes
759
+ * the current CBOR structure would take up.
760
+ *
761
+ * @param[in] enc Encoder context
762
+ *
763
+ * @return Length of the encoded structure
764
+ */
765
+ size_t nanocbor_encoded_len(nanocbor_encoder_t *enc);
766
+
767
+ /**
768
+ * @brief Write a CBOR boolean value into a buffer
769
+ *
770
+ * @param[in] enc Encoder context
771
+ * @param[in] content Boolean value to write
772
+ *
773
+ * @return Number of bytes written
774
+ * @return Negative on error
775
+ */
776
+ int nanocbor_fmt_bool(nanocbor_encoder_t *enc, bool content);
777
+
778
+ /**
779
+ * @brief Write an unsigned integer of at most sizeof uint64_t into the buffer
780
+ *
781
+ * @param[in] enc Encoder context
782
+ * @param[in] num unsigned integer to write
783
+ *
784
+ * @return number of bytes written
785
+ * @return Negative on error
786
+ */
787
+ int nanocbor_fmt_uint(nanocbor_encoder_t *enc, uint64_t num);
788
+
789
+ /**
790
+ * @brief Write a CBOR tag of at most sizeof uint64_t into the buffer
791
+ *
792
+ * @param[in] enc Encoder context
793
+ * @param[in] num tag value to write into the buffer
794
+ *
795
+ * @return number of bytes written
796
+ * @return Negative on error
797
+ */
798
+ int nanocbor_fmt_tag(nanocbor_encoder_t *enc, uint64_t num);
799
+
800
+ /**
801
+ * @brief Write a signed integer of at most sizeof int32_t into the buffer
802
+ *
803
+ * If it is not certain if the data is signed, use this function.
804
+ *
805
+ * @param[in] enc Encoder context
806
+ * @param[in] num unsigned integer to write
807
+ *
808
+ * @return number of bytes written
809
+ * @return Negative on error
810
+ */
811
+ int nanocbor_fmt_int(nanocbor_encoder_t *enc, int64_t num);
812
+
813
+ /**
814
+ * @brief Write a CBOR simple value into the encoder buffer
815
+ *
816
+ * Disallows assigned and reserved simple values between 20 and 31.
817
+ * Please use the respective functions for emitting true, false, undefined, and null.
818
+ *
819
+ * @param[in] enc Encoder context
820
+ * @param[in] value Simple value to write
821
+ *
822
+ * @return Number of bytes written
823
+ * @return Negative on error
824
+ */
825
+ int nanocbor_fmt_simple(nanocbor_encoder_t *enc, uint8_t value);
826
+
827
+ /**
828
+ * @brief Write a byte string indicator for a byte string with specific length
829
+ * into the encoder buffer
830
+ *
831
+ * This doesn't write any byte string into the encoder buffer, only the type
832
+ * and length indicator for the byte string
833
+ *
834
+ * @param[in] enc Encoder context
835
+ * @param[in] len Length of the byte string
836
+ *
837
+ * @return number of bytes written
838
+ * @return Negative on error
839
+ */
840
+ int nanocbor_fmt_bstr(nanocbor_encoder_t *enc, size_t len);
841
+
842
+ /**
843
+ * @brief Write a text string indicator for a string with specific length
844
+ * into the encoder buffer
845
+ *
846
+ * This doesn't write any text string into the encoder buffer, only the type
847
+ * and length indicator for the text string
848
+ *
849
+ * @param[in] enc Encoder context
850
+ * @param[in] len Length of the text string
851
+ *
852
+ * @return number of bytes written
853
+ * @return Negative on error
854
+ */
855
+ int nanocbor_fmt_tstr(nanocbor_encoder_t *enc, size_t len);
856
+
857
+ /**
858
+ * @brief Copy a byte string with indicator into the encoder buffer
859
+ *
860
+ * @param[in] enc Encoder context
861
+ * @param[in] str byte string to encode
862
+ * @param[in] len Length of the string
863
+ *
864
+ * @return NANOCBOR_OK if the string fits
865
+ * @return Negative on error
866
+ */
867
+ int nanocbor_put_bstr(nanocbor_encoder_t *enc, const uint8_t *str, size_t len);
868
+
869
+ /**
870
+ * @brief Copy a text string with indicator into the encoder buffer
871
+ *
872
+ * @param[in] enc Encoder context
873
+ * @param[in] str null terminated text string to encode
874
+ *
875
+ * @return NANOCBOR_OK if the string fits
876
+ * @return Negative on error
877
+ */
878
+ int nanocbor_put_tstr(nanocbor_encoder_t *enc, const char *str);
879
+
880
+ /**
881
+ * @brief Copy n bytes of a text string with indicator into the encoder buffer
882
+ *
883
+ * @param[in] enc Encoder context
884
+ * @param[in] str text string to encode
885
+ * @param[in] len number of string bytes to copy
886
+ *
887
+ * @return NANOCBOR_OK if the string fits
888
+ * @return Negative on error
889
+ */
890
+ int nanocbor_put_tstrn(nanocbor_encoder_t *enc, const char *str, size_t len);
891
+
892
+ /**
893
+ * @brief Write an array indicator with @p len items
894
+ *
895
+ * It is assumed that the calling code will encode @p len items after calling
896
+ * this function. The array automatically terminates after @p len items are
897
+ * added, no function to close the container is necessary.
898
+ *
899
+ * @param[in] enc Encoder context
900
+ * @param[in] len Number of items in the array
901
+ *
902
+ * @return Number of bytes written
903
+ * @return Negative on error
904
+ */
905
+ int nanocbor_fmt_array(nanocbor_encoder_t *enc, size_t len);
906
+
907
+ /**
908
+ * @brief Write a map indicator with @p len pairs
909
+ *
910
+ * It is assumed that the calling code will encode @p len item pairs after
911
+ * calling this function. The array automatically terminates after @p len item
912
+ * pairs are added, no function to close the container is necessary.
913
+ *
914
+ * @param[in] enc Encoder context
915
+ * @param[in] len Number of pairs in the map
916
+ *
917
+ * @return Number of bytes written
918
+ * @return Negative on error
919
+ */
920
+ int nanocbor_fmt_map(nanocbor_encoder_t *enc, size_t len);
921
+
922
+ /**
923
+ * @brief Write an indefinite-length array indicator
924
+ *
925
+ * @param[in] enc Encoder context
926
+ *
927
+ * @return Number of bytes written
928
+ * @return Negative on error
929
+ */
930
+ int nanocbor_fmt_array_indefinite(nanocbor_encoder_t *enc);
931
+
932
+ /**
933
+ * @brief Write an indefinite-length map indicator
934
+ *
935
+ * @param[in] enc Encoder context
936
+ *
937
+ * @return Number of bytes written
938
+ * @return Negative on error
939
+ */
940
+ int nanocbor_fmt_map_indefinite(nanocbor_encoder_t *enc);
941
+
942
+ /**
943
+ * @brief Write a stop code for indefinite length containers
944
+ *
945
+ * @param[in] enc Encoder context
946
+ *
947
+ * @return Number of bytes written
948
+ * @return Negative on error
949
+ */
950
+ int nanocbor_fmt_end_indefinite(nanocbor_encoder_t *enc);
951
+
952
+ /**
953
+ * @brief Write a Null value into the encoder buffer
954
+ *
955
+ * @param[in] enc Encoder context
956
+ *
957
+ * @return NANOCBOR_OK
958
+ * @return Negative on error
959
+ */
960
+ int nanocbor_fmt_null(nanocbor_encoder_t *enc);
961
+
962
+ /**
963
+ * @brief Write an Undefined value into the encoder buffer
964
+ *
965
+ * @param[in] enc Encoder context
966
+ *
967
+ * @return NANOCBOR_OK
968
+ * @return Negative on error
969
+ */
970
+ int nanocbor_fmt_undefined(nanocbor_encoder_t *enc);
971
+
972
+ /**
973
+ * @brief Write a float value into the encoder buffer
974
+ *
975
+ * @param[in] enc Encoder context
976
+ * @param[in] num Floating point to encode
977
+ *
978
+ * @return Number of bytes written
979
+ * @return Negative on error
980
+ */
981
+ int nanocbor_fmt_float(nanocbor_encoder_t *enc, float num);
982
+
983
+ /**
984
+ * @brief Write a double floating point value into the encoder buffer
985
+ *
986
+ * @param[in] enc Encoder context
987
+ * @param[in] num Floating point to encode
988
+ *
989
+ * @return Number of bytes written
990
+ * @return Negative on error
991
+ */
992
+ int nanocbor_fmt_double(nanocbor_encoder_t *enc, double num);
993
+
994
+ /**
995
+ * @brief Write a decimal fraction into the encoder buffer
996
+ *
997
+ * @param[in] enc Encoder context
998
+ * @param[in] m Mantisa
999
+ * @param[in] e Exponent
1000
+ *
1001
+ * @return Number of bytes written
1002
+ */
1003
+ int nanocbor_fmt_decimal_frac(nanocbor_encoder_t *enc, int32_t e, int32_t m);
1004
+
1005
+ /** @} */
1006
+
1007
+ #ifdef __cplusplus
1008
+ }
1009
+ #endif
1010
+
1011
+ #endif /* NANOCBOR_NANOCBOR_H */
1012
+ /** @} */