1 /****************************************************************************
3 ** Copyright (C) 2017 Intel Corporation
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:
12 ** The above copyright notice and this permission notice shall be included in
13 ** all copies or substantial portions of the Software.
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
23 ****************************************************************************/
37 #include "tinycbor-version.h"
39 #define TINYCBOR_VERSION ((TINYCBOR_VERSION_MAJOR << 16) | (TINYCBOR_VERSION_MINOR << 8) | TINYCBOR_VERSION_PATCH)
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
53 * So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
55 # define SIZE_MAX ((size_t)-1)
61 #ifndef CBOR_PRIVATE_API
62 # define CBOR_PRIVATE_API
64 #ifndef CBOR_INLINE_API
65 # if defined(__cplusplus)
66 # define CBOR_INLINE inline
67 # define CBOR_INLINE_API inline
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
82 typedef enum CborType
{
83 CborIntegerType
= 0x00,
84 CborByteStringType
= 0x40,
85 CborTextStringType
= 0x60,
89 CborSimpleType
= 0xe0,
90 CborBooleanType
= 0xf5,
92 CborUndefinedType
= 0xf7,
93 CborHalfFloatType
= 0xf9,
95 CborDoubleType
= 0xfb,
97 CborInvalidType
= 0xff /* equivalent to the break byte, so it will never be used */
100 typedef uint64_t CborTag
;
101 typedef enum CborKnownTags
{
102 CborDateTimeStringTag
= 0,
103 CborUnixTime_tTag
= 1,
104 CborPositiveBignumTag
= 2,
105 CborNegativeBignumTag
= 3,
108 CborCOSE_Encrypt0Tag
= 16,
109 CborCOSE_Mac0Tag
= 17,
110 CborCOSE_Sign1Tag
= 18,
111 CborExpectedBase64urlTag
= 21,
112 CborExpectedBase64Tag
= 22,
113 CborExpectedBase16Tag
= 23,
114 CborEncodedCborTag
= 24,
116 CborBase64urlTag
= 33,
118 CborRegularExpressionTag
= 35,
119 CborMimeMessageTag
= 36,
120 CborCOSE_EncryptTag
= 96,
121 CborCOSE_MacTag
= 97,
122 CborCOSE_SignTag
= 98,
123 CborSignatureTag
= 55799
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
152 typedef enum CborError
{
155 /* errors in all modes */
157 CborErrorUnknownLength
, /* request for length in array, map, or string with indeterminate length */
158 CborErrorAdvancePastEOF
,
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 */
170 /* parser errors in strict mode parsing only */
171 CborErrorUnknownSimpleType
= 512,
173 CborErrorInappropriateTagForType
,
174 CborErrorDuplicateObjectKeys
,
175 CborErrorInvalidUtf8TextString
,
176 CborErrorExcludedType
,
177 CborErrorExcludedValue
,
178 CborErrorImproperValue
,
179 CborErrorOverlongEncoding
,
180 CborErrorMapKeyNotString
,
181 CborErrorMapNotSorted
,
182 CborErrorMapKeysNotUnique
,
185 CborErrorTooManyItems
= 768,
186 CborErrorTooFewItems
,
188 /* internal implementation errors */
189 CborErrorDataTooLarge
= 1024,
190 CborErrorNestingTooDeep
,
191 CborErrorUnsupportedType
,
193 /* errors in converting to JSON */
194 CborErrorJsonObjectKeyIsAggregate
= 1280,
195 CborErrorJsonObjectKeyNotString
,
196 CborErrorJsonNotImplemented
,
198 CborErrorOutOfMemory
= (int)(~0U / 2 + 1),
199 CborErrorInternalError
= (int)(~0U / 2) /* INT_MAX on two's complement machines */
202 CBOR_API
const char *cbor_error_string(CborError error
);
208 ptrdiff_t bytes_needed
;
214 typedef struct CborEncoder CborEncoder
;
216 static const size_t CborIndefiniteLength
= SIZE_MAX
;
218 CBOR_API
void cbor_encoder_init(CborEncoder
*encoder
, uint8_t *buffer
, size_t size
, int flags
);
219 CBOR_API CborError
cbor_encode_uint(CborEncoder
*encoder
, uint64_t value
);
220 CBOR_API CborError
cbor_encode_int(CborEncoder
*encoder
, int64_t value
);
221 CBOR_API CborError
cbor_encode_negative_int(CborEncoder
*encoder
, uint64_t absolute_value
);
222 CBOR_API CborError
cbor_encode_simple_value(CborEncoder
*encoder
, uint8_t value
);
223 CBOR_API CborError
cbor_encode_tag(CborEncoder
*encoder
, CborTag tag
);
224 CBOR_API CborError
cbor_encode_text_string(CborEncoder
*encoder
, const char *string
, size_t length
);
225 CBOR_INLINE_API CborError
cbor_encode_text_stringz(CborEncoder
*encoder
, const char *string
)
226 { return cbor_encode_text_string(encoder
, string
, strlen(string
)); }
227 CBOR_API CborError
cbor_encode_byte_string(CborEncoder
*encoder
, const uint8_t *string
, size_t length
);
228 CBOR_API CborError
cbor_encode_floating_point(CborEncoder
*encoder
, CborType fpType
, const void *value
);
230 CBOR_INLINE_API CborError
cbor_encode_boolean(CborEncoder
*encoder
, bool value
)
231 { return cbor_encode_simple_value(encoder
, (int)value
- 1 + (CborBooleanType
& 0x1f)); }
232 CBOR_INLINE_API CborError
cbor_encode_null(CborEncoder
*encoder
)
233 { return cbor_encode_simple_value(encoder
, CborNullType
& 0x1f); }
234 CBOR_INLINE_API CborError
cbor_encode_undefined(CborEncoder
*encoder
)
235 { return cbor_encode_simple_value(encoder
, CborUndefinedType
& 0x1f); }
237 CBOR_INLINE_API CborError
cbor_encode_half_float(CborEncoder
*encoder
, const void *value
)
238 { return cbor_encode_floating_point(encoder
, CborHalfFloatType
, value
); }
239 CBOR_INLINE_API CborError
cbor_encode_float(CborEncoder
*encoder
, float value
)
240 { return cbor_encode_floating_point(encoder
, CborFloatType
, &value
); }
241 CBOR_INLINE_API CborError
cbor_encode_double(CborEncoder
*encoder
, double value
)
242 { return cbor_encode_floating_point(encoder
, CborDoubleType
, &value
); }
244 CBOR_API CborError
cbor_encoder_create_array(CborEncoder
*encoder
, CborEncoder
*arrayEncoder
, size_t length
);
245 CBOR_API CborError
cbor_encoder_create_map(CborEncoder
*encoder
, CborEncoder
*mapEncoder
, size_t length
);
246 CBOR_API CborError
cbor_encoder_close_container(CborEncoder
*encoder
, const CborEncoder
*containerEncoder
);
247 CBOR_API CborError
cbor_encoder_close_container_checked(CborEncoder
*encoder
, const CborEncoder
*containerEncoder
);
249 CBOR_INLINE_API
uint8_t *_cbor_encoder_get_buffer_pointer(const CborEncoder
*encoder
) {
250 return encoder
->data
.ptr
;
253 CBOR_INLINE_API
size_t cbor_encoder_get_buffer_size(const CborEncoder
*encoder
, const uint8_t *buffer
) {
254 return (size_t)(encoder
->data
.ptr
- buffer
);
257 CBOR_INLINE_API
size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder
*encoder
) {
258 return encoder
->end
? 0 : (size_t)encoder
->data
.bytes_needed
;
263 enum CborParserIteratorFlags
{
264 CborIteratorFlag_IntegerValueTooLarge
= 0x01,
265 CborIteratorFlag_NegativeInteger
= 0x02,
266 CborIteratorFlag_IteratingStringChunks
= 0x02,
267 CborIteratorFlag_UnknownLength
= 0x04,
268 CborIteratorFlag_ContainerIsMap
= 0x20
275 typedef struct CborParser CborParser
;
278 const CborParser
*parser
;
285 typedef struct CborValue CborValue
;
287 CBOR_API CborError
cbor_parser_init(const uint8_t *buffer
, size_t size
, uint32_t flags
, CborParser
*parser
, CborValue
*it
);
289 CBOR_API CborError
cbor_value_validate_basic(const CborValue
*it
);
291 CBOR_INLINE_API
bool cbor_value_at_end(const CborValue
*it
)
292 { return it
->remaining
== 0; }
293 CBOR_INLINE_API
const uint8_t *cbor_value_get_next_byte(const CborValue
*it
)
295 CBOR_API CborError
cbor_value_advance_fixed(CborValue
*it
);
296 CBOR_API CborError
cbor_value_advance(CborValue
*it
);
297 CBOR_INLINE_API
bool cbor_value_is_container(const CborValue
*it
)
298 { return it
->type
== CborArrayType
|| it
->type
== CborMapType
; }
299 CBOR_API CborError
cbor_value_enter_container(const CborValue
*it
, CborValue
*recursed
);
300 CBOR_API CborError
cbor_value_leave_container(CborValue
*it
, const CborValue
*recursed
);
302 CBOR_PRIVATE_API
uint64_t _cbor_value_decode_int64_internal(const CborValue
*value
);
303 CBOR_INLINE_API
uint64_t _cbor_value_extract_int64_helper(const CborValue
*value
) {
304 return (value
->flags
& CborIteratorFlag_IntegerValueTooLarge
) ?
305 _cbor_value_decode_int64_internal(value
) : value
->extra
;
308 CBOR_INLINE_API
bool cbor_value_is_valid(const CborValue
*value
)
309 { return value
&& value
->type
!= CborInvalidType
; }
310 CBOR_INLINE_API CborType
cbor_value_get_type(const CborValue
*value
)
311 { return (CborType
)value
->type
; }
313 /* Null & undefined type */
314 CBOR_INLINE_API
bool cbor_value_is_null(const CborValue
*value
)
315 { return value
->type
== CborNullType
; }
316 CBOR_INLINE_API
bool cbor_value_is_undefined(const CborValue
*value
)
317 { return value
->type
== CborUndefinedType
; }
320 CBOR_INLINE_API
bool cbor_value_is_boolean(const CborValue
*value
)
321 { return value
->type
== CborBooleanType
; }
322 CBOR_INLINE_API CborError
cbor_value_get_boolean(const CborValue
*value
, bool *result
) {
323 assert(cbor_value_is_boolean(value
));
324 *result
= !!value
->extra
;
329 CBOR_INLINE_API
bool cbor_value_is_simple_type(const CborValue
*value
)
330 { return value
->type
== CborSimpleType
; }
331 CBOR_INLINE_API CborError
cbor_value_get_simple_type(const CborValue
*value
, uint8_t *result
) {
332 assert(cbor_value_is_simple_type(value
));
333 *result
= (uint8_t)value
->extra
;
338 CBOR_INLINE_API
bool cbor_value_is_integer(const CborValue
*value
)
339 { return value
->type
== CborIntegerType
; }
340 CBOR_INLINE_API
bool cbor_value_is_unsigned_integer(const CborValue
*value
)
341 { return cbor_value_is_integer(value
) && (value
->flags
& CborIteratorFlag_NegativeInteger
) == 0; }
342 CBOR_INLINE_API
bool cbor_value_is_negative_integer(const CborValue
*value
)
343 { return cbor_value_is_integer(value
) && (value
->flags
& CborIteratorFlag_NegativeInteger
); }
345 CBOR_INLINE_API CborError
cbor_value_get_raw_integer(const CborValue
*value
, uint64_t *result
) {
346 assert(cbor_value_is_integer(value
));
347 *result
= _cbor_value_extract_int64_helper(value
);
351 CBOR_INLINE_API CborError
cbor_value_get_uint64(const CborValue
*value
, uint64_t *result
) {
352 assert(cbor_value_is_unsigned_integer(value
));
353 *result
= _cbor_value_extract_int64_helper(value
);
357 CBOR_INLINE_API CborError
cbor_value_get_int64(const CborValue
*value
, int64_t *result
) {
358 assert(cbor_value_is_integer(value
));
359 *result
= (int64_t) _cbor_value_extract_int64_helper(value
);
360 if (value
->flags
& CborIteratorFlag_NegativeInteger
)
361 *result
= -*result
- 1;
365 CBOR_INLINE_API CborError
cbor_value_get_int(const CborValue
*value
, int *result
) {
366 assert(cbor_value_is_integer(value
));
367 *result
= (int) _cbor_value_extract_int64_helper(value
);
368 if (value
->flags
& CborIteratorFlag_NegativeInteger
)
369 *result
= -*result
- 1;
373 CBOR_API CborError
cbor_value_get_int64_checked(const CborValue
*value
, int64_t *result
);
374 CBOR_API CborError
cbor_value_get_int_checked(const CborValue
*value
, int *result
);
376 CBOR_INLINE_API
bool cbor_value_is_length_known(const CborValue
*value
)
377 { return (value
->flags
& CborIteratorFlag_UnknownLength
) == 0; }
380 CBOR_INLINE_API
bool cbor_value_is_tag(const CborValue
*value
)
381 { return value
->type
== CborTagType
; }
382 CBOR_INLINE_API CborError
cbor_value_get_tag(const CborValue
*value
, CborTag
*result
) {
383 assert(cbor_value_is_tag(value
));
384 *result
= _cbor_value_extract_int64_helper(value
);
387 CBOR_API CborError
cbor_value_skip_tag(CborValue
*it
);
390 CBOR_INLINE_API
bool cbor_value_is_byte_string(const CborValue
*value
)
391 { return value
->type
== CborByteStringType
; }
392 CBOR_INLINE_API
bool cbor_value_is_text_string(const CborValue
*value
)
393 { return value
->type
== CborTextStringType
; }
395 CBOR_INLINE_API CborError
cbor_value_get_string_length(const CborValue
*value
, size_t *length
) {
397 assert(cbor_value_is_byte_string(value
) || cbor_value_is_text_string(value
));
398 if (!cbor_value_is_length_known(value
))
399 return CborErrorUnknownLength
;
400 v
= _cbor_value_extract_int64_helper(value
);
403 return CborErrorDataTooLarge
;
407 CBOR_PRIVATE_API CborError
_cbor_value_copy_string(const CborValue
*value
, void *buffer
,
408 size_t *buflen
, CborValue
*next
);
409 CBOR_PRIVATE_API CborError
_cbor_value_dup_string(const CborValue
*value
, void **buffer
,
410 size_t *buflen
, CborValue
*next
);
412 CBOR_API CborError
cbor_value_calculate_string_length(const CborValue
*value
, size_t *len
);
414 CBOR_INLINE_API CborError
cbor_value_copy_text_string(const CborValue
*value
, char *buffer
,
415 size_t *buflen
, CborValue
*next
) {
416 assert(cbor_value_is_text_string(value
));
417 return _cbor_value_copy_string(value
, buffer
, buflen
, next
);
419 CBOR_INLINE_API CborError
cbor_value_copy_byte_string(const CborValue
*value
, uint8_t *buffer
,
420 size_t *buflen
, CborValue
*next
) {
421 assert(cbor_value_is_byte_string(value
));
422 return _cbor_value_copy_string(value
, buffer
, buflen
, next
);
425 CBOR_INLINE_API CborError
cbor_value_dup_text_string(const CborValue
*value
, char **buffer
,
426 size_t *buflen
, CborValue
*next
) {
427 assert(cbor_value_is_text_string(value
));
428 return _cbor_value_dup_string(value
, (void **)buffer
, buflen
, next
);
430 CBOR_INLINE_API CborError
cbor_value_dup_byte_string(const CborValue
*value
, uint8_t **buffer
,
431 size_t *buflen
, CborValue
*next
) {
432 assert(cbor_value_is_byte_string(value
));
433 return _cbor_value_dup_string(value
, (void **)buffer
, buflen
, next
);
436 CBOR_API CborError
cbor_value_text_string_equals(const CborValue
*value
, const char *string
, bool *result
);
438 /* Maps and arrays */
439 CBOR_INLINE_API
bool cbor_value_is_array(const CborValue
*value
)
440 { return value
->type
== CborArrayType
; }
441 CBOR_INLINE_API
bool cbor_value_is_map(const CborValue
*value
)
442 { return value
->type
== CborMapType
; }
444 CBOR_INLINE_API CborError
cbor_value_get_array_length(const CborValue
*value
, size_t *length
) {
446 assert(cbor_value_is_array(value
));
447 if (!cbor_value_is_length_known(value
))
448 return CborErrorUnknownLength
;
449 v
= _cbor_value_extract_int64_helper(value
);
452 return CborErrorDataTooLarge
;
456 CBOR_INLINE_API CborError
cbor_value_get_map_length(const CborValue
*value
, size_t *length
) {
458 assert(cbor_value_is_map(value
));
459 if (!cbor_value_is_length_known(value
))
460 return CborErrorUnknownLength
;
461 v
= _cbor_value_extract_int64_helper(value
);
464 return CborErrorDataTooLarge
;
468 CBOR_API CborError
cbor_value_map_find_value(const CborValue
*map
, const char *string
, CborValue
*element
);
471 CBOR_INLINE_API
bool cbor_value_is_half_float(const CborValue
*value
)
472 { return value
->type
== CborHalfFloatType
; }
473 CBOR_API CborError
cbor_value_get_half_float(const CborValue
*value
, void *result
);
475 CBOR_INLINE_API
bool cbor_value_is_float(const CborValue
*value
)
476 { return value
->type
== CborFloatType
; }
477 CBOR_INLINE_API CborError
cbor_value_get_float(const CborValue
*value
, float *result
) {
479 assert(cbor_value_is_float(value
));
480 assert(value
->flags
& CborIteratorFlag_IntegerValueTooLarge
);
481 data
= (uint32_t)_cbor_value_decode_int64_internal(value
);
482 memcpy(result
, &data
, sizeof(*result
));
486 CBOR_INLINE_API
bool cbor_value_is_double(const CborValue
*value
)
487 { return value
->type
== CborDoubleType
; }
488 CBOR_INLINE_API CborError
cbor_value_get_double(const CborValue
*value
, double *result
) {
490 assert(cbor_value_is_double(value
));
491 assert(value
->flags
& CborIteratorFlag_IntegerValueTooLarge
);
492 data
= _cbor_value_decode_int64_internal(value
);
493 memcpy(result
, &data
, sizeof(*result
));
499 enum CborValidationFlags
{
501 * bits 0-7 (8 bits): canonical format
502 * bits 8-11 (4 bits): canonical format & strict mode
503 * bits 12-20 (8 bits): strict mode
504 * bits 21-31 (10 bits): other
507 CborValidateShortestIntegrals
= 0x0001,
508 CborValidateShortestFloatingPoint
= 0x0002,
509 CborValidateShortestNumbers
= CborValidateShortestIntegrals
| CborValidateShortestFloatingPoint
,
510 CborValidateNoIndeterminateLength
= 0x0100,
511 CborValidateMapIsSorted
= 0x0200 | CborValidateNoIndeterminateLength
,
513 CborValidateCanonicalFormat
= 0x0fff,
515 CborValidateMapKeysAreUnique
= 0x1000 | CborValidateMapIsSorted
,
516 CborValidateTagUse
= 0x2000,
517 CborValidateUtf8
= 0x4000,
519 CborValidateStrictMode
= 0xfff00,
521 CborValidateMapKeysAreString
= 0x100000,
522 CborValidateNoUndefined
= 0x200000,
523 CborValidateNoTags
= 0x400000,
524 CborValidateFiniteFloatingPoint
= 0x800000,
525 /* unused = 0x1000000, */
526 /* unused = 0x2000000, */
528 CborValidateNoUnknownSimpleTypesSA
= 0x4000000,
529 CborValidateNoUnknownSimpleTypes
= 0x8000000 | CborValidateNoUnknownSimpleTypesSA
,
530 CborValidateNoUnknownTagsSA
= 0x10000000,
531 CborValidateNoUnknownTagsSR
= 0x20000000 | CborValidateNoUnknownTagsSA
,
532 CborValidateNoUnknownTags
= 0x40000000 | CborValidateNoUnknownTagsSR
,
534 CborValidateCompleteData
= (int)0x80000000,
536 CborValidateStrictest
= (int)~0U,
537 CborValidateBasic
= 0
540 CBOR_API CborError
cbor_value_validate(const CborValue
*it
, uint32_t flags
);
542 /* Human-readable (dump) API */
544 enum CborPrettyFlags
{
545 CborPrettyNumericEncodingIndicators
= 0x01,
546 CborPrettyTextualEncodingIndicators
= 0,
548 CborPrettyIndicateIndeterminateLength
= 0x02,
549 CborPrettyIndicateIndetermineLength
= CborPrettyIndicateIndeterminateLength
, /* deprecated */
550 CborPrettyIndicateOverlongNumbers
= 0x04,
552 CborPrettyShowStringFragments
= 0x100,
553 CborPrettyMergeStringFragments
= 0,
555 CborPrettyDefaultFlags
= CborPrettyIndicateIndeterminateLength
558 /* cf https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ */
559 typedef CborError(*CborStreamFunction
)(void *token
, const char *fmt
, ...)
560 #if defined(__MINGW32__) || defined(__MINGW64__)
561 __attribute__((format(__MINGW_PRINTF_FORMAT
, 2, 3)));
562 #elif defined(__GNUC__)
563 __attribute__((__format__(printf
, 2, 3)))
567 CBOR_API CborError
cbor_value_to_pretty_stream(CborStreamFunction streamFunction
, void *token
, CborValue
*value
, int flags
);
569 /* The following API requires a hosted C implementation (uses FILE*) */
570 #if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1
571 CBOR_API CborError
cbor_value_to_pretty_advance_flags(FILE *out
, CborValue
*value
, int flags
);
572 CBOR_API CborError
cbor_value_to_pretty_advance(FILE *out
, CborValue
*value
);
573 CBOR_INLINE_API CborError
cbor_value_to_pretty(FILE *out
, const CborValue
*value
) {
574 CborValue copy
= *value
;
575 return cbor_value_to_pretty_advance_flags(out
, ©
, CborPrettyDefaultFlags
);
577 #endif /* __STDC_HOSTED__ check */