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