From f2397db2cab21c9db06e8f7b69981f7eb2ca8cd5 Mon Sep 17 00:00:00 2001 From: rimio Date: Fri, 2 Mar 2018 01:40:43 +0200 Subject: Added indefinite string API; added test case answers --- src/ecbor.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/ecbor_describe.c | 96 +++++++++++++++++++++++++++---------- 2 files changed, 204 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/ecbor.c b/src/ecbor.c index 96cc4cc..1e95830 100644 --- a/src/ecbor.c +++ b/src/ecbor.c @@ -300,7 +300,138 @@ ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *item) return ECBOR_OK; } -extern ecbor_error_t +static inline ecbor_error_t +ecbor_get_string_internal (ecbor_item_t *str, uint8_t **value, ecbor_type_t type) +{ + if (!str) { + return ECBOR_ERR_NULL_ITEM; + } + if (!value) { + return ECBOR_ERR_NULL_VALUE; + } + if (str->type != type) { + return ECBOR_ERR_INVALID_TYPE; + } + if (str->is_indefinite) { + return ECBOR_ERR_WONT_RETURN_INDEFINITE; + } + + (*value) = (uint8_t *) str->value.string.str; + + return ECBOR_OK; +} + +static inline ecbor_error_t +ecbor_get_string_chunk_count_internal (ecbor_item_t *str, uint64_t *count, + ecbor_type_t type) +{ + if (!str) { + return ECBOR_ERR_NULL_ITEM; + } + if (!count) { + return ECBOR_ERR_NULL_VALUE; + } + if (str->type != type) { + return ECBOR_ERR_INVALID_TYPE; + } + if (!str->is_indefinite) { + return ECBOR_ERR_WONT_RETURN_DEFINITE; + } + + (*count) = str->value.string.n_chunks; + + return ECBOR_OK; +} + +static inline ecbor_error_t +ecbor_get_string_chunk_internal (ecbor_item_t *str, uint64_t index, + ecbor_item_t *chunk, ecbor_type_t type) +{ + ecbor_decode_context_t context; + ecbor_error_t rc; + uint64_t i; + + if (!str) { + return ECBOR_ERR_NULL_ITEM; + } + if (!chunk) { + return ECBOR_ERR_NULL_VALUE; + } + if (str->type != type) { + return ECBOR_ERR_INVALID_TYPE; + } + if (!str->is_indefinite) { + return ECBOR_ERR_WONT_RETURN_DEFINITE; + } + if (index >= str->value.string.n_chunks) { + return ECBOR_ERR_INDEX_OUT_OF_BOUNDS; + } + + /* locate chunk */ + rc = ecbor_initialize_decode (&context, str->value.string.str, str->size); + if (rc != ECBOR_OK) { + return rc; + } + + for (i = 0; i <= index; i ++) { + rc = ecbor_decode (&context, chunk); + if (rc != ECBOR_OK) { + if (rc == ECBOR_END_OF_BUFFER) { + return ECBOR_ERR_INVALID_END_OF_BUFFER; + } else { + return rc; + } + } + } + + /* check chunk */ + if (chunk->type != type) { + return ECBOR_ERR_INVALID_CHUNK_MAJOR_TYPE; + } + if (chunk->is_indefinite) { + return ECBOR_ERR_NESTET_INDEFINITE_STRING; + } + + return ECBOR_OK; +} + +ecbor_error_t +ecbor_get_str (ecbor_item_t *str, char **value) +{ + return ecbor_get_string_internal (str, (uint8_t **)value, ECBOR_TYPE_STR); +} + +ecbor_error_t +ecbor_get_str_chunk_count (ecbor_item_t *str, uint64_t *count) +{ + return ecbor_get_string_chunk_count_internal (str, count, ECBOR_TYPE_STR); +} + +ecbor_error_t +ecbor_get_str_chunk (ecbor_item_t *str, uint64_t index, ecbor_item_t *chunk) +{ + return ecbor_get_string_chunk_internal (str, index, chunk, ECBOR_TYPE_STR); +} + +ecbor_error_t +ecbor_get_bstr (ecbor_item_t *str, uint8_t **value) +{ + return ecbor_get_string_internal (str, value, ECBOR_TYPE_BSTR); +} + +ecbor_error_t +ecbor_get_bstr_chunk_count (ecbor_item_t *str, uint64_t *count) +{ + return ecbor_get_string_chunk_count_internal (str, count, ECBOR_TYPE_BSTR); +} + +ecbor_error_t +ecbor_get_bstr_chunk (ecbor_item_t *str, uint64_t index, ecbor_item_t *chunk) +{ + return ecbor_get_string_chunk_internal (str, index, chunk, ECBOR_TYPE_BSTR); +} + +ecbor_error_t ecbor_get_root (ecbor_decode_context_t *context, ecbor_node_t **root) { if (!context) { diff --git a/src/ecbor_describe.c b/src/ecbor_describe.c index 2ae9ccf..fc72331 100644 --- a/src/ecbor_describe.c +++ b/src/ecbor_describe.c @@ -87,50 +87,98 @@ print_ecbor_item (ecbor_item_t *item, unsigned int level, char *prefix) case ECBOR_TYPE_STR: { uint64_t len; - char *val; rc = ecbor_get_length (item, &len); if (rc != ECBOR_OK) { return rc; } - - rc = ecbor_get_value (item, (char *) &val); - if (rc != ECBOR_OK) { - return rc; - } - printf ("[STR] len %u %s value '%.*s'\n", (unsigned int) len, - (ECBOR_IS_INDEFINITE (*item) ? "(indefinite)" : ""), - (int)(len <= max_str_print_len ? len : strlen(msg_too_large)), - (len <= max_str_print_len ? val : msg_too_large)); + if (ECBOR_IS_INDEFINITE (*item)) { + uint64_t nchunks; + + rc = ecbor_get_str_chunk_count (item, &nchunks); + if (rc != ECBOR_OK) { + return rc; + } + + printf ("[STR] len %u (indefinite)\n", (unsigned int) len); + for (i = 0; i < nchunks; i ++) { + ecbor_item_t chunk; + + rc = ecbor_get_str_chunk (item, i, &chunk); + if (rc != ECBOR_OK) { + return rc; + } + + rc = print_ecbor_item (&chunk, level + 1, ""); + if (rc != ECBOR_OK) { + return rc; + } + } + } else { + char *val; + + rc = ecbor_get_str (item, &val); + if (rc != ECBOR_OK) { + return rc; + } + + printf ("[STR] len %u value '%.*s'\n", (unsigned int) len, + (int)(len <= max_str_print_len ? len : strlen(msg_too_large)), + (len <= max_str_print_len ? val : msg_too_large)); + } } break; case ECBOR_TYPE_BSTR: { uint64_t len; - char *val; rc = ecbor_get_length (item, &len); if (rc != ECBOR_OK) { return rc; } - - rc = ecbor_get_value (item, (char *) &val); - if (rc != ECBOR_OK) { - return rc; - } - printf ("[BSTR] len %u %s value ", (unsigned int) len, - (ECBOR_IS_INDEFINITE (*item) ? "(indefinite)" : "")); - if (len > max_str_print_len) { - printf ("'%s'\n", msg_too_large); + if (ECBOR_IS_INDEFINITE (*item)) { + uint64_t nchunks; + + rc = ecbor_get_bstr_chunk_count (item, &nchunks); + if (rc != ECBOR_OK) { + return rc; + } + + printf ("[BSTR] len %u (indefinite)\n", (unsigned int) len); + for (i = 0; i < nchunks; i ++) { + ecbor_item_t chunk; + + rc = ecbor_get_bstr_chunk (item, i, &chunk); + if (rc != ECBOR_OK) { + return rc; + } + + rc = print_ecbor_item (&chunk, level + 1, ""); + if (rc != ECBOR_OK) { + return rc; + } + } } else { - printf ("'"); - for (i = 0; i < len; i ++) { - printf("%02x", val[i]); + uint8_t *val; + + rc = ecbor_get_bstr (item, &val); + if (rc != ECBOR_OK) { + return rc; + } + + printf ("[BSTR] len %u value ", (unsigned int) len); + if (len > max_str_print_len) { + printf ("'%s'\n", msg_too_large); + } else { + printf ("'"); + for (i = 0; i < len; i ++) { + printf("%02x", val[i]); + } + printf ("'\n"); } - printf ("'\n"); } } break; -- cgit v1.2.3