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