xref: /freebsd/contrib/libcbor/src/cbor/data.h (revision 5d3e7166)
110ff414cSEd Maste /*
210ff414cSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
310ff414cSEd Maste  *
410ff414cSEd Maste  * libcbor is free software; you can redistribute it and/or modify
510ff414cSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
610ff414cSEd Maste  */
710ff414cSEd Maste 
810ff414cSEd Maste #ifndef LIBCBOR_DATA_H
910ff414cSEd Maste #define LIBCBOR_DATA_H
1010ff414cSEd Maste 
1110ff414cSEd Maste #include <stdbool.h>
1210ff414cSEd Maste #include <stddef.h>
1310ff414cSEd Maste #include <stdint.h>
1410ff414cSEd Maste #include <stdlib.h>
1510ff414cSEd Maste 
1610ff414cSEd Maste #ifdef __cplusplus
1710ff414cSEd Maste extern "C" {
1810ff414cSEd Maste #endif
1910ff414cSEd Maste 
2010ff414cSEd Maste typedef const unsigned char* cbor_data;
2110ff414cSEd Maste typedef unsigned char* cbor_mutable_data;
2210ff414cSEd Maste 
2310ff414cSEd Maste /** Specifies the Major type of ::cbor_item_t */
2410ff414cSEd Maste typedef enum cbor_type {
2510ff414cSEd Maste   CBOR_TYPE_UINT /** 0 - positive integers */
2610ff414cSEd Maste   ,
2710ff414cSEd Maste   CBOR_TYPE_NEGINT /** 1 - negative integers*/
2810ff414cSEd Maste   ,
2910ff414cSEd Maste   CBOR_TYPE_BYTESTRING /** 2 - byte strings */
3010ff414cSEd Maste   ,
3110ff414cSEd Maste   CBOR_TYPE_STRING /** 3 - strings */
3210ff414cSEd Maste   ,
3310ff414cSEd Maste   CBOR_TYPE_ARRAY /** 4 - arrays */
3410ff414cSEd Maste   ,
3510ff414cSEd Maste   CBOR_TYPE_MAP /** 5 - maps */
3610ff414cSEd Maste   ,
3710ff414cSEd Maste   CBOR_TYPE_TAG /** 6 - tags  */
3810ff414cSEd Maste   ,
3910ff414cSEd Maste   CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil,
4010ff414cSEd Maste                           ...) */
4110ff414cSEd Maste } cbor_type;
4210ff414cSEd Maste 
4310ff414cSEd Maste /** Possible decoding errors */
4410ff414cSEd Maste typedef enum {
4510ff414cSEd Maste   CBOR_ERR_NONE,
4610ff414cSEd Maste   CBOR_ERR_NOTENOUGHDATA,
4710ff414cSEd Maste   CBOR_ERR_NODATA,
48*5d3e7166SEd Maste   // TODO: Should be "malformed" or at least "malformatted". Retained for
49*5d3e7166SEd Maste   // backwards compatibility.
5010ff414cSEd Maste   CBOR_ERR_MALFORMATED,
5110ff414cSEd Maste   CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for
5210ff414cSEd Maste                        your allocator? */
5310ff414cSEd Maste   ,
5410ff414cSEd Maste   CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */
5510ff414cSEd Maste } cbor_error_code;
5610ff414cSEd Maste 
5710ff414cSEd Maste /** Possible widths of #CBOR_TYPE_UINT items */
5810ff414cSEd Maste typedef enum {
5910ff414cSEd Maste   CBOR_INT_8,
6010ff414cSEd Maste   CBOR_INT_16,
6110ff414cSEd Maste   CBOR_INT_32,
6210ff414cSEd Maste   CBOR_INT_64
6310ff414cSEd Maste } cbor_int_width;
6410ff414cSEd Maste 
6510ff414cSEd Maste /** Possible widths of #CBOR_TYPE_FLOAT_CTRL items */
6610ff414cSEd Maste typedef enum {
6710ff414cSEd Maste   CBOR_FLOAT_0 /** Internal use - ctrl and special values */
6810ff414cSEd Maste   ,
6910ff414cSEd Maste   CBOR_FLOAT_16 /** Half float */
7010ff414cSEd Maste   ,
7110ff414cSEd Maste   CBOR_FLOAT_32 /** Single float */
7210ff414cSEd Maste   ,
7310ff414cSEd Maste   CBOR_FLOAT_64 /** Double */
7410ff414cSEd Maste } cbor_float_width;
7510ff414cSEd Maste 
7610ff414cSEd Maste /** Metadata for dynamically sized types */
7710ff414cSEd Maste typedef enum {
7810ff414cSEd Maste   _CBOR_METADATA_DEFINITE,
7910ff414cSEd Maste   _CBOR_METADATA_INDEFINITE
8010ff414cSEd Maste } _cbor_dst_metadata;
8110ff414cSEd Maste 
8210ff414cSEd Maste /** Semantic mapping for CTRL simple values */
8310ff414cSEd Maste typedef enum {
8410ff414cSEd Maste   CBOR_CTRL_NONE = 0,
8510ff414cSEd Maste   CBOR_CTRL_FALSE = 20,
8610ff414cSEd Maste   CBOR_CTRL_TRUE = 21,
8710ff414cSEd Maste   CBOR_CTRL_NULL = 22,
8810ff414cSEd Maste   CBOR_CTRL_UNDEF = 23
8910ff414cSEd Maste } _cbor_ctrl;
9010ff414cSEd Maste 
91*5d3e7166SEd Maste // Metadata items use size_t (instead of uint64_t) because items in memory take
92*5d3e7166SEd Maste // up at least 1B per entry or string byte, so if size_t is narrower than
93*5d3e7166SEd Maste // uint64_t, we wouldn't be able to create them in the first place and can save
94*5d3e7166SEd Maste // some space.
95*5d3e7166SEd Maste 
9610ff414cSEd Maste /** Integers specific metadata */
9710ff414cSEd Maste struct _cbor_int_metadata {
9810ff414cSEd Maste   cbor_int_width width;
9910ff414cSEd Maste };
10010ff414cSEd Maste 
10110ff414cSEd Maste /** Bytestrings specific metadata */
10210ff414cSEd Maste struct _cbor_bytestring_metadata {
10310ff414cSEd Maste   size_t length;
10410ff414cSEd Maste   _cbor_dst_metadata type;
10510ff414cSEd Maste };
10610ff414cSEd Maste 
10710ff414cSEd Maste /** Strings specific metadata */
10810ff414cSEd Maste struct _cbor_string_metadata {
10910ff414cSEd Maste   size_t length;
11010ff414cSEd Maste   size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite
11110ff414cSEd Maste                              strings */
11210ff414cSEd Maste   _cbor_dst_metadata type;
11310ff414cSEd Maste };
11410ff414cSEd Maste 
11510ff414cSEd Maste /** Arrays specific metadata */
11610ff414cSEd Maste struct _cbor_array_metadata {
11710ff414cSEd Maste   size_t allocated;
11810ff414cSEd Maste   size_t end_ptr;
11910ff414cSEd Maste   _cbor_dst_metadata type;
12010ff414cSEd Maste };
12110ff414cSEd Maste 
12210ff414cSEd Maste /** Maps specific metadata */
12310ff414cSEd Maste struct _cbor_map_metadata {
12410ff414cSEd Maste   size_t allocated;
12510ff414cSEd Maste   size_t end_ptr;
12610ff414cSEd Maste   _cbor_dst_metadata type;
12710ff414cSEd Maste };
12810ff414cSEd Maste 
12910ff414cSEd Maste /** Arrays specific metadata
13010ff414cSEd Maste  *
13110ff414cSEd Maste  * The pointer is included - cbor_item_metadata is
13210ff414cSEd Maste  * 2 * sizeof(size_t) + sizeof(_cbor_string_type_metadata),
13310ff414cSEd Maste  * lets use the space
13410ff414cSEd Maste  */
13510ff414cSEd Maste struct _cbor_tag_metadata {
13610ff414cSEd Maste   struct cbor_item_t* tagged_item;
13710ff414cSEd Maste   uint64_t value;
13810ff414cSEd Maste };
13910ff414cSEd Maste 
14010ff414cSEd Maste /** Floats specific metadata - includes CTRL values */
14110ff414cSEd Maste struct _cbor_float_ctrl_metadata {
14210ff414cSEd Maste   cbor_float_width width;
14310ff414cSEd Maste   uint8_t ctrl;
14410ff414cSEd Maste };
14510ff414cSEd Maste 
14610ff414cSEd Maste /** Raw memory casts helper */
14710ff414cSEd Maste union _cbor_float_helper {
14810ff414cSEd Maste   float as_float;
14910ff414cSEd Maste   uint32_t as_uint;
15010ff414cSEd Maste };
15110ff414cSEd Maste 
15210ff414cSEd Maste /** Raw memory casts helper */
15310ff414cSEd Maste union _cbor_double_helper {
15410ff414cSEd Maste   double as_double;
15510ff414cSEd Maste   uint64_t as_uint;
15610ff414cSEd Maste };
15710ff414cSEd Maste 
15810ff414cSEd Maste /** Union of metadata across all possible types - discriminated in #cbor_item_t
15910ff414cSEd Maste  */
16010ff414cSEd Maste union cbor_item_metadata {
16110ff414cSEd Maste   struct _cbor_int_metadata int_metadata;
16210ff414cSEd Maste   struct _cbor_bytestring_metadata bytestring_metadata;
16310ff414cSEd Maste   struct _cbor_string_metadata string_metadata;
16410ff414cSEd Maste   struct _cbor_array_metadata array_metadata;
16510ff414cSEd Maste   struct _cbor_map_metadata map_metadata;
16610ff414cSEd Maste   struct _cbor_tag_metadata tag_metadata;
16710ff414cSEd Maste   struct _cbor_float_ctrl_metadata float_ctrl_metadata;
16810ff414cSEd Maste };
16910ff414cSEd Maste 
17010ff414cSEd Maste /** The item handle */
17110ff414cSEd Maste typedef struct cbor_item_t {
17210ff414cSEd Maste   /** Discriminated by type */
17310ff414cSEd Maste   union cbor_item_metadata metadata;
17410ff414cSEd Maste   /** Reference count - initialize to 0 */
17510ff414cSEd Maste   size_t refcount;
17610ff414cSEd Maste   /** Major type discriminator */
17710ff414cSEd Maste   cbor_type type;
17810ff414cSEd Maste   /** Raw data block - interpretation depends on metadata */
17910ff414cSEd Maste   unsigned char* data;
18010ff414cSEd Maste } cbor_item_t;
18110ff414cSEd Maste 
18210ff414cSEd Maste /** Defines cbor_item_t#data structure for indefinite strings and bytestrings
18310ff414cSEd Maste  *
18410ff414cSEd Maste  * Used to cast the raw representation for a sane manipulation
18510ff414cSEd Maste  */
18610ff414cSEd Maste struct cbor_indefinite_string_data {
18710ff414cSEd Maste   size_t chunk_count;
18810ff414cSEd Maste   size_t chunk_capacity;
18910ff414cSEd Maste   cbor_item_t** chunks;
19010ff414cSEd Maste };
19110ff414cSEd Maste 
19210ff414cSEd Maste /** High-level decoding error */
19310ff414cSEd Maste struct cbor_error {
194*5d3e7166SEd Maste   /** Approximate position */
19510ff414cSEd Maste   size_t position;
19610ff414cSEd Maste   /** Description */
19710ff414cSEd Maste   cbor_error_code code;
19810ff414cSEd Maste };
19910ff414cSEd Maste 
20010ff414cSEd Maste /** Simple pair of items for use in maps */
20110ff414cSEd Maste struct cbor_pair {
20210ff414cSEd Maste   cbor_item_t *key, *value;
20310ff414cSEd Maste };
20410ff414cSEd Maste 
20510ff414cSEd Maste /** High-level decoding result */
20610ff414cSEd Maste struct cbor_load_result {
20710ff414cSEd Maste   /** Error indicator */
20810ff414cSEd Maste   struct cbor_error error;
20910ff414cSEd Maste   /** Number of bytes read */
21010ff414cSEd Maste   size_t read;
21110ff414cSEd Maste };
21210ff414cSEd Maste 
21310ff414cSEd Maste /** Streaming decoder result - status */
21410ff414cSEd Maste enum cbor_decoder_status {
21510ff414cSEd Maste   /** Decoding finished successfully (a callback has been invoked)
21610ff414cSEd Maste    *
21710ff414cSEd Maste    * Note that this does *not* mean that the buffer has been fully decoded;
21810ff414cSEd Maste    * there may still be unread bytes for which no callback has been involved.
21910ff414cSEd Maste    */
22010ff414cSEd Maste   CBOR_DECODER_FINISHED,
22110ff414cSEd Maste   /** Not enough data to invoke a callback */
222*5d3e7166SEd Maste   // TODO: The name is inconsistent with CBOR_ERR_NOTENOUGHDATA. Retained for
223*5d3e7166SEd Maste   // backwards compatibility.
22410ff414cSEd Maste   CBOR_DECODER_NEDATA,
22510ff414cSEd Maste   /** Bad data (reserved MTB, malformed value, etc.)  */
22610ff414cSEd Maste   CBOR_DECODER_ERROR
22710ff414cSEd Maste };
22810ff414cSEd Maste 
22910ff414cSEd Maste /** Streaming decoder result */
23010ff414cSEd Maste struct cbor_decoder_result {
23110ff414cSEd Maste   /** Input bytes read/consumed
23210ff414cSEd Maste    *
23310ff414cSEd Maste    * If this is less than the size of input buffer, the client will likely
23410ff414cSEd Maste    * resume parsing starting at the next byte (e.g. `buffer + result.read`).
23510ff414cSEd Maste    *
23610ff414cSEd Maste    * Set to 0 if the #status is not #CBOR_DECODER_FINISHED.
23710ff414cSEd Maste    */
23810ff414cSEd Maste   size_t read;
23910ff414cSEd Maste 
24010ff414cSEd Maste   /** The decoding status */
24110ff414cSEd Maste   enum cbor_decoder_status status;
24210ff414cSEd Maste 
24310ff414cSEd Maste   /** Number of bytes in the input buffer needed to resume parsing
24410ff414cSEd Maste    *
24510ff414cSEd Maste    * Set to 0 unless the result status is #CBOR_DECODER_NEDATA. If it is, then:
24610ff414cSEd Maste    *  - If at least one byte was passed, #required will be set to the minimum
24710ff414cSEd Maste    *    number of bytes needed to invoke a decoded callback on the current
24810ff414cSEd Maste    *    prefix.
24910ff414cSEd Maste    *
25010ff414cSEd Maste    *    For example: Attempting to decode a 1B buffer containing `0x19` will
25110ff414cSEd Maste    *    set #required to 3 as `0x19` signals a 2B integer item, so we need at
25210ff414cSEd Maste    *    least 3B to continue (the `0x19` MTB byte and two bytes of data needed
25310ff414cSEd Maste    *    to invoke #cbor_callbacks.uint16).
25410ff414cSEd Maste    *
25510ff414cSEd Maste    *  - If there was no data at all, #read will always be set to 1
25610ff414cSEd Maste    */
25710ff414cSEd Maste   size_t required;
25810ff414cSEd Maste };
25910ff414cSEd Maste 
26010ff414cSEd Maste #ifdef __cplusplus
26110ff414cSEd Maste }
26210ff414cSEd Maste #endif
26310ff414cSEd Maste 
26410ff414cSEd Maste #endif  // LIBCBOR_DATA_H
265