1/****************************************************************************
2**
3** Copyright (C) 2018 Intel Corporation
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
13** all 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
21** THE SOFTWARE.
22**
23****************************************************************************/
24
25#ifndef CBOR_H
26#define CBOR_H
27
28#ifndef assert
29#include <assert.h>
30#endif
31#include <limits.h>
32#include <stddef.h>
33#include <stdint.h>
34#include <string.h>
35#include <stdio.h>
36
37#include "tinycbor-version.h"
38
39#define TINYCBOR_VERSION ((TINYCBOR_VERSION_MAJOR << 16) | (TINYCBOR_VERSION_MINOR << 8) | TINYCBOR_VERSION_PATCH)
40
41#ifdef __cplusplus
42extern "C" {
43#else
44#include <stdbool.h>
45#endif
46
47#ifndef SIZE_MAX
48/* Some systems fail to define SIZE_MAX in <stdint.h>, even though C99 requires it...
49 * Conversion from signed to unsigned is defined in 6.3.1.3 (Signed and unsigned integers) p2,
50 * which says: "the value is converted by repeatedly adding or subtracting one more than the
51 * maximum value that can be represented in the new type until the value is in the range of the
52 * new type."
53 * So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
54 */
55# define SIZE_MAX ((size_t)-1)
56#endif
57
58#ifndef CBOR_API
59# define CBOR_API
60#endif
61#ifndef CBOR_PRIVATE_API
62# define CBOR_PRIVATE_API
63#endif
64#ifndef CBOR_INLINE_API
65# if defined(__cplusplus)
66# define CBOR_INLINE inline
67# define CBOR_INLINE_API inline
68# else
69# define CBOR_INLINE_API static CBOR_INLINE
70# if defined(_MSC_VER)
71# define CBOR_INLINE __inline
72# elif defined(__GNUC__)
73# define CBOR_INLINE __inline__
74# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
75# define CBOR_INLINE inline
76# else
77# define CBOR_INLINE
78# endif
79# endif
80#endif
81
82typedef enum CborType {
83 CborIntegerType = 0x00,
84 CborByteStringType = 0x40,
85 CborTextStringType = 0x60,
86 CborArrayType = 0x80,
87 CborMapType = 0xa0,
88 CborTagType = 0xc0,
89 CborSimpleType = 0xe0,
90 CborBooleanType = 0xf5,
91 CborNullType = 0xf6,
92 CborUndefinedType = 0xf7,
93 CborHalfFloatType = 0xf9,
94 CborFloatType = 0xfa,
95 CborDoubleType = 0xfb,
96
97 CborInvalidType = 0xff /* equivalent to the break byte, so it will never be used */
98} CborType;
99
100typedef uint64_t CborTag;
101typedef enum CborKnownTags {
102 CborDateTimeStringTag = 0,
103 CborUnixTime_tTag = 1,
104 CborPositiveBignumTag = 2,
105 CborNegativeBignumTag = 3,
106 CborDecimalTag = 4,
107 CborBigfloatTag = 5,
108 CborCOSE_Encrypt0Tag = 16,
109 CborCOSE_Mac0Tag = 17,
110 CborCOSE_Sign1Tag = 18,
111 CborExpectedBase64urlTag = 21,
112 CborExpectedBase64Tag = 22,
113 CborExpectedBase16Tag = 23,
114 CborEncodedCborTag = 24,
115 CborUrlTag = 32,
116 CborBase64urlTag = 33,
117 CborBase64Tag = 34,
118 CborRegularExpressionTag = 35,
119 CborMimeMessageTag = 36,
120 CborCOSE_EncryptTag = 96,
121 CborCOSE_MacTag = 97,
122 CborCOSE_SignTag = 98,
123 CborSignatureTag = 55799
124} CborKnownTags;
125
126/* #define the constants so we can check with #ifdef */
127#define CborDateTimeStringTag CborDateTimeStringTag
128#define CborUnixTime_tTag CborUnixTime_tTag
129#define CborPositiveBignumTag CborPositiveBignumTag
130#define CborNegativeBignumTag CborNegativeBignumTag
131#define CborDecimalTag CborDecimalTag
132#define CborBigfloatTag CborBigfloatTag
133#define CborCOSE_Encrypt0Tag CborCOSE_Encrypt0Tag
134#define CborCOSE_Mac0Tag CborCOSE_Mac0Tag
135#define CborCOSE_Sign1Tag CborCOSE_Sign1Tag
136#define CborExpectedBase64urlTag CborExpectedBase64urlTag
137#define CborExpectedBase64Tag CborExpectedBase64Tag
138#define CborExpectedBase16Tag CborExpectedBase16Tag
139#define CborEncodedCborTag CborEncodedCborTag
140#define CborUrlTag CborUrlTag
141#define CborBase64urlTag CborBase64urlTag
142#define CborBase64Tag CborBase64Tag
143#define CborRegularExpressionTag CborRegularExpressionTag
144#define CborMimeMessageTag CborMimeMessageTag
145#define CborCOSE_EncryptTag CborCOSE_EncryptTag
146#define CborCOSE_MacTag CborCOSE_MacTag
147#define CborCOSE_SignTag CborCOSE_SignTag
148#define CborSignatureTag CborSignatureTag
149
150/* Error API */
151
152typedef enum CborError {
153 CborNoError = 0,
154
155 /* errors in all modes */
156 CborUnknownError,
157 CborErrorUnknownLength, /* request for length in array, map, or string with indeterminate length */
158 CborErrorAdvancePastEOF,
159 CborErrorIO,
160
161 /* parser errors streaming errors */
162 CborErrorGarbageAtEnd = 256,
163 CborErrorUnexpectedEOF,
164 CborErrorUnexpectedBreak,
165 CborErrorUnknownType, /* can only happen in major type 7 */
166 CborErrorIllegalType, /* type not allowed here */
167 CborErrorIllegalNumber,
168 CborErrorIllegalSimpleType, /* types of value less than 32 encoded in two bytes */
169 CborErrorNoMoreStringChunks,
170
171 /* parser errors in strict mode parsing only */
172 CborErrorUnknownSimpleType = 512,
173 CborErrorUnknownTag,
174 CborErrorInappropriateTagForType,
175 CborErrorDuplicateObjectKeys,
176 CborErrorInvalidUtf8TextString,
177 CborErrorExcludedType,
178 CborErrorExcludedValue,
179 CborErrorImproperValue,
180 CborErrorOverlongEncoding,
181 CborErrorMapKeyNotString,
182 CborErrorMapNotSorted,
183 CborErrorMapKeysNotUnique,
184
185 /* encoder errors */
186 CborErrorTooManyItems = 768,
187 CborErrorTooFewItems,
188
189 /* internal implementation errors */
190 CborErrorDataTooLarge = 1024,
191 CborErrorNestingTooDeep,
192 CborErrorUnsupportedType,
193 CborErrorUnimplementedValidation,
194
195 /* errors in converting to JSON */
196 CborErrorJsonObjectKeyIsAggregate = 1280,
197 CborErrorJsonObjectKeyNotString,
198 CborErrorJsonNotImplemented,
199
200 CborErrorOutOfMemory = (int) (~0U / 2 + 1),
201 CborErrorInternalError = (int) (~0U / 2) /* INT_MAX on two's complement machines */
202} CborError;
203
204CBOR_API const char *cbor_error_string(CborError error);
205
206/* Encoder API */
207
208typedef enum CborEncoderAppendType
209{
210 CborEncoderAppendCborData = 0,
211 CborEncoderAppendStringData = 1
212} CborEncoderAppendType;
213
214typedef CborError (*CborEncoderWriteFunction)(void *, const void *, size_t, CborEncoderAppendType);
215
216enum CborEncoderFlags
217{
218 CborIteratorFlag_WriterFunction = 0x01,
219 CborIteratorFlag_ContainerIsMap_ = 0x20
220};
221
222struct CborEncoder
223{
224 union {
225 uint8_t *ptr;
226 ptrdiff_t bytes_needed;
227 CborEncoderWriteFunction writer;
228 } data;
229 uint8_t *end;
230 size_t remaining;
231 int flags;
232};
233typedef struct CborEncoder CborEncoder;
234
235static const size_t CborIndefiniteLength = SIZE_MAX;
236
237#ifndef CBOR_NO_ENCODER_API
238CBOR_API void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags);
239CBOR_API void cbor_encoder_init_writer(CborEncoder *encoder, CborEncoderWriteFunction writer, void *);
240CBOR_API CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value);
241CBOR_API CborError cbor_encode_int(CborEncoder *encoder, int64_t value);
242CBOR_API CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value);
243CBOR_API CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value);
244CBOR_API CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag);
245CBOR_API CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length);
246CBOR_INLINE_API CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
247{ return cbor_encode_text_string(encoder, string, length: strlen(s: string)); }
248CBOR_API CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length);
249CBOR_API CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value);
250
251CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
252{ return cbor_encode_simple_value(encoder, value: (int)value - 1 + (CborBooleanType & 0x1f)); }
253CBOR_INLINE_API CborError cbor_encode_null(CborEncoder *encoder)
254{ return cbor_encode_simple_value(encoder, value: CborNullType & 0x1f); }
255CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
256{ return cbor_encode_simple_value(encoder, value: CborUndefinedType & 0x1f); }
257
258CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
259{ return cbor_encode_floating_point(encoder, fpType: CborHalfFloatType, value); }
260CBOR_API CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value);
261CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
262{ return cbor_encode_floating_point(encoder, fpType: CborFloatType, value: &value); }
263CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
264{ return cbor_encode_floating_point(encoder, fpType: CborDoubleType, value: &value); }
265
266CBOR_API CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length);
267CBOR_API CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length);
268CBOR_API CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder);
269CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder);
270
271CBOR_INLINE_API uint8_t *_cbor_encoder_get_buffer_pointer(const CborEncoder *encoder)
272{
273 return encoder->data.ptr;
274}
275
276CBOR_INLINE_API size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
277{
278 return (size_t)(encoder->data.ptr - buffer);
279}
280
281CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
282{
283 return encoder->end ? 0 : (size_t)encoder->data.bytes_needed;
284}
285#endif /* CBOR_NO_ENCODER_API */
286
287/* Parser API */
288
289enum CborParserGlobalFlags
290{
291 CborParserFlag_ExternalSource = 0x01
292};
293
294enum CborParserIteratorFlags
295{
296 /* used for all types, but not during string chunk iteration
297 * (values are static-asserted, don't change) */
298 CborIteratorFlag_IntegerValueIs64Bit = 0x01,
299 CborIteratorFlag_IntegerValueTooLarge = 0x02,
300
301 /* used only for CborIntegerType */
302 CborIteratorFlag_NegativeInteger = 0x04,
303
304 /* used only during string iteration */
305 CborIteratorFlag_BeforeFirstStringChunk = 0x04,
306 CborIteratorFlag_IteratingStringChunks = 0x08,
307
308 /* used for arrays, maps and strings, including during chunk iteration */
309 CborIteratorFlag_UnknownLength = 0x10,
310
311 /* used for maps, but must be kept for all types
312 * (ContainerIsMap value must be CborMapType - CborArrayType) */
313 CborIteratorFlag_ContainerIsMap = 0x20,
314 CborIteratorFlag_NextIsMapKey = 0x40
315};
316
317struct CborValue;
318struct CborParserOperations
319{
320 bool (*can_read_bytes)(void *token, size_t len);
321 void *(*read_bytes)(void *token, void *dst, size_t offset, size_t len);
322 void (*advance_bytes)(void *token, size_t len);
323 CborError (*transfer_string)(void *token, const void **userptr, size_t offset, size_t len);
324};
325
326struct CborParser
327{
328 union {
329 const uint8_t *end;
330 const struct CborParserOperations *ops;
331 } source;
332 enum CborParserGlobalFlags flags;
333};
334typedef struct CborParser CborParser;
335
336struct CborValue
337{
338 const CborParser *parser;
339 union {
340 const uint8_t *ptr;
341 void *token;
342 } source;
343 uint32_t remaining;
344 uint16_t extra;
345 uint8_t type;
346 uint8_t flags;
347};
348typedef struct CborValue CborValue;
349
350#ifndef CBOR_NO_PARSER_API
351CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, CborParser *parser, CborValue *it);
352CBOR_API CborError cbor_parser_init_reader(const struct CborParserOperations *ops, CborParser *parser, CborValue *it, void *token);
353
354CBOR_API CborError cbor_value_validate_basic(const CborValue *it);
355
356CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
357{ return it->remaining == 0; }
358CBOR_INLINE_API const uint8_t *cbor_value_get_next_byte(const CborValue *it)
359{ return it->source.ptr; }
360CBOR_API CborError cbor_value_reparse(CborValue *it);
361CBOR_API CborError cbor_value_advance_fixed(CborValue *it);
362CBOR_API CborError cbor_value_advance(CborValue *it);
363CBOR_INLINE_API bool cbor_value_is_container(const CborValue *it)
364{ return it->type == CborArrayType || it->type == CborMapType; }
365CBOR_API CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed);
366CBOR_API CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed);
367
368CBOR_PRIVATE_API uint64_t _cbor_value_decode_int64_internal(const CborValue *value);
369CBOR_INLINE_API uint64_t _cbor_value_extract_int64_helper(const CborValue *value)
370{
371 return value->flags & CborIteratorFlag_IntegerValueTooLarge ?
372 _cbor_value_decode_int64_internal(value) : value->extra;
373}
374
375CBOR_INLINE_API bool cbor_value_is_valid(const CborValue *value)
376{ return value && value->type != CborInvalidType; }
377CBOR_INLINE_API CborType cbor_value_get_type(const CborValue *value)
378{ return (CborType)value->type; }
379
380/* Null & undefined type */
381CBOR_INLINE_API bool cbor_value_is_null(const CborValue *value)
382{ return value->type == CborNullType; }
383CBOR_INLINE_API bool cbor_value_is_undefined(const CborValue *value)
384{ return value->type == CborUndefinedType; }
385
386/* Booleans */
387CBOR_INLINE_API bool cbor_value_is_boolean(const CborValue *value)
388{ return value->type == CborBooleanType; }
389CBOR_INLINE_API CborError cbor_value_get_boolean(const CborValue *value, bool *result)
390{
391 assert(cbor_value_is_boolean(value));
392 *result = !!value->extra;
393 return CborNoError;
394}
395
396/* Simple types */
397CBOR_INLINE_API bool cbor_value_is_simple_type(const CborValue *value)
398{ return value->type == CborSimpleType; }
399CBOR_INLINE_API CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
400{
401 assert(cbor_value_is_simple_type(value));
402 *result = (uint8_t)value->extra;
403 return CborNoError;
404}
405
406/* Integers */
407CBOR_INLINE_API bool cbor_value_is_integer(const CborValue *value)
408{ return value->type == CborIntegerType; }
409CBOR_INLINE_API bool cbor_value_is_unsigned_integer(const CborValue *value)
410{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger) == 0; }
411CBOR_INLINE_API bool cbor_value_is_negative_integer(const CborValue *value)
412{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger); }
413
414CBOR_INLINE_API CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
415{
416 assert(cbor_value_is_integer(value));
417 *result = _cbor_value_extract_int64_helper(value);
418 return CborNoError;
419}
420
421CBOR_INLINE_API CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
422{
423 assert(cbor_value_is_unsigned_integer(value));
424 *result = _cbor_value_extract_int64_helper(value);
425 return CborNoError;
426}
427
428CBOR_INLINE_API CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
429{
430 assert(cbor_value_is_integer(value));
431 *result = (int64_t) _cbor_value_extract_int64_helper(value);
432 if (value->flags & CborIteratorFlag_NegativeInteger)
433 *result = -*result - 1;
434 return CborNoError;
435}
436
437CBOR_INLINE_API CborError cbor_value_get_int(const CborValue *value, int *result)
438{
439 assert(cbor_value_is_integer(value));
440 *result = (int) _cbor_value_extract_int64_helper(value);
441 if (value->flags & CborIteratorFlag_NegativeInteger)
442 *result = -*result - 1;
443 return CborNoError;
444}
445
446CBOR_API CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result);
447CBOR_API CborError cbor_value_get_int_checked(const CborValue *value, int *result);
448
449CBOR_INLINE_API bool cbor_value_is_length_known(const CborValue *value)
450{ return (value->flags & CborIteratorFlag_UnknownLength) == 0; }
451
452/* Tags */
453CBOR_INLINE_API bool cbor_value_is_tag(const CborValue *value)
454{ return value->type == CborTagType; }
455CBOR_INLINE_API CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
456{
457 assert(cbor_value_is_tag(value));
458 *result = _cbor_value_extract_int64_helper(value);
459 return CborNoError;
460}
461CBOR_API CborError cbor_value_skip_tag(CborValue *it);
462
463/* Strings */
464CBOR_INLINE_API bool cbor_value_is_byte_string(const CborValue *value)
465{ return value->type == CborByteStringType; }
466CBOR_INLINE_API bool cbor_value_is_text_string(const CborValue *value)
467{ return value->type == CborTextStringType; }
468
469CBOR_INLINE_API CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
470{
471 uint64_t v;
472 assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
473 if (!cbor_value_is_length_known(value))
474 return CborErrorUnknownLength;
475 v = _cbor_value_extract_int64_helper(value);
476 *length = (size_t)v;
477 if (*length != v)
478 return CborErrorDataTooLarge;
479 return CborNoError;
480}
481
482CBOR_PRIVATE_API CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
483 size_t *buflen, CborValue *next);
484CBOR_PRIVATE_API CborError _cbor_value_dup_string(const CborValue *value, void **buffer,
485 size_t *buflen, CborValue *next);
486
487CBOR_API CborError cbor_value_calculate_string_length(const CborValue *value, size_t *length);
488
489CBOR_INLINE_API CborError cbor_value_copy_text_string(const CborValue *value, char *buffer,
490 size_t *buflen, CborValue *next)
491{
492 assert(cbor_value_is_text_string(value));
493 return _cbor_value_copy_string(value, buffer, buflen, next);
494}
495CBOR_INLINE_API CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer,
496 size_t *buflen, CborValue *next)
497{
498 assert(cbor_value_is_byte_string(value));
499 return _cbor_value_copy_string(value, buffer, buflen, next);
500}
501
502CBOR_INLINE_API CborError cbor_value_dup_text_string(const CborValue *value, char **buffer,
503 size_t *buflen, CborValue *next)
504{
505 assert(cbor_value_is_text_string(value));
506 return _cbor_value_dup_string(value, buffer: (void **)buffer, buflen, next);
507}
508CBOR_INLINE_API CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer,
509 size_t *buflen, CborValue *next)
510{
511 assert(cbor_value_is_byte_string(value));
512 return _cbor_value_dup_string(value, buffer: (void **)buffer, buflen, next);
513}
514
515CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk_size(const CborValue *value, size_t *len);
516CBOR_INLINE_API CborError cbor_value_get_string_chunk_size(const CborValue *value, size_t *len)
517{
518 assert(value->flags & CborIteratorFlag_IteratingStringChunks);
519 return _cbor_value_get_string_chunk_size(value, len);
520}
521
522CBOR_INLINE_API bool cbor_value_string_iteration_at_end(const CborValue *value)
523{
524 size_t dummy;
525 return cbor_value_get_string_chunk_size(value, len: &dummy) == CborErrorNoMoreStringChunks;
526}
527
528CBOR_PRIVATE_API CborError _cbor_value_begin_string_iteration(CborValue *value);
529CBOR_INLINE_API CborError cbor_value_begin_string_iteration(CborValue *value)
530{
531 assert(cbor_value_is_text_string(value) || cbor_value_is_byte_string(value));
532 assert(!(value->flags & CborIteratorFlag_IteratingStringChunks));
533 return _cbor_value_begin_string_iteration(value);
534}
535
536CBOR_PRIVATE_API CborError _cbor_value_finish_string_iteration(CborValue *value);
537CBOR_INLINE_API CborError cbor_value_finish_string_iteration(CborValue *value)
538{
539 assert(cbor_value_string_iteration_at_end(value));
540 return _cbor_value_finish_string_iteration(value);
541}
542
543CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr,
544 size_t *len, CborValue *next);
545CBOR_INLINE_API CborError cbor_value_get_text_string_chunk(const CborValue *value, const char **bufferptr,
546 size_t *len, CborValue *next)
547{
548 assert(cbor_value_is_text_string(value));
549 return _cbor_value_get_string_chunk(value, bufferptr: (const void **)bufferptr, len, next);
550}
551CBOR_INLINE_API CborError cbor_value_get_byte_string_chunk(const CborValue *value, const uint8_t **bufferptr,
552 size_t *len, CborValue *next)
553{
554 assert(cbor_value_is_byte_string(value));
555 return _cbor_value_get_string_chunk(value, bufferptr: (const void **)bufferptr, len, next);
556}
557
558CBOR_API CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result);
559
560/* Maps and arrays */
561CBOR_INLINE_API bool cbor_value_is_array(const CborValue *value)
562{ return value->type == CborArrayType; }
563CBOR_INLINE_API bool cbor_value_is_map(const CborValue *value)
564{ return value->type == CborMapType; }
565
566CBOR_INLINE_API CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
567{
568 uint64_t v;
569 assert(cbor_value_is_array(value));
570 if (!cbor_value_is_length_known(value))
571 return CborErrorUnknownLength;
572 v = _cbor_value_extract_int64_helper(value);
573 *length = (size_t)v;
574 if (*length != v)
575 return CborErrorDataTooLarge;
576 return CborNoError;
577}
578
579CBOR_INLINE_API CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
580{
581 uint64_t v;
582 assert(cbor_value_is_map(value));
583 if (!cbor_value_is_length_known(value))
584 return CborErrorUnknownLength;
585 v = _cbor_value_extract_int64_helper(value);
586 *length = (size_t)v;
587 if (*length != v)
588 return CborErrorDataTooLarge;
589 return CborNoError;
590}
591
592CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element);
593
594/* Floating point */
595CBOR_INLINE_API bool cbor_value_is_half_float(const CborValue *value)
596{ return value->type == CborHalfFloatType; }
597CBOR_API CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result);
598CBOR_INLINE_API CborError cbor_value_get_half_float(const CborValue *value, void *result)
599{
600 assert(cbor_value_is_half_float(value));
601 assert((value->flags & CborIteratorFlag_IntegerValueTooLarge) == 0);
602
603 /* size has already been computed */
604 memcpy(dest: result, src: &value->extra, n: sizeof(value->extra));
605 return CborNoError;
606}
607
608CBOR_INLINE_API bool cbor_value_is_float(const CborValue *value)
609{ return value->type == CborFloatType; }
610CBOR_INLINE_API CborError cbor_value_get_float(const CborValue *value, float *result)
611{
612 uint32_t data;
613 assert(cbor_value_is_float(value));
614 assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
615 data = (uint32_t)_cbor_value_decode_int64_internal(value);
616 memcpy(dest: result, src: &data, n: sizeof(*result));
617 return CborNoError;
618}
619
620CBOR_INLINE_API bool cbor_value_is_double(const CborValue *value)
621{ return value->type == CborDoubleType; }
622CBOR_INLINE_API CborError cbor_value_get_double(const CborValue *value, double *result)
623{
624 uint64_t data;
625 assert(cbor_value_is_double(value));
626 assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
627 data = _cbor_value_decode_int64_internal(value);
628 memcpy(dest: result, src: &data, n: sizeof(*result));
629 return CborNoError;
630}
631
632/* Validation API */
633#ifndef CBOR_NO_VALIDATION_API
634
635enum CborValidationFlags {
636 /* Bit mapping:
637 * bits 0-7 (8 bits): canonical format
638 * bits 8-11 (4 bits): canonical format & strict mode
639 * bits 12-20 (8 bits): strict mode
640 * bits 21-31 (10 bits): other
641 */
642
643 CborValidateShortestIntegrals = 0x0001,
644 CborValidateShortestFloatingPoint = 0x0002,
645 CborValidateShortestNumbers = CborValidateShortestIntegrals | CborValidateShortestFloatingPoint,
646 CborValidateNoIndeterminateLength = 0x0100,
647 CborValidateMapIsSorted = 0x0200 | CborValidateNoIndeterminateLength,
648
649 CborValidateCanonicalFormat = 0x0fff,
650
651 CborValidateMapKeysAreUnique = 0x1000 | CborValidateMapIsSorted,
652 CborValidateTagUse = 0x2000,
653 CborValidateUtf8 = 0x4000,
654
655 CborValidateStrictMode = 0xfff00,
656
657 CborValidateMapKeysAreString = 0x100000,
658 CborValidateNoUndefined = 0x200000,
659 CborValidateNoTags = 0x400000,
660 CborValidateFiniteFloatingPoint = 0x800000,
661 /* unused = 0x1000000, */
662 /* unused = 0x2000000, */
663
664 CborValidateNoUnknownSimpleTypesSA = 0x4000000,
665 CborValidateNoUnknownSimpleTypes = 0x8000000 | CborValidateNoUnknownSimpleTypesSA,
666 CborValidateNoUnknownTagsSA = 0x10000000,
667 CborValidateNoUnknownTagsSR = 0x20000000 | CborValidateNoUnknownTagsSA,
668 CborValidateNoUnknownTags = 0x40000000 | CborValidateNoUnknownTagsSR,
669
670 CborValidateCompleteData = (int)0x80000000,
671
672 CborValidateStrictest = (int)~0U,
673 CborValidateBasic = 0
674};
675
676CBOR_API CborError cbor_value_validate(const CborValue *it, uint32_t flags);
677#endif /* CBOR_NO_VALIDATION_API */
678
679/* Human-readable (dump) API */
680#ifndef CBOR_NO_PRETTY_API
681
682enum CborPrettyFlags {
683 CborPrettyNumericEncodingIndicators = 0x01,
684 CborPrettyTextualEncodingIndicators = 0,
685
686 CborPrettyIndicateIndeterminateLength = 0x02,
687 CborPrettyIndicateIndetermineLength = CborPrettyIndicateIndeterminateLength, /* deprecated */
688 CborPrettyIndicateOverlongNumbers = 0x04,
689
690 CborPrettyShowStringFragments = 0x100,
691 CborPrettyMergeStringFragments = 0,
692
693 CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength
694};
695
696typedef CborError (*CborStreamFunction)(void *token, const char *fmt, ...)
697#ifdef __GNUC__
698 __attribute__((__format__(printf, 2, 3)))
699#endif
700;
701
702CBOR_API CborError cbor_value_to_pretty_stream(CborStreamFunction streamFunction, void *token, CborValue *value, int flags);
703
704/* The following API requires a hosted C implementation (uses FILE*) */
705#if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1
706CBOR_API CborError cbor_value_to_pretty_advance_flags(FILE *out, CborValue *value, int flags);
707CBOR_API CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value);
708CBOR_INLINE_API CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
709{
710 CborValue copy = *value;
711 return cbor_value_to_pretty_advance_flags(out, value: &copy, flags: CborPrettyDefaultFlags);
712}
713#endif /* __STDC_HOSTED__ check */
714
715#endif /* CBOR_NO_PRETTY_API */
716
717#endif /* CBOR_NO_PARSER_API */
718
719#ifdef __cplusplus
720}
721#endif
722
723#endif /* CBOR_H */
724
725

source code of qtbase/src/3rdparty/tinycbor/src/cbor.h