Merge branch 'upstream' into tizen
[platform/upstream/iotivity.git] / extlibs / tinycbor / tinycbor / src / cbor.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 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 #include <assert.h>
29 #include <limits.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <stdio.h>
34
35 #ifdef __cplusplus
36 extern "C" {
37 #else
38 #include <stdbool.h>
39 #endif
40
41 #ifndef SIZE_MAX
42 /* Some systems fail to define SIZE_MAX in <stdint.h>, even though C99 requires it...
43  * Conversion from signed to unsigned is defined in 6.3.1.3 (Signed and unsigned integers) p2,
44  * which says: "the value is converted by repeatedly adding or subtracting one more than the
45  * maximum value that can be represented in the new type until the value is in the range of the
46  * new type."
47  * So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
48  */
49 #  define SIZE_MAX ((size_t)-1)
50 #endif
51
52 #ifndef CBOR_API
53 #  define CBOR_API
54 #endif
55 #ifndef CBOR_PRIVATE_API
56 #  define CBOR_PRIVATE_API
57 #endif
58 #ifndef CBOR_INLINE_API
59 #  if defined(__cplusplus)
60 #    define CBOR_INLINE_API inline
61 #  else
62 #    define CBOR_INLINE_API static inline
63 #  endif
64 #endif
65
66 typedef enum CborType {
67     CborIntegerType     = 0x00,
68     CborByteStringType  = 0x40,
69     CborTextStringType  = 0x60,
70     CborArrayType       = 0x80,
71     CborMapType         = 0xa0,
72     CborTagType         = 0xc0,
73     CborSimpleType      = 0xe0,
74     CborBooleanType     = 0xf5,
75     CborNullType        = 0xf6,
76     CborUndefinedType   = 0xf7,
77     CborHalfFloatType   = 0xf9,
78     CborFloatType       = 0xfa,
79     CborDoubleType      = 0xfb,
80
81     CborInvalidType     = 0xff              /* equivalent to the break byte, so it will never be used */
82 } CborType;
83
84 typedef uint64_t CborTag;
85 typedef enum CborKnownTags {
86     CborDateTimeStringTag          = 0,        /* RFC 3339 format: YYYY-MM-DD hh:mm:ss+zzzz */
87     CborUnixTime_tTag              = 1,
88     CborPositiveBignumTag          = 2,
89     CborNegativeBignumTag          = 3,
90     CborDecimalTag                 = 4,
91     CborBigfloatTag                = 5,
92     CborExpectedBase64urlTag       = 21,
93     CborExpectedBase64Tag          = 22,
94     CborExpectedBase16Tag          = 23,
95     CborUriTag                     = 32,
96     CborBase64urlTag               = 33,
97     CborBase64Tag                  = 34,
98     CborRegularExpressionTag       = 35,
99     CborMimeMessageTag             = 36,       /* RFC 2045-2047 */
100     CborSignatureTag               = 55799
101 } CborKnownTags;
102
103 /* Error API */
104
105 typedef enum CborError {
106     CborNoError = 0,
107
108     /* errors in all modes */
109     CborUnknownError,
110     CborErrorUnknownLength,         /* request for length in array, map, or string with indeterminate length */
111     CborErrorAdvancePastEOF,
112     CborErrorIO,
113
114     /* parser errors streaming errors */
115     CborErrorGarbageAtEnd = 256,
116     CborErrorUnexpectedEOF,
117     CborErrorUnexpectedBreak,
118     CborErrorUnknownType,           /* can only heppen in major type 7 */
119     CborErrorIllegalType,           /* type not allowed here */
120     CborErrorIllegalNumber,
121     CborErrorIllegalSimpleType,     /* types of value less than 32 encoded in two bytes */
122
123     /* parser errors in strict mode parsing only */
124     CborErrorUnknownSimpleType = 512,
125     CborErrorUnknownTag,
126     CborErrorInappropriateTagForType,
127     CborErrorDuplicateObjectKeys,
128     CborErrorInvalidUtf8TextString,
129
130     /* encoder errors */
131     CborErrorTooManyItems = 768,
132     CborErrorTooFewItems,
133
134     /* internal implementation errors */
135     CborErrorDataTooLarge = 1024,
136     CborErrorNestingTooDeep,
137     CborErrorUnsupportedType,
138
139     /* errors in converting to JSON */
140     CborErrorJsonObjectKeyIsAggregate,
141     CborErrorJsonObjectKeyNotString,
142
143     CborErrorOutOfMemory = ~0U / 2 + 1,
144     CborErrorInternalError = ~0U
145 } CborError;
146
147 CBOR_API const char *cbor_error_string(CborError error);
148
149 /* Encoder API */
150 struct CborEncoder
151 {
152     union {
153         uint8_t *ptr;
154         ptrdiff_t bytes_needed;
155     };
156     const uint8_t *end;
157     size_t added;
158     int flags;
159 };
160 typedef struct CborEncoder CborEncoder;
161
162 static const size_t CborIndefiniteLength = SIZE_MAX;
163
164 CBOR_API void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags);
165 CBOR_API CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value);
166 CBOR_API CborError cbor_encode_int(CborEncoder *encoder, int64_t value);
167 CBOR_API CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value);
168 CBOR_API CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value);
169 CBOR_API CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag);
170 CBOR_API CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length);
171 CBOR_INLINE_API CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
172 { return cbor_encode_text_string(encoder, string, strlen(string)); }
173 CBOR_API CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length);
174 CBOR_API CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value);
175
176 CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
177 { return cbor_encode_simple_value(encoder, (int)value - 1 + (CborBooleanType & 0x1f)); }
178 CBOR_INLINE_API CborError cbor_encode_null(CborEncoder *encoder)
179 { return cbor_encode_simple_value(encoder, CborNullType & 0x1f); }
180 CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
181 { return cbor_encode_simple_value(encoder, CborUndefinedType & 0x1f); }
182
183 CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
184 { return cbor_encode_floating_point(encoder, CborHalfFloatType, value); }
185 CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
186 { return cbor_encode_floating_point(encoder, CborFloatType, &value); }
187 CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
188 { return cbor_encode_floating_point(encoder, CborDoubleType, &value); }
189
190 CBOR_API CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length);
191 CBOR_API CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length);
192 CBOR_API CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder);
193 CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder);
194
195 /* Parser API */
196
197 enum CborParserIteratorFlags
198 {
199     CborIteratorFlag_IntegerValueTooLarge   = 0x01,
200     CborIteratorFlag_NegativeInteger        = 0x02,
201     CborIteratorFlag_UnknownLength          = 0x04,
202     CborIteratorFlag_ContainerIsMap         = 0x20
203 };
204
205 struct CborParser
206 {
207     const uint8_t *end;
208     int flags;
209 };
210 typedef struct CborParser CborParser;
211
212 struct CborValue
213 {
214     const CborParser *parser;
215     const uint8_t *ptr;
216     uint32_t remaining;
217     uint16_t extra;
218     uint8_t type;
219     uint8_t flags;
220 };
221 typedef struct CborValue CborValue;
222
223 CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it);
224
225 CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
226 { return it->remaining == 0; }
227 CBOR_API CborError cbor_value_advance_fixed(CborValue *it);
228 CBOR_API CborError cbor_value_advance(CborValue *it);
229 CBOR_INLINE_API bool cbor_value_is_container(const CborValue *it)
230 { return it->type == CborArrayType || it->type == CborMapType; }
231 CBOR_API CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed);
232 CBOR_API CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed);
233
234 CBOR_PRIVATE_API uint64_t _cbor_value_decode_int64_internal(const CborValue *value);
235 CBOR_INLINE_API uint64_t _cbor_value_extract_int64_helper(const CborValue *value)
236 {
237     return value->flags & CborIteratorFlag_IntegerValueTooLarge ?
238                 _cbor_value_decode_int64_internal(value) : value->extra;
239 }
240
241 CBOR_INLINE_API bool cbor_value_is_valid(const CborValue *value)
242 { return value && value->type != CborInvalidType; }
243 CBOR_INLINE_API CborType cbor_value_get_type(const CborValue *value)
244 { return (CborType)value->type; }
245
246 /* Null & undefined type */
247 CBOR_INLINE_API bool cbor_type_is_null(const CborValue *value)
248 { return value->type == CborNullType; }
249 CBOR_INLINE_API bool cbor_type_is_undefined(const CborValue *value)
250 { return value->type == CborUndefinedType; }
251
252 /* Booleans */
253 CBOR_INLINE_API bool cbor_value_is_boolean(const CborValue *value)
254 { return value->type == CborBooleanType; }
255 CBOR_INLINE_API CborError cbor_value_get_boolean(const CborValue *value, bool *result)
256 {
257     assert(cbor_value_is_boolean(value));
258     *result = value->extra;
259     return CborNoError;
260 }
261
262 /* Simple types */
263 CBOR_INLINE_API bool cbor_value_is_simple_type(const CborValue *value)
264 { return value->type == CborSimpleType; }
265 CBOR_INLINE_API CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
266 {
267     assert(cbor_value_is_simple_type(value));
268     *result = value->extra;
269     return CborNoError;
270 }
271
272 /* Integers */
273 CBOR_INLINE_API bool cbor_value_is_integer(const CborValue *value)
274 { return value->type == CborIntegerType; }
275 CBOR_INLINE_API bool cbor_value_is_unsigned_integer(const CborValue *value)
276 { return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger) == 0; }
277 CBOR_INLINE_API bool cbor_value_is_negative_integer(const CborValue *value)
278 { return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger); }
279
280 CBOR_INLINE_API CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
281 {
282     assert(cbor_value_is_integer(value));
283     *result = _cbor_value_extract_int64_helper(value);
284     return CborNoError;
285 }
286
287 CBOR_INLINE_API CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
288 {
289     assert(cbor_value_is_unsigned_integer(value));
290     *result = _cbor_value_extract_int64_helper(value);
291     return CborNoError;
292 }
293
294 CBOR_INLINE_API CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
295 {
296     assert(cbor_value_is_integer(value));
297     *result = (int64_t) _cbor_value_extract_int64_helper(value);
298     if (value->flags & CborIteratorFlag_NegativeInteger)
299         *result = -*result - 1;
300     return CborNoError;
301 }
302
303 CBOR_INLINE_API CborError cbor_value_get_int(const CborValue *value, int *result)
304 {
305     assert(cbor_value_is_integer(value));
306     *result = (int) _cbor_value_extract_int64_helper(value);
307     if (value->flags & CborIteratorFlag_NegativeInteger)
308         *result = -*result - 1;
309     return CborNoError;
310 }
311
312 CBOR_API CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result);
313 CBOR_API CborError cbor_value_get_int_checked(const CborValue *value, int *result);
314
315 CBOR_INLINE_API bool cbor_value_is_length_known(const CborValue *value)
316 { return (value->flags & CborIteratorFlag_UnknownLength) == 0; }
317
318 /* Tags */
319 CBOR_INLINE_API bool cbor_value_is_tag(const CborValue *value)
320 { return value->type == CborTagType; }
321 CBOR_INLINE_API CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
322 {
323     assert(cbor_value_is_tag(value));
324     *result = _cbor_value_extract_int64_helper(value);
325     return CborNoError;
326 }
327 CBOR_API CborError cbor_value_skip_tag(CborValue *it);
328
329 /* Strings */
330 CBOR_INLINE_API bool cbor_value_is_byte_string(const CborValue *value)
331 { return value->type == CborByteStringType; }
332 CBOR_INLINE_API bool cbor_value_is_text_string(const CborValue *value)
333 { return value->type == CborTextStringType; }
334
335 CBOR_INLINE_API CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
336 {
337     assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
338     if (!cbor_value_is_length_known(value))
339         return CborErrorUnknownLength;
340     uint64_t v = _cbor_value_extract_int64_helper(value);
341     *length = v;
342     if (*length != v)
343         return CborErrorDataTooLarge;
344     return CborNoError;
345 }
346
347 CBOR_PRIVATE_API CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
348                                                    size_t *buflen, CborValue *next);
349 CBOR_PRIVATE_API CborError _cbor_value_dup_string(const CborValue *value, void **buffer,
350                                                   size_t *buflen, CborValue *next);
351
352 CBOR_API CborError cbor_value_calculate_string_length(const CborValue *value, size_t *length);
353
354 CBOR_INLINE_API CborError cbor_value_copy_text_string(const CborValue *value, char *buffer,
355                                                       size_t *buflen, CborValue *next)
356 {
357     assert(cbor_value_is_text_string(value));
358     return _cbor_value_copy_string(value, buffer, buflen, next);
359 }
360 CBOR_INLINE_API CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer,
361                                                       size_t *buflen, CborValue *next)
362 {
363     assert(cbor_value_is_byte_string(value));
364     return _cbor_value_copy_string(value, buffer, buflen, next);
365 }
366
367 CBOR_INLINE_API CborError cbor_value_dup_text_string(const CborValue *value, char **buffer,
368                                                      size_t *buflen, CborValue *next)
369 {
370     assert(cbor_value_is_text_string(value));
371     return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
372 }
373 CBOR_INLINE_API CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer,
374                                                      size_t *buflen, CborValue *next)
375 {
376     assert(cbor_value_is_byte_string(value));
377     return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
378 }
379
380 /* ### TBD: partial reading API */
381
382 CBOR_API CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result);
383
384 /* Maps and arrays */
385 CBOR_INLINE_API bool cbor_value_is_array(const CborValue *value)
386 { return value->type == CborArrayType; }
387 CBOR_INLINE_API bool cbor_value_is_map(const CborValue *value)
388 { return value->type == CborMapType; }
389
390 CBOR_INLINE_API CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
391 {
392     assert(cbor_value_is_array(value));
393     if (!cbor_value_is_length_known(value))
394         return CborErrorUnknownLength;
395     uint64_t v = _cbor_value_extract_int64_helper(value);
396     *length = v;
397     if (*length != v)
398         return CborErrorDataTooLarge;
399     return CborNoError;
400 }
401
402 CBOR_INLINE_API CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
403 {
404     assert(cbor_value_is_map(value));
405     if (!cbor_value_is_length_known(value))
406         return CborErrorUnknownLength;
407     uint64_t v = _cbor_value_extract_int64_helper(value);
408     *length = v;
409     if (*length != v)
410         return CborErrorDataTooLarge;
411     return CborNoError;
412 }
413
414 CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element);
415
416 /* Floating point */
417 CBOR_API CborError cbor_value_get_half_float(const CborValue *value, void *result);
418 CBOR_INLINE_API CborError cbor_value_get_float(const CborValue *value, float *result)
419 {
420     assert(value->type == CborFloatType);
421     assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
422     uint32_t data = _cbor_value_decode_int64_internal(value);
423     memcpy(result, &data, sizeof(*result));
424     return CborNoError;
425 }
426
427 CBOR_INLINE_API CborError cbor_value_get_double(const CborValue *value, double *result)
428 {
429     assert(value->type == CborDoubleType);
430     assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
431     uint64_t data = _cbor_value_decode_int64_internal(value);
432     memcpy(result, &data, sizeof(*result));
433     return CborNoError;
434 }
435
436 /* Human-readable (dump) API */
437 CBOR_API CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value);
438 CBOR_INLINE_API CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
439 {
440     CborValue copy = *value;
441     return cbor_value_to_pretty_advance(out, &copy);
442 }
443
444 #ifdef __cplusplus
445 }
446 #endif
447
448 #endif // CBOR_H
449