summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrimio <vasi.vilvoiu@gmail.com>2018-03-02 01:40:43 +0200
committerrimio <vasi.vilvoiu@gmail.com>2018-03-02 01:40:43 +0200
commitf2397db2cab21c9db06e8f7b69981f7eb2ca8cd5 (patch)
tree897682067030314d41db3491c013117739e04bb9
parent85f4b2274c7ed2107dd56329c3421c15272e67a5 (diff)
Added indefinite string API; added test case answers
-rw-r--r--include/ecbor.h23
-rw-r--r--src/ecbor.c133
-rw-r--r--src/ecbor_describe.c96
-rw-r--r--test/files/appendix_a/0071.answer3
-rw-r--r--test/files/appendix_a/0072.answer3
-rw-r--r--test/files/appendix_a/0073.answer1
-rw-r--r--test/files/appendix_a/0074.answer8
-rw-r--r--test/files/appendix_a/0075.answer8
-rw-r--r--test/files/appendix_a/0076.answer8
-rw-r--r--test/files/appendix_a/0077.answer8
-rw-r--r--test/files/appendix_a/0078.answer26
-rw-r--r--test/files/appendix_a/0079.answer7
-rw-r--r--test/files/appendix_a/0080.answer5
-rw-r--r--test/files/appendix_a/0081.answer5
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