summaryrefslogtreecommitdiff
path: root/src/ecbor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ecbor.c')
-rw-r--r--src/ecbor.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/src/ecbor.c b/src/ecbor.c
index 11984a6..882f729 100644
--- a/src/ecbor.c
+++ b/src/ecbor.c
@@ -6,3 +6,221 @@
*/
#include "ecbor.h"
+
+extern ecbor_major_type_t
+ecbor_get_type (ecbor_item_t *item)
+{
+ if (!item) {
+ return ECBOR_MT_UNDEFINED;
+ }
+ if (item->major_type < ECBOR_MT_UINT
+ || item->major_type > ECBOR_MT_SPECIAL) {
+ return ECBOR_MT_UNDEFINED;
+ }
+ return item->major_type;
+}
+
+extern ecbor_error_t
+ecbor_get_value (ecbor_item_t *item, void *value)
+{
+ if (!item) {
+ return ECBOR_ERR_NULL_ITEM;
+ }
+ if (!value) {
+ return ECBOR_ERR_NULL_VALUE;
+ }
+
+ switch (item->major_type) {
+ case ECBOR_MT_NINT:
+ *((int64_t *)value) = item->value.integer;
+ break;
+
+ case ECBOR_MT_UINT:
+ *((uint64_t *)value) = item->value.uinteger;
+ break;
+
+ case ECBOR_MT_BSTR:
+ case ECBOR_MT_STR:
+ *((uint8_t **)value) = (uint8_t *) item->value.string;
+ break;
+
+ case ECBOR_MT_TAG:
+ *((uint64_t *)value) = item->value.tag.tag_value;
+ break;
+
+ default:
+ return ECBOR_ERR_INVALID_TYPE;
+ }
+
+ return ECBOR_OK;
+}
+
+extern ecbor_error_t
+ecbor_get_length (ecbor_item_t *item, uint64_t *length)
+{
+ if (!item) {
+ return ECBOR_ERR_NULL_ITEM;
+ }
+ if (!length) {
+ return ECBOR_ERR_NULL_VALUE;
+ }
+
+ switch (item->major_type) {
+ case ECBOR_MT_BSTR:
+ case ECBOR_MT_STR:
+ *length = item->size;
+ break;
+
+ case ECBOR_MT_ARRAY:
+ *length = item->n_chunks;
+ break;
+
+ case ECBOR_MT_MAP:
+ *length = item->n_chunks / 2;
+ break;
+
+ default:
+ return ECBOR_ERR_INVALID_TYPE;
+ }
+
+ return ECBOR_OK;
+}
+
+extern ecbor_error_t
+ecbor_get_array_item (ecbor_item_t *array, uint64_t index,
+ ecbor_item_t *item)
+{
+ ecbor_decode_context_t context;
+ ecbor_error_t rc;
+ uint64_t i;
+
+ if (!array) {
+ return ECBOR_ERR_NULL_ARRAY;
+ }
+ if (array->major_type != ECBOR_MT_ARRAY) {
+ return ECBOR_ERR_INVALID_TYPE;
+ }
+ if (array->n_chunks <= index) {
+ return ECBOR_ERR_INDEX_OUT_OF_BOUNDS;
+ }
+ if (!item) {
+ return ECBOR_ERR_NULL_ITEM;
+ }
+
+ rc = ecbor_initialize_decode (&context, array->value.items, array->size);
+ if (rc != ECBOR_OK) {
+ return rc;
+ }
+
+ for (i = 0; i < index; i ++) {
+ rc = ecbor_decode (&context, item);
+ if (rc != ECBOR_OK) {
+ if (rc == ECBOR_END_OF_BUFFER) {
+ return ECBOR_ERR_INVALID_END_OF_BUFFER;
+ } else {
+ return rc;
+ }
+ }
+ }
+
+ return ECBOR_OK;
+}
+
+extern ecbor_error_t
+ecbor_get_map_item (ecbor_item_t *map, uint64_t index, ecbor_item_t *key,
+ ecbor_item_t *value)
+{
+ ecbor_decode_context_t context;
+ ecbor_error_t rc;
+ uint64_t i;
+
+ if (!map) {
+ return ECBOR_ERR_NULL_MAP;
+ }
+ if (map->major_type != ECBOR_MT_ARRAY) {
+ return ECBOR_ERR_INVALID_TYPE;
+ }
+ if (map->n_chunks <= (index * 2)) {
+ return ECBOR_ERR_INDEX_OUT_OF_BOUNDS;
+ }
+ if (!key || !value) {
+ return ECBOR_ERR_NULL_ITEM;
+ }
+
+ rc = ecbor_initialize_decode (&context, map->value.items, map->size);
+ if (rc != ECBOR_OK) {
+ return rc;
+ }
+
+ for (i = 0; i < index; i ++) {
+ rc = ecbor_decode (&context, key);
+ if (rc != ECBOR_OK) {
+ if (rc == ECBOR_END_OF_BUFFER) {
+ return ECBOR_ERR_INVALID_END_OF_BUFFER;
+ } else {
+ return rc;
+ }
+ }
+
+ rc = ecbor_decode (&context, value);
+ if (rc != ECBOR_OK) {
+ if (rc == ECBOR_END_OF_BUFFER) {
+ return ECBOR_ERR_INVALID_END_OF_BUFFER;
+ } else {
+ return rc;
+ }
+ }
+ }
+
+ return ECBOR_OK;
+}
+
+extern ecbor_error_t
+ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *item)
+{
+ ecbor_decode_context_t context;
+ ecbor_error_t rc;
+
+ if (!tag) {
+ return ECBOR_ERR_NULL_ITEM;
+ }
+ if (tag->major_type != ECBOR_MT_ARRAY) {
+ return ECBOR_ERR_INVALID_TYPE;
+ }
+ if (!item) {
+ return ECBOR_ERR_NULL_VALUE;
+ }
+
+ rc = ecbor_initialize_decode (&context, tag->value.items, tag->size);
+ if (rc != ECBOR_OK) {
+ return rc;
+ }
+
+ rc = ecbor_decode (&context, item);
+ if (rc != ECBOR_OK) {
+ if (rc == ECBOR_END_OF_BUFFER) {
+ return ECBOR_ERR_INVALID_END_OF_BUFFER;
+ } else {
+ return rc;
+ }
+ }
+
+ return ECBOR_OK;
+}
+
+extern ecbor_error_t
+ecbor_get_root (ecbor_decode_context_t *context, ecbor_node_t **root)
+{
+ if (!context) {
+ return ECBOR_ERR_NULL_CONTEXT;
+ }
+ if (!root) {
+ return ECBOR_ERR_NULL_NODE;
+ }
+ if (context->n_nodes <= 0) {
+ return ECBOR_ERR_EMPTY_NODE_BUFFER;
+ }
+
+ *root = &context->nodes[0];
+ return ECBOR_OK;
+} \ No newline at end of file