Home | History | Annotate | Line # | Download | only in cbor
      1 /*
      2  * Copyright (c) 2014-2019 Pavel Kalvoda <me (at) 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   CBOR_DECODER_FINISHED /** OK, finished */
    209   ,
    210   CBOR_DECODER_NEDATA /** Not enough data - mismatch with MTB */
    211   ,
    212   CBOR_DECODER_EBUFFER /** Buffer manipulation problem */
    213   ,
    214   CBOR_DECODER_ERROR /** Malformed or reserved MTB/value */
    215 };
    216 
    217 /** Streaming decoder result */
    218 struct cbor_decoder_result {
    219   /** Bytes read */
    220   size_t read;
    221   /** The result */
    222   enum cbor_decoder_status status;
    223   /** When status == CBOR_DECODER_NEDATA,
    224    *  the minimum number of bytes required to continue parsing */
    225   size_t required;
    226 };
    227 
    228 #ifdef __cplusplus
    229 }
    230 #endif
    231 
    232 #endif  // LIBCBOR_DATA_H
    233