Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop a9d943b70 -> 6d5df7301


cborattr; support arrays of objects, values as objects, and
unnamed attributes.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/6d5df730
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/6d5df730
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/6d5df730

Branch: refs/heads/develop
Commit: 6d5df73017c2832538df654492300fd94d7d9520
Parents: a9d943b
Author: Marko Kiiskila <[email protected]>
Authored: Tue Jan 3 16:48:01 2017 -0800
Committer: Marko Kiiskila <[email protected]>
Committed: Tue Jan 3 16:48:01 2017 -0800

----------------------------------------------------------------------
 encoding/cborattr/include/cborattr/cborattr.h   |  24 +++
 encoding/cborattr/src/cborattr.c                |  58 ++++--
 encoding/cborattr/test/src/test_cborattr.c      |   3 +
 encoding/cborattr/test/src/test_cborattr.h      |   3 +
 .../test/src/testcases/cborattr_decode_object.c | 198 +++++++++++++++++++
 .../testcases/cborattr_decode_object_array.c    | 126 ++++++++++++
 .../testcases/cborattr_decode_unnamed_array.c   |  99 ++++++++++
 7 files changed, 493 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/include/cborattr/cborattr.h
----------------------------------------------------------------------
diff --git a/encoding/cborattr/include/cborattr/cborattr.h 
b/encoding/cborattr/include/cborattr/cborattr.h
index ed92d35..a1cfe79 100644
--- a/encoding/cborattr/include/cborattr/cborattr.h
+++ b/encoding/cborattr/include/cborattr/cborattr.h
@@ -51,6 +51,7 @@ typedef enum CborAttrType {
     CborAttrDoubleType,
     CborAttrArrayType,
     CborAttrObjectType,
+    CborAttrStructObjectType,
     CborAttrNullType,
 } CborAttrType;
 
@@ -107,6 +108,7 @@ struct cbor_attr_t {
         } bytestring;
         struct cbor_array_t array;
         size_t offset;
+        struct cbor_attr_t *obj;
     } addr;
     union {
         long long int integer;
@@ -119,6 +121,28 @@ struct cbor_attr_t {
     bool nodefault;
 };
 
+/*
+ * Use the following macros to declare template initializers for
+ * CborAttrStructObjectType arrays. Writing the equivalents out by hand is
+ * error-prone.
+ *
+ * CBOR_STRUCT_OBJECT takes a structure name s, and a fieldname f in s.
+ *
+ * CBOR_STRUCT_ARRAY takes the name of a structure array, a pointer to a an
+ * initializer defining the subobject type, and the address of an integer to
+ * store the length in.
+ */
+#define CBORATTR_STRUCT_OBJECT(s, f)        .addr.offset = offsetof(s, f)
+#define CBORATTR_STRUCT_ARRAY(a, e, n)                                  \
+    .addr.array.element_type = CborAttrStructObjectType,                \
+    .addr.array.arr.objects.subtype = e,                                \
+    .addr.array.arr.objects.base = (char*)a,                            \
+    .addr.array.arr.objects.stride = sizeof(a[0]),                      \
+    .addr.array.count = n,                                              \
+    .addr.array.maxlen = (int)(sizeof(a)/sizeof(a[0]))
+
+#define CBORATTR_ATTR_UNNAMED (char *)(-1)
+
 int cbor_read_object(struct CborValue *, const struct cbor_attr_t *);
 int cbor_read_array(struct CborValue *, const struct cbor_array_t *);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/src/cborattr.c
----------------------------------------------------------------------
diff --git a/encoding/cborattr/src/cborattr.c b/encoding/cborattr/src/cborattr.c
index 19b0584..6329753 100644
--- a/encoding/cborattr/src/cborattr.c
+++ b/encoding/cborattr/src/cborattr.c
@@ -65,6 +65,11 @@ valid_attr_type(CborType ct, CborAttrType at)
             return 1;
         }
         break;
+    case CborAttrObjectType:
+        if (ct == CborMapType) {
+            return 1;
+        }
+        break;
     case CborAttrNullType:
         if (ct == CborNullType) {
             return 1;
@@ -84,7 +89,7 @@ cbor_target_address(const struct cbor_attr_t *cursor,
 {
     char *targetaddr = NULL;
 
-    if (parent == NULL || parent->element_type != CborAttrObjectType) {
+    if (parent == NULL || parent->element_type != CborAttrStructObjectType) {
         /* ordinary case - use the address in the cursor structure */
         switch (cursor->type) {
         case CborAttrNullType:
@@ -132,7 +137,7 @@ cbor_internal_read_object(CborValue *root_value,
                           const struct cbor_array_t *parent,
                           int offset)
 {
-    const struct cbor_attr_t *cursor;
+    const struct cbor_attr_t *cursor, *best_match;
     char attrbuf[CBOR_ATTR_MAX + 1];
     void *lptr;
     CborValue cur_value;
@@ -190,29 +195,36 @@ cbor_internal_read_object(CborValue *root_value,
                 err |= cbor_value_copy_text_string(&cur_value, attrbuf, &len,
                                                      NULL);
             }
-        } else {
-            err |= CborErrorIllegalType;
-            goto err_return;
-        }
 
-        /* at least get the type of the next value so we can match the
-         * attribute name and type for a perfect match */
-        err |= cbor_value_advance(&cur_value);
-        if (cbor_value_is_valid(&cur_value)) {
-            type = cbor_value_get_type(&cur_value);
+            /* at least get the type of the next value so we can match the
+             * attribute name and type for a perfect match */
+            err |= cbor_value_advance(&cur_value);
+            if (cbor_value_is_valid(&cur_value)) {
+                type = cbor_value_get_type(&cur_value);
+            } else {
+                err |= CborErrorIllegalType;
+                goto err_return;
+            }
         } else {
-            err |= CborErrorIllegalType;
-            goto err_return;
+            attrbuf[0] = '\0';
+            type = cbor_value_get_type(&cur_value);
         }
 
         /* find this attribute in our list */
+        best_match = NULL;
         for (cursor = attrs; cursor->attribute != NULL; cursor++) {
-            if (valid_attr_type(type, cursor->type) &&
-                (memcmp(cursor->attribute, attrbuf, len) == 0)) {
-                break;
+            if (valid_attr_type(type, cursor->type)) {
+                if (cursor->attribute == CBORATTR_ATTR_UNNAMED &&
+                    attrbuf[0] == '\0') {
+                    best_match = cursor;
+                } else if (!memcmp(cursor->attribute, attrbuf, len)) {
+                    break;
+                }
             }
         }
-
+        if (!cursor->attribute && best_match) {
+            cursor = best_match;
+        }
         /* we found a match */
         if (cursor->attribute != NULL) {
             lptr = cbor_target_address(cursor, parent, offset);
@@ -253,6 +265,10 @@ cbor_internal_read_object(CborValue *root_value,
             case CborAttrArrayType:
                 err |= cbor_read_array(&cur_value, &cursor->addr.array);
                 continue;
+            case CborAttrObjectType:
+                err |= cbor_internal_read_object(&cur_value, cursor->addr.obj,
+                                                 NULL, 0);
+                continue;
             default:
                 err |= CborErrorIllegalType;
             }
@@ -308,12 +324,18 @@ cbor_read_array(struct CborValue *value, const struct 
cbor_array_t *arr)
             arr->arr.strings.ptrs[off] = tp;
             tp += len + 1;
             break;
+        case CborAttrStructObjectType:
+            err |= cbor_internal_read_object(&elem, arr->arr.objects.subtype,
+                                             arr, off);
+            break;
         default:
             err |= CborErrorIllegalType;
             break;
         }
         arrcount++;
-        err |= cbor_value_advance(&elem);
+        if (arr->element_type != CborAttrStructObjectType) {
+            err |= cbor_value_advance(&elem);
+        }
         if (!cbor_value_is_valid(&elem)) {
             break;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/test/src/test_cborattr.c
----------------------------------------------------------------------
diff --git a/encoding/cborattr/test/src/test_cborattr.c 
b/encoding/cborattr/test/src/test_cborattr.c
index bdcce20..8125660 100644
--- a/encoding/cborattr/test/src/test_cborattr.c
+++ b/encoding/cborattr/test/src/test_cborattr.c
@@ -26,9 +26,12 @@ TEST_SUITE(test_cborattr_suite)
     test_cborattr_decode1();
     test_cborattr_decode_partial();
     test_cborattr_decode_simple();
+    test_cborattr_decode_object();
     test_cborattr_decode_int_array();
     test_cborattr_decode_bool_array();
     test_cborattr_decode_string_array();
+    test_cborattr_decode_object_array();
+    test_cborattr_decode_unnamed_array();
 }
 
 #if MYNEWT_VAL(SELFTEST)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/test/src/test_cborattr.h
----------------------------------------------------------------------
diff --git a/encoding/cborattr/test/src/test_cborattr.h 
b/encoding/cborattr/test/src/test_cborattr.h
index 68823b4..1a5757b 100644
--- a/encoding/cborattr/test/src/test_cborattr.h
+++ b/encoding/cborattr/test/src/test_cborattr.h
@@ -41,9 +41,12 @@ const uint8_t *test_str1(int *len);
 TEST_CASE_DECL(test_cborattr_decode1);
 TEST_CASE_DECL(test_cborattr_decode_partial);
 TEST_CASE_DECL(test_cborattr_decode_simple);
+TEST_CASE_DECL(test_cborattr_decode_object);
 TEST_CASE_DECL(test_cborattr_decode_int_array);
 TEST_CASE_DECL(test_cborattr_decode_bool_array);
 TEST_CASE_DECL(test_cborattr_decode_string_array);
+TEST_CASE_DECL(test_cborattr_decode_object_array);
+TEST_CASE_DECL(test_cborattr_decode_unnamed_array);
 
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/test/src/testcases/cborattr_decode_object.c
----------------------------------------------------------------------
diff --git a/encoding/cborattr/test/src/testcases/cborattr_decode_object.c 
b/encoding/cborattr/test/src/testcases/cborattr_decode_object.c
new file mode 100644
index 0000000..25a32d2
--- /dev/null
+++ b/encoding/cborattr/test/src/testcases/cborattr_decode_object.c
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "test_cborattr.h"
+
+/*
+ * Where we collect cbor data.
+ */
+static uint8_t test_cbor_buf[1024];
+static int test_cbor_len;
+
+/*
+ * CBOR encoder data structures.
+ */
+static int test_cbor_wr(struct cbor_encoder_writer *, const char *, int);
+static CborEncoder test_encoder;
+static struct cbor_encoder_writer test_writer = {
+    .write = test_cbor_wr
+};
+
+static int
+test_cbor_wr(struct cbor_encoder_writer *cew, const char *data, int len)
+{
+    memcpy(test_cbor_buf + test_cbor_len, data, len);
+    test_cbor_len += len;
+
+    assert(test_cbor_len < sizeof(test_cbor_buf));
+    return 0;
+}
+
+static void
+test_encode_data(void)
+{
+    CborEncoder test_data;
+    CborEncoder sub_obj;
+
+    test_cbor_len = 0;
+    cbor_encoder_init(&test_encoder, &test_writer, 0);
+    cbor_encoder_create_map(&test_encoder, &test_data, CborIndefiniteLength);
+
+    /*
+     * p: { bm : 7 }
+     */
+    cbor_encode_text_stringz(&test_data, "p");
+
+    cbor_encoder_create_map(&test_data, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&test_data, "bm");
+    cbor_encode_int(&test_data, 7);
+    cbor_encoder_close_container(&test_data, &sub_obj);
+
+    cbor_encoder_close_container(&test_encoder, &test_data);
+}
+
+static void
+test_encode_data_complex(void)
+{
+    CborEncoder test_data;
+    CborEncoder sub_obj;
+    CborEncoder sub_sub_obj;
+
+    test_cbor_len = 0;
+
+    cbor_encoder_init(&test_encoder, &test_writer, 0);
+    cbor_encoder_create_map(&test_encoder, &test_data, CborIndefiniteLength);
+
+    /*
+     * p: { bm : 7 }, c: { d : { i : 1 } }, a: 3
+     */
+    cbor_encode_text_stringz(&test_data, "p");
+
+    cbor_encoder_create_map(&test_data, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&test_data, "bm");
+    cbor_encode_int(&test_data, 7);
+    cbor_encoder_close_container(&test_data, &sub_obj);
+
+    cbor_encode_text_stringz(&test_data, "c");
+    cbor_encoder_create_map(&test_data, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&sub_obj, "d");
+
+    cbor_encoder_create_map(&sub_obj, &sub_sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&sub_sub_obj, "i");
+    cbor_encode_int(&sub_sub_obj, 1);
+    cbor_encoder_close_container(&sub_obj, &sub_sub_obj);
+    cbor_encoder_close_container(&test_data, &sub_obj);
+
+    cbor_encode_text_stringz(&test_data, "a");
+    cbor_encode_int(&test_data, 3);
+
+    cbor_encoder_close_container(&test_encoder, &test_data);
+}
+
+/*
+ * Simple decoding.
+ */
+TEST_CASE(test_cborattr_decode_object)
+{
+    int rc;
+    int64_t bm_val = 0;
+    struct cbor_attr_t test_sub_attr_bm[] = {
+        [0] = {
+            .attribute = "bm",
+            .type = CborAttrIntegerType,
+            .addr.integer = &bm_val,
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+    struct cbor_attr_t test_attrs[] = {
+        [0] = {
+            .attribute = "p",
+            .type = CborAttrObjectType,
+            .addr.obj = test_sub_attr_bm,
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+    int64_t a_val = 0;
+    int64_t i_val = 0;
+    struct cbor_attr_t test_sub_sub_attr[] = {
+        [0] = {
+            .attribute = "i",
+            .type = CborAttrIntegerType,
+            .addr.integer = &i_val,
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+    struct cbor_attr_t test_sub_attr_d[] = {
+        [0] = {
+            .attribute = "d",
+            .type = CborAttrObjectType,
+            .addr.obj = test_sub_sub_attr,
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+    struct cbor_attr_t test_attr_complex[] = {
+        [0] = {
+            .attribute = "c",
+            .type = CborAttrObjectType,
+            .addr.obj = test_sub_attr_d,
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = "a",
+            .type = CborAttrIntegerType,
+            .addr.integer = &a_val,
+            .nodefault = true
+        },
+        [2] = {
+            .attribute = "p",
+            .type = CborAttrObjectType,
+            .addr.obj = test_sub_attr_bm,
+            .nodefault = true
+        },
+        [3] = {
+            .attribute = NULL
+        }
+    };
+
+    test_encode_data();
+
+    rc = cbor_read_flat_attrs(test_cbor_buf, test_cbor_len, test_attrs);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(bm_val == 7);
+
+    test_encode_data_complex();
+
+    bm_val = 0;
+    i_val = 0;
+    rc = cbor_read_flat_attrs(test_cbor_buf, test_cbor_len, test_attr_complex);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(bm_val == 7);
+    TEST_ASSERT(i_val == 1);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/test/src/testcases/cborattr_decode_object_array.c
----------------------------------------------------------------------
diff --git 
a/encoding/cborattr/test/src/testcases/cborattr_decode_object_array.c 
b/encoding/cborattr/test/src/testcases/cborattr_decode_object_array.c
new file mode 100644
index 0000000..82cc34f
--- /dev/null
+++ b/encoding/cborattr/test/src/testcases/cborattr_decode_object_array.c
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "test_cborattr.h"
+
+/*
+ * Where we collect cbor data.
+ */
+static uint8_t test_cbor_buf[1024];
+static int test_cbor_len;
+
+/*
+ * CBOR encoder data structures.
+ */
+static int test_cbor_wr(struct cbor_encoder_writer *, const char *, int);
+static CborEncoder test_encoder;
+static struct cbor_encoder_writer test_writer = {
+    .write = test_cbor_wr
+};
+
+static int
+test_cbor_wr(struct cbor_encoder_writer *cew, const char *data, int len)
+{
+    memcpy(test_cbor_buf + test_cbor_len, data, len);
+    test_cbor_len += len;
+
+    assert(test_cbor_len < sizeof(test_cbor_buf));
+    return 0;
+}
+
+static void
+test_encode_object_array(void)
+{
+    CborEncoder data;
+    CborEncoder array;
+    CborEncoder sub_obj;
+
+    test_cbor_len = 0;
+    cbor_encoder_init(&test_encoder, &test_writer, 0);
+
+    cbor_encoder_create_map(&test_encoder, &data, CborIndefiniteLength);
+
+    /*
+     * a: [ { h:"str1"}, {h:"2str"}, {h:"str3"}]
+     */
+    cbor_encode_text_stringz(&data, "a");
+
+    cbor_encoder_create_array(&data, &array, CborIndefiniteLength);
+
+    cbor_encoder_create_map(&array, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&sub_obj, "h");
+    cbor_encode_text_stringz(&sub_obj, "str1");
+    cbor_encoder_close_container(&array, &sub_obj);
+
+    cbor_encoder_create_map(&array, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&sub_obj, "h");
+    cbor_encode_text_stringz(&sub_obj, "2str");
+    cbor_encoder_close_container(&array, &sub_obj);
+
+    cbor_encoder_create_map(&array, &sub_obj, CborIndefiniteLength);
+    cbor_encode_text_stringz(&sub_obj, "h");
+    cbor_encode_text_stringz(&sub_obj, "str3");
+    cbor_encoder_close_container(&array, &sub_obj);
+
+    cbor_encoder_close_container(&data, &array);
+
+    cbor_encoder_close_container(&test_encoder, &data);
+}
+
+/*
+ * object array
+ */
+TEST_CASE(test_cborattr_decode_object_array)
+{
+    int rc;
+    struct h_obj {
+        char h_data[32];
+    } arr_objs[5];
+    int arr_cnt = 0;
+    struct cbor_attr_t sub_attr[] = {
+        [0] = {
+            .attribute = "h",
+            .type = CborAttrTextStringType,
+            CBORATTR_STRUCT_OBJECT(struct h_obj, h_data),
+            .len = sizeof(arr_objs[0].h_data)
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+    struct cbor_attr_t test_attrs[] = {
+        [0] = {
+            .attribute = "a",
+            .type = CborAttrArrayType,
+            CBORATTR_STRUCT_ARRAY(arr_objs, sub_attr, &arr_cnt),
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+
+    test_encode_object_array();
+
+    rc = cbor_read_flat_attrs(test_cbor_buf, test_cbor_len, test_attrs);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(arr_cnt == 3);
+    TEST_ASSERT(!strcmp(arr_objs[0].h_data, "str1"));
+    TEST_ASSERT(!strcmp(arr_objs[1].h_data, "2str"));
+    TEST_ASSERT(!strcmp(arr_objs[2].h_data, "str3"));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d5df730/encoding/cborattr/test/src/testcases/cborattr_decode_unnamed_array.c
----------------------------------------------------------------------
diff --git 
a/encoding/cborattr/test/src/testcases/cborattr_decode_unnamed_array.c 
b/encoding/cborattr/test/src/testcases/cborattr_decode_unnamed_array.c
new file mode 100644
index 0000000..c4446b8
--- /dev/null
+++ b/encoding/cborattr/test/src/testcases/cborattr_decode_unnamed_array.c
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "test_cborattr.h"
+
+/*
+ * Where we collect cbor data.
+ */
+static uint8_t test_cbor_buf[1024];
+static int test_cbor_len;
+
+/*
+ * CBOR encoder data structures.
+ */
+static int test_cbor_wr(struct cbor_encoder_writer *, const char *, int);
+static CborEncoder test_encoder;
+static struct cbor_encoder_writer test_writer = {
+    .write = test_cbor_wr
+};
+
+static int
+test_cbor_wr(struct cbor_encoder_writer *cew, const char *data, int len)
+{
+    memcpy(test_cbor_buf + test_cbor_len, data, len);
+    test_cbor_len += len;
+
+    assert(test_cbor_len < sizeof(test_cbor_buf));
+    return 0;
+}
+
+static void
+test_encode_unnamed_array(void)
+{
+    CborEncoder data;
+    CborEncoder array;
+
+    cbor_encoder_init(&test_encoder, &test_writer, 0);
+
+    cbor_encoder_create_map(&test_encoder, &data, CborIndefiniteLength);
+
+    /*
+     * [1,2,33]
+     */
+    cbor_encoder_create_array(&data, &array, CborIndefiniteLength);
+    cbor_encode_int(&array, 1);
+    cbor_encode_int(&array, 2);
+    cbor_encode_int(&array, 33);
+    cbor_encoder_close_container(&data, &array);
+
+    cbor_encoder_close_container(&test_encoder, &data);
+}
+
+/*
+ * integer array
+ */
+TEST_CASE(test_cborattr_decode_unnamed_array)
+{
+    int rc;
+    int64_t arr_data[5];
+    int arr_cnt = 0;
+    struct cbor_attr_t test_attrs[] = {
+        [0] = {
+            .attribute = CBORATTR_ATTR_UNNAMED,
+            .type = CborAttrArrayType,
+            .addr.array.element_type = CborAttrIntegerType,
+            .addr.array.arr.integers.store = arr_data,
+            .addr.array.count = &arr_cnt,
+            .addr.array.maxlen = sizeof(arr_data) / sizeof(arr_data[0]),
+            .nodefault = true
+        },
+        [1] = {
+            .attribute = NULL
+        }
+    };
+
+    test_encode_unnamed_array();
+
+    rc = cbor_read_flat_attrs(test_cbor_buf, test_cbor_len, test_attrs);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(arr_cnt == 3);
+    TEST_ASSERT(arr_data[0] == 1);
+    TEST_ASSERT(arr_data[1] == 2);
+    TEST_ASSERT(arr_data[2] == 33);
+}

Reply via email to