1 /* 2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 3 * 4 * libcbor is free software; you can redistribute it and/or modify 5 * it under the terms of the MIT license. See LICENSE for details. 6 */ 7 8 #ifndef LIBCBOR_DATA_H 9 #define LIBCBOR_DATA_H 10 11 #include <stdbool.h> 12 #include <stddef.h> 13 #include <stdint.h> 14 #include <stdlib.h> 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 typedef const unsigned char* cbor_data; 21 typedef unsigned char* cbor_mutable_data; 22 23 /** Specifies the Major type of ::cbor_item_t */ 24 typedef enum cbor_type { 25 CBOR_TYPE_UINT /** 0 - positive integers */ 26 , 27 CBOR_TYPE_NEGINT /** 1 - negative integers*/ 28 , 29 CBOR_TYPE_BYTESTRING /** 2 - byte strings */ 30 , 31 CBOR_TYPE_STRING /** 3 - strings */ 32 , 33 CBOR_TYPE_ARRAY /** 4 - arrays */ 34 , 35 CBOR_TYPE_MAP /** 5 - maps */ 36 , 37 CBOR_TYPE_TAG /** 6 - tags */ 38 , 39 CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil, 40 ...) */ 41 } cbor_type; 42 43 /** Possible decoding errors */ 44 typedef enum { 45 CBOR_ERR_NONE, 46 CBOR_ERR_NOTENOUGHDATA, 47 CBOR_ERR_NODATA, 48 CBOR_ERR_MALFORMATED, 49 CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for 50 your allocator? */ 51 , 52 CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */ 53 } cbor_error_code; 54 55 /** Possible widths of #CBOR_TYPE_UINT items */ 56 typedef enum { 57 CBOR_INT_8, 58 CBOR_INT_16, 59 CBOR_INT_32, 60 CBOR_INT_64 61 } cbor_int_width; 62 63 /** Possible widths of #CBOR_TYPE_FLOAT_CTRL items */ 64 typedef enum { 65 CBOR_FLOAT_0 /** Internal use - ctrl and special values */ 66 , 67 CBOR_FLOAT_16 /** Half float */ 68 , 69 CBOR_FLOAT_32 /** Single float */ 70 , 71 CBOR_FLOAT_64 /** Double */ 72 } cbor_float_width; 73 74 /** Metadata for dynamically sized types */ 75 typedef enum { 76 _CBOR_METADATA_DEFINITE, 77 _CBOR_METADATA_INDEFINITE 78 } _cbor_dst_metadata; 79 80 /** Semantic mapping for CTRL simple values */ 81 typedef enum { 82 CBOR_CTRL_NONE = 0, 83 CBOR_CTRL_FALSE = 20, 84 CBOR_CTRL_TRUE = 21, 85 CBOR_CTRL_NULL = 22, 86 CBOR_CTRL_UNDEF = 23 87 } _cbor_ctrl; 88 89 /** Integers specific metadata */ 90 struct _cbor_int_metadata { 91 cbor_int_width width; 92 }; 93 94 /** Bytestrings specific metadata */ 95 struct _cbor_bytestring_metadata { 96 size_t length; 97 _cbor_dst_metadata type; 98 }; 99 100 /** Strings specific metadata */ 101 struct _cbor_string_metadata { 102 size_t length; 103 size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite 104 strings */ 105 _cbor_dst_metadata type; 106 }; 107 108 /** Arrays specific metadata */ 109 struct _cbor_array_metadata { 110 size_t allocated; 111 size_t end_ptr; 112 _cbor_dst_metadata type; 113 }; 114 115 /** Maps specific metadata */ 116 struct _cbor_map_metadata { 117 size_t allocated; 118 size_t end_ptr; 119 _cbor_dst_metadata type; 120 }; 121 122 /** Arrays specific metadata 123 * 124 * The pointer is included - cbor_item_metadata is 125 * 2 * sizeof(size_t) + sizeof(_cbor_string_type_metadata), 126 * lets use the space 127 */ 128 struct _cbor_tag_metadata { 129 struct cbor_item_t* tagged_item; 130 uint64_t value; 131 }; 132 133 /** Floats specific metadata - includes CTRL values */ 134 struct _cbor_float_ctrl_metadata { 135 cbor_float_width width; 136 uint8_t ctrl; 137 }; 138 139 /** Raw memory casts helper */ 140 union _cbor_float_helper { 141 float as_float; 142 uint32_t as_uint; 143 }; 144 145 /** Raw memory casts helper */ 146 union _cbor_double_helper { 147 double as_double; 148 uint64_t as_uint; 149 }; 150 151 /** Union of metadata across all possible types - discriminated in #cbor_item_t 152 */ 153 union cbor_item_metadata { 154 struct _cbor_int_metadata int_metadata; 155 struct _cbor_bytestring_metadata bytestring_metadata; 156 struct _cbor_string_metadata string_metadata; 157 struct _cbor_array_metadata array_metadata; 158 struct _cbor_map_metadata map_metadata; 159 struct _cbor_tag_metadata tag_metadata; 160 struct _cbor_float_ctrl_metadata float_ctrl_metadata; 161 }; 162 163 /** The item handle */ 164 typedef struct cbor_item_t { 165 /** Discriminated by type */ 166 union cbor_item_metadata metadata; 167 /** Reference count - initialize to 0 */ 168 size_t refcount; 169 /** Major type discriminator */ 170 cbor_type type; 171 /** Raw data block - interpretation depends on metadata */ 172 unsigned char* data; 173 } cbor_item_t; 174 175 /** Defines cbor_item_t#data structure for indefinite strings and bytestrings 176 * 177 * Used to cast the raw representation for a sane manipulation 178 */ 179 struct cbor_indefinite_string_data { 180 size_t chunk_count; 181 size_t chunk_capacity; 182 cbor_item_t** chunks; 183 }; 184 185 /** High-level decoding error */ 186 struct cbor_error { 187 /** Aproximate position */ 188 size_t position; 189 /** Description */ 190 cbor_error_code code; 191 }; 192 193 /** Simple pair of items for use in maps */ 194 struct cbor_pair { 195 cbor_item_t *key, *value; 196 }; 197 198 /** High-level decoding result */ 199 struct cbor_load_result { 200 /** Error indicator */ 201 struct cbor_error error; 202 /** Number of bytes read */ 203 size_t read; 204 }; 205 206 /** Streaming decoder result - status */ 207 enum cbor_decoder_status { 208 /** Decoding finished successfully (a callback has been invoked) 209 * 210 * Note that this does *not* mean that the buffer has been fully decoded; 211 * there may still be unread bytes for which no callback has been involved. 212 */ 213 CBOR_DECODER_FINISHED, 214 /** Not enough data to invoke a callback */ 215 CBOR_DECODER_NEDATA, 216 /** Bad data (reserved MTB, malformed value, etc.) */ 217 CBOR_DECODER_ERROR 218 }; 219 220 /** Streaming decoder result */ 221 struct cbor_decoder_result { 222 /** Input bytes read/consumed 223 * 224 * If this is less than the size of input buffer, the client will likely 225 * resume parsing starting at the next byte (e.g. `buffer + result.read`). 226 * 227 * Set to 0 if the #status is not #CBOR_DECODER_FINISHED. 228 */ 229 size_t read; 230 231 /** The decoding status */ 232 enum cbor_decoder_status status; 233 234 /** Number of bytes in the input buffer needed to resume parsing 235 * 236 * Set to 0 unless the result status is #CBOR_DECODER_NEDATA. If it is, then: 237 * - If at least one byte was passed, #required will be set to the minimum 238 * number of bytes needed to invoke a decoded callback on the current 239 * prefix. 240 * 241 * For example: Attempting to decode a 1B buffer containing `0x19` will 242 * set #required to 3 as `0x19` signals a 2B integer item, so we need at 243 * least 3B to continue (the `0x19` MTB byte and two bytes of data needed 244 * to invoke #cbor_callbacks.uint16). 245 * 246 * - If there was no data at all, #read will always be set to 1 247 */ 248 size_t required; 249 }; 250 251 #ifdef __cplusplus 252 } 253 #endif 254 255 #endif // LIBCBOR_DATA_H 256