From d31766d827c085dea004ebf7209ab45eddaad02b Mon Sep 17 00:00:00 2001 From: rimio Date: Fri, 2 Mar 2018 01:42:43 +0200 Subject: Various fixes and refactoring. --- include/ecbor.h | 207 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 138 insertions(+), 69 deletions(-) (limited to 'include') diff --git a/include/ecbor.h b/include/ecbor.h index a0c166c..6408d3d 100644 --- a/include/ecbor.h +++ b/include/ecbor.h @@ -9,6 +9,7 @@ #define _ECBOR_H_ #include +#include /* * Error codes @@ -22,23 +23,23 @@ typedef enum { ECBOR_ERR_NULL_CONTEXT = 10, ECBOR_ERR_NULL_INPUT_BUFFER = 11, ECBOR_ERR_NULL_OUTPUT_BUFFER = 12, - ECBOR_ERR_NULL_NODE_BUFFER = 13, + ECBOR_ERR_NULL_ITEM_BUFFER = 13, ECBOR_ERR_NULL_VALUE = 14, ECBOR_ERR_NULL_ARRAY = 15, ECBOR_ERR_NULL_MAP = 16, ECBOR_ERR_NULL_ITEM = 20, - ECBOR_ERR_NULL_NODE = 21, ECBOR_ERR_WRONG_MODE = 30, /* bounds errors */ ECBOR_ERR_INVALID_END_OF_BUFFER = 50, - ECBOR_ERR_END_OF_NODE_BUFFER = 51, - ECBOR_ERR_EMPTY_NODE_BUFFER = 52, + ECBOR_ERR_END_OF_ITEM_BUFFER = 51, + ECBOR_ERR_EMPTY_ITEM_BUFFER = 52, ECBOR_ERR_INDEX_OUT_OF_BOUNDS = 53, ECBOR_ERR_WONT_RETURN_INDEFINITE = 54, ECBOR_ERR_WONT_RETURN_DEFINITE = 55, + ECBOR_ERR_VALUE_OVERFLOW = 56, /* semantic errors */ ECBOR_ERR_CURRENTLY_NOT_SUPPORTED = 100, @@ -95,7 +96,8 @@ typedef enum { /* * CBOR Item */ -typedef struct { +typedef struct ecbor_item ecbor_item_t; +struct ecbor_item { /* item type */ ecbor_type_t type; @@ -111,35 +113,29 @@ typedef struct { } tag; struct { const uint8_t *str; - uint64_t n_chunks; + size_t n_chunks; } string; const uint8_t *items; } value; /* storage size (serialized) of item, in bytes */ - uint64_t size; + size_t size; /* length of value; can mean different things: * - payload (value) size, in bytes, for ints and strings * - number of items in arrays and maps */ - uint64_t length; + size_t length; /* non-zero if size is indefinite (for strings, maps and arrays) */ uint8_t is_indefinite; -} ecbor_item_t; - -/* - * CBOR tree node - */ -typedef struct ecbor_node ecbor_node_t; -struct ecbor_node { - ecbor_item_t item; - ecbor_node_t *parent; - ecbor_node_t *child; /* first child */ - ecbor_node_t *next; /* next in array or map */ - ecbor_node_t *prev; /* ditto */ - uint64_t index; /* index in array or map */ + + /* tree links and metainformation (only populated in tree decoder mode) */ + ecbor_item_t *parent; + ecbor_item_t *child; /* first child */ + ecbor_item_t *next; /* next in array or map */ + ecbor_item_t *prev; /* ditto */ + size_t index; /* index in array or map */ }; /* @@ -163,7 +159,7 @@ typedef struct { uint8_t *out_position; /* remaining bytes */ - unsigned int bytes_left; + size_t bytes_left; } ecbor_encode_context_t; typedef struct { @@ -174,16 +170,16 @@ typedef struct { const uint8_t *in_position; /* remaining bytes */ - uint64_t bytes_left; + size_t bytes_left; - /* node buffer */ - ecbor_node_t *nodes; + /* item buffer */ + ecbor_item_t *items; /* capacity of item buffer (in items) */ - unsigned int node_capacity; + size_t item_capacity; /* number of used items so far */ - unsigned int n_nodes; + size_t n_items; } ecbor_decode_context_t; @@ -193,19 +189,19 @@ typedef struct { extern ecbor_error_t ecbor_initialize_decode (ecbor_decode_context_t *context, const uint8_t *buffer, - uint64_t buffer_size); + size_t buffer_size); extern ecbor_error_t ecbor_initialize_decode_streamed (ecbor_decode_context_t *context, const uint8_t *buffer, - uint64_t buffer_size); + size_t buffer_size); extern ecbor_error_t ecbor_initialize_decode_tree (ecbor_decode_context_t *context, const uint8_t *buffer, - uint64_t buffer_size, - ecbor_node_t *node_buffer, - uint64_t node_capacity); + size_t buffer_size, + ecbor_item_t *item_buffer, + size_t item_capacity); /* @@ -220,103 +216,176 @@ extern ecbor_error_t ecbor_decode (ecbor_decode_context_t *context, ecbor_item_t *item); extern ecbor_error_t -ecbor_decode_tree (ecbor_decode_context_t *context); +ecbor_decode_tree (ecbor_decode_context_t *context, ecbor_item_t **root); /* * Tree API */ -extern ecbor_error_t -ecbor_get_root (ecbor_decode_context_t *context, ecbor_node_t **root); /* * Strict API */ + +/* Metadata */ extern ecbor_type_t ecbor_get_type (ecbor_item_t *item); extern ecbor_error_t -ecbor_get_value (ecbor_item_t *item, void *value); +ecbor_get_length (ecbor_item_t *item, size_t *length); -extern ecbor_error_t -ecbor_get_length (ecbor_item_t *item, uint64_t *length); +/* Child items */ extern ecbor_error_t -ecbor_get_array_item (ecbor_item_t *array, uint64_t index, +ecbor_get_array_item (ecbor_item_t *array, size_t index, ecbor_item_t *arr_item); extern ecbor_error_t -ecbor_get_map_item (ecbor_item_t *map, uint64_t index, ecbor_item_t *key, +ecbor_get_array_item_ptr (ecbor_item_t *array, size_t index, + ecbor_item_t **item); + +extern ecbor_error_t +ecbor_get_map_item (ecbor_item_t *map, size_t index, ecbor_item_t *key, ecbor_item_t *value); extern ecbor_error_t -ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *arr_item); +ecbor_get_map_item_ptr (ecbor_item_t *map, size_t index, ecbor_item_t **key, + ecbor_item_t **value); + +extern ecbor_error_t +ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *item); + +extern ecbor_error_t +ecbor_get_tag_item_ptr (ecbor_item_t *tag, ecbor_item_t **item); + + +/* Ints */ +extern ecbor_error_t +ecbor_get_uint8 (ecbor_item_t *item, uint8_t *value); + +extern ecbor_error_t +ecbor_get_uint16 (ecbor_item_t *item, uint16_t *value); + +extern ecbor_error_t +ecbor_get_uint32 (ecbor_item_t *item, uint32_t *value); + +extern ecbor_error_t +ecbor_get_uint64 (ecbor_item_t *item, uint64_t *value); + + +extern ecbor_error_t +ecbor_get_int8 (ecbor_item_t *item, int8_t *value); + +extern ecbor_error_t +ecbor_get_int16 (ecbor_item_t *item, int16_t *value); +extern ecbor_error_t +ecbor_get_int32 (ecbor_item_t *item, int32_t *value); +extern ecbor_error_t +ecbor_get_int64 (ecbor_item_t *item, int64_t *value); + + +/* Strings */ extern ecbor_error_t ecbor_get_str (ecbor_item_t *str, char **value); extern ecbor_error_t -ecbor_get_str_chunk_count (ecbor_item_t *str, uint64_t *count); +ecbor_get_str_chunk_count (ecbor_item_t *str, size_t *count); extern ecbor_error_t -ecbor_get_str_chunk (ecbor_item_t *str, uint64_t index, ecbor_item_t *chunk); +ecbor_get_str_chunk (ecbor_item_t *str, size_t index, ecbor_item_t *chunk); extern ecbor_error_t ecbor_get_bstr (ecbor_item_t *str, uint8_t **value); extern ecbor_error_t -ecbor_get_bstr_chunk_count (ecbor_item_t *str, uint64_t *count); +ecbor_get_bstr_chunk_count (ecbor_item_t *str, size_t *count); + +extern ecbor_error_t +ecbor_get_bstr_chunk (ecbor_item_t *str, size_t index, ecbor_item_t *chunk); + +/* Tag */ extern ecbor_error_t -ecbor_get_bstr_chunk (ecbor_item_t *str, uint64_t index, ecbor_item_t *chunk); +ecbor_get_tag_value (ecbor_item_t *tag, uint64_t *tag_value); + + +/* Floating point */ +extern ecbor_error_t +ecbor_get_fp32 (ecbor_item_t *item, float *value); + +extern ecbor_error_t +ecbor_get_fp64 (ecbor_item_t *item, double *value); + + +/* Boolean */ +extern ecbor_error_t +ecbor_get_bool (ecbor_item_t *item, uint8_t *value); /* * Inline API */ #define ECBOR_GET_TYPE(i) \ - ((i).type) + ((i)->type) +#define ECBOR_GET_LENGTH(i) \ + ((i)->type == ECBOR_TYPE_MAP ? (i)->length / 2 : (i)->length) + +#define ECBOR_GET_INT(i) \ + ((i)->value.integer) +#define ECBOR_GET_UINT(i) \ + ((i)->value.uinteger) + +#define ECBOR_GET_STRING(i) \ + ((i)->value.string) + +#define ECBOR_GET_FP32(i) \ + ((i)->value.fp32) +#define ECBOR_GET_FP64(i) \ + ((i)->value.fp64) + +#define ECBOR_GET_BOOL(i) \ + ((i)->value.uinteger) + +#define ECBOR_GET_TAG_VALUE(i) \ + ((i)->value.tag.tag_value) +#define ECBOR_GET_TAG_ITEM(i) \ + ((i)->child) #define ECBOR_IS_INDEFINITE(i) \ - ((i).is_indefinite) + ((i)->is_indefinite) #define ECBOR_IS_DEFINITE(i) \ - (!(i).is_indefinite) - + (!(i)->is_indefinite) #define ECBOR_IS_NINT(i) \ - ((i).type == ECBOR_TYPE_NINT) + ((i)->type == ECBOR_TYPE_NINT) #define ECBOR_IS_UINT(i) \ - ((i).type == ECBOR_TYPE_UINT) + ((i)->type == ECBOR_TYPE_UINT) #define ECBOR_IS_INTEGER(i) \ (ECBOR_IS_NINT(i) || ECBOR_IS_UINT(i)) #define ECBOR_IS_BSTR(i) \ - ((i).type == ECBOR_TYPE_BSTR) + ((i)->type == ECBOR_TYPE_BSTR) #define ECBOR_IS_STR(i) \ - ((i).type == ECBOR_TYPE_STR) + ((i)->type == ECBOR_TYPE_STR) #define ECBOR_IS_ARRAY(i) \ - ((i).type == ECBOR_TYPE_ARRAY) + ((i)->type == ECBOR_TYPE_ARRAY) #define ECBOR_IS_MAP(i) \ - ((i).type == ECBOR_TYPE_MAP) + ((i)->type == ECBOR_TYPE_MAP) #define ECBOR_IS_TAG(i) \ - ((i).type == ECBOR_TYPE_TAG) + ((i)->type == ECBOR_TYPE_TAG) #define ECBOR_IS_FP32(i) \ - ((i).type == ECBOR_TYPE_FP32) + ((i)->type == ECBOR_TYPE_FP32) #define ECBOR_IS_FLOAT(i) \ ECBOR_IS_FP32(i) #define ECBOR_IS_FP64(i) \ - ((i).type == ECBOR_TYPE_FP64) + ((i)->type == ECBOR_TYPE_FP64) #define ECBOR_IS_DOUBLE(i) \ ECBOR_IS_FP64(i) - -#define ECBOR_GET_INT(i) \ - ((i).value.integer) -#define ECBOR_GET_UINT(i) \ - ((i).value.uinteger) -#define ECBOR_GET_BSTR(i) \ - ((i).value.string) -#define ECBOR_GET_STR(i) \ - ((i).value.string) -#define ECBOR_GET_TAG(i) \ - ((i).value.tag.tag_value) +#define ECBOR_IS_BOOL(i) \ + ((i)->type == ECBOR_TYPE_BOOL) +#define ECBOR_IS_NULL(i) \ + ((i)->type == ECBOR_TYPE_NULL) +#define ECBOR_IS_UNDEFINED(i) \ + ((i)->type == ECBOR_TYPE_UNDEFINED) #endif \ No newline at end of file -- cgit v1.2.3