diff options
| author | rimio <vasi.vilvoiu@gmail.com> | 2018-03-02 01:40:43 +0200 |
|---|---|---|
| committer | rimio <vasi.vilvoiu@gmail.com> | 2018-03-02 01:40:43 +0200 |
| commit | f2397db2cab21c9db06e8f7b69981f7eb2ca8cd5 (patch) | |
| tree | 897682067030314d41db3491c013117739e04bb9 | |
| parent | 85f4b2274c7ed2107dd56329c3421c15272e67a5 (diff) | |
Added indefinite string API; added test case answers
| -rw-r--r-- | include/ecbor.h | 23 | ||||
| -rw-r--r-- | src/ecbor.c | 133 | ||||
| -rw-r--r-- | src/ecbor_describe.c | 96 | ||||
| -rw-r--r-- | test/files/appendix_a/0071.answer | 3 | ||||
| -rw-r--r-- | test/files/appendix_a/0072.answer | 3 | ||||
| -rw-r--r-- | test/files/appendix_a/0073.answer | 1 | ||||
| -rw-r--r-- | test/files/appendix_a/0074.answer | 8 | ||||
| -rw-r--r-- | test/files/appendix_a/0075.answer | 8 | ||||
| -rw-r--r-- | test/files/appendix_a/0076.answer | 8 | ||||
| -rw-r--r-- | test/files/appendix_a/0077.answer | 8 | ||||
| -rw-r--r-- | test/files/appendix_a/0078.answer | 26 | ||||
| -rw-r--r-- | test/files/appendix_a/0079.answer | 7 | ||||
| -rw-r--r-- | test/files/appendix_a/0080.answer | 5 | ||||
| -rw-r--r-- | test/files/appendix_a/0081.answer | 5 |
14 files changed, 309 insertions, 25 deletions
diff --git a/include/ecbor.h b/include/ecbor.h index c8a43f7..a0c166c 100644 --- a/include/ecbor.h +++ b/include/ecbor.h @@ -38,6 +38,7 @@ typedef enum { ECBOR_ERR_EMPTY_NODE_BUFFER = 52, ECBOR_ERR_INDEX_OUT_OF_BOUNDS = 53, ECBOR_ERR_WONT_RETURN_INDEFINITE = 54, + ECBOR_ERR_WONT_RETURN_DEFINITE = 55, /* semantic errors */ ECBOR_ERR_CURRENTLY_NOT_SUPPORTED = 100, @@ -251,6 +252,26 @@ extern ecbor_error_t ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *arr_item); +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); + +extern ecbor_error_t +ecbor_get_str_chunk (ecbor_item_t *str, uint64_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); + +extern ecbor_error_t +ecbor_get_bstr_chunk (ecbor_item_t *str, uint64_t index, ecbor_item_t *chunk); + + /* * Inline API */ @@ -259,6 +280,8 @@ ecbor_get_tag_item (ecbor_item_t *tag, ecbor_item_t *arr_item); #define ECBOR_IS_INDEFINITE(i) \ ((i).is_indefinite) +#define ECBOR_IS_DEFINITE(i) \ + (!(i).is_indefinite) #define ECBOR_IS_NINT(i) \ ((i).type == ECBOR_TYPE_NINT) 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; diff --git a/test/files/appendix_a/0071.answer b/test/files/appendix_a/0071.answer new file mode 100644 index 0000000..345f355 --- /dev/null +++ b/test/files/appendix_a/0071.answer @@ -0,0 +1,3 @@ +[BSTR] len 5 (indefinite) + [BSTR] len 2 value '0102' + [BSTR] len 3 value '030405' diff --git a/test/files/appendix_a/0072.answer b/test/files/appendix_a/0072.answer new file mode 100644 index 0000000..e146cd8 --- /dev/null +++ b/test/files/appendix_a/0072.answer @@ -0,0 +1,3 @@ +[STR] len 9 (indefinite) + [STR] len 5 value 'strea' + [STR] len 4 value 'ming' diff --git a/test/files/appendix_a/0073.answer b/test/files/appendix_a/0073.answer new file mode 100644 index 0000000..972fb75 --- /dev/null +++ b/test/files/appendix_a/0073.answer @@ -0,0 +1 @@ +[ARRAY] len 0 (indefinite) diff --git a/test/files/appendix_a/0074.answer b/test/files/appendix_a/0074.answer new file mode 100644 index 0000000..8c993e6 --- /dev/null +++ b/test/files/appendix_a/0074.answer @@ -0,0 +1,8 @@ +[ARRAY] len 3 (indefinite) + [UINT] value 1 + [ARRAY] len 2 + [UINT] value 2 + [UINT] value 3 + [ARRAY] len 2 (indefinite) + [UINT] value 4 + [UINT] value 5 diff --git a/test/files/appendix_a/0075.answer b/test/files/appendix_a/0075.answer new file mode 100644 index 0000000..376b219 --- /dev/null +++ b/test/files/appendix_a/0075.answer @@ -0,0 +1,8 @@ +[ARRAY] len 3 (indefinite) + [UINT] value 1 + [ARRAY] len 2 + [UINT] value 2 + [UINT] value 3 + [ARRAY] len 2 + [UINT] value 4 + [UINT] value 5 diff --git a/test/files/appendix_a/0076.answer b/test/files/appendix_a/0076.answer new file mode 100644 index 0000000..f229e54 --- /dev/null +++ b/test/files/appendix_a/0076.answer @@ -0,0 +1,8 @@ +[ARRAY] len 3 + [UINT] value 1 + [ARRAY] len 2 + [UINT] value 2 + [UINT] value 3 + [ARRAY] len 2 (indefinite) + [UINT] value 4 + [UINT] value 5 diff --git a/test/files/appendix_a/0077.answer b/test/files/appendix_a/0077.answer new file mode 100644 index 0000000..31566a4 --- /dev/null +++ b/test/files/appendix_a/0077.answer @@ -0,0 +1,8 @@ +[ARRAY] len 3 + [UINT] value 1 + [ARRAY] len 2 (indefinite) + [UINT] value 2 + [UINT] value 3 + [ARRAY] len 2 + [UINT] value 4 + [UINT] value 5 diff --git a/test/files/appendix_a/0078.answer b/test/files/appendix_a/0078.answer new file mode 100644 index 0000000..f1126ad --- /dev/null +++ b/test/files/appendix_a/0078.answer @@ -0,0 +1,26 @@ +[ARRAY] len 25 (indefinite) + [UINT] value 1 + [UINT] value 2 + [UINT] value 3 + [UINT] value 4 + [UINT] value 5 + [UINT] value 6 + [UINT] value 7 + [UINT] value 8 + [UINT] value 9 + [UINT] value 10 + [UINT] value 11 + [UINT] value 12 + [UINT] value 13 + [UINT] value 14 + [UINT] value 15 + [UINT] value 16 + [UINT] value 17 + [UINT] value 18 + [UINT] value 19 + [UINT] value 20 + [UINT] value 21 + [UINT] value 22 + [UINT] value 23 + [UINT] value 24 + [UINT] value 25 diff --git a/test/files/appendix_a/0079.answer b/test/files/appendix_a/0079.answer new file mode 100644 index 0000000..8bd634e --- /dev/null +++ b/test/files/appendix_a/0079.answer @@ -0,0 +1,7 @@ +[MAP] len 2 (indefinite) + key[0]: [STR] len 1 value 'a' + val[0]: [UINT] value 1 + key[1]: [STR] len 1 value 'b' + val[1]: [ARRAY] len 2 (indefinite) + [UINT] value 2 + [UINT] value 3 diff --git a/test/files/appendix_a/0080.answer b/test/files/appendix_a/0080.answer new file mode 100644 index 0000000..91f4607 --- /dev/null +++ b/test/files/appendix_a/0080.answer @@ -0,0 +1,5 @@ +[ARRAY] len 2 + [STR] len 1 value 'a' + [MAP] len 1 (indefinite) + key[0]: [STR] len 1 value 'b' + val[0]: [STR] len 1 value 'c' diff --git a/test/files/appendix_a/0081.answer b/test/files/appendix_a/0081.answer new file mode 100644 index 0000000..ca819ca --- /dev/null +++ b/test/files/appendix_a/0081.answer @@ -0,0 +1,5 @@ +[MAP] len 2 (indefinite) + key[0]: [STR] len 3 value 'Fun' + val[0]: [BOOL] value true + key[1]: [STR] len 3 value 'Amt' + val[1]: [NINT] value -2 |
