aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Hildebrand <joe-github@cursive.net>2015-04-01 00:04:32 -0600
committerJoe Hildebrand <joe-github@cursive.net>2015-04-01 00:04:32 -0600
commitbe754341be643c83c7f7bccd34a8bb4f2824744e (patch)
treed06173da69488a5d53f365a349bd740741d23568
parent086317455574684ee2923e3b7bab9cb51ef03531 (diff)
downloadplatform_external_cn-cbor-be754341be643c83c7f7bccd34a8bb4f2824744e.tar.gz
platform_external_cn-cbor-be754341be643c83c7f7bccd34a8bb4f2824744e.tar.bz2
platform_external_cn-cbor-be754341be643c83c7f7bccd34a8bb4f2824744e.zip
Add creation routines
-rw-r--r--include/cn-cbor/cn-cbor.h34
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/cn-create.c168
-rw-r--r--src/cn-encoder.c1
-rw-r--r--test/cbor_test.c85
5 files changed, 287 insertions, 2 deletions
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index 247da17..161d28c 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -14,6 +14,8 @@ extern "C" {
} /* Duh. */
#endif
+#include <stdint.h>
+
/**
* All of the different kinds of CBOR values.
*/
@@ -209,7 +211,7 @@ typedef struct cn_cbor_context {
* @param[out] errp Error, if NULL is returned
* @return The parsed CBOR structure, or NULL on error
*/
-const cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
+const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
/**
* Get a value from a CBOR map that has the given string as a key.
@@ -308,6 +310,36 @@ ssize_t cbor_encoder_write(uint8_t *buf,
size_t buf_size,
const cn_cbor *cb);
+cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
+
+cn_cbor* cn_cbor_data_create(const char* data, int len
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp);
+
+cn_cbor* cn_cbor_string_create(const char* data
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp);
+
+cn_cbor* cn_cbor_int_create(int64_t value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp);
+
+void cn_cbor_mapput_int(cn_cbor* cb_map,
+ int64_t key, cn_cbor* cb_value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp);
+
+void cn_cbor_mapput_string(cn_cbor* cb_map,
+ char* key, cn_cbor* cb_value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp);
+
+cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
+
+void cn_cbor_array_append(cn_cbor* cb_array,
+ cn_cbor* cb_value,
+ cn_cbor_errback *errp);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2acac3a..ceb0608 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,6 +4,7 @@
set ( cbor_srcs
cn-cbor.c
+ cn-create.c
cn-encoder.c
cn-error.c
cn-get.c
diff --git a/src/cn-create.c b/src/cn-create.c
new file mode 100644
index 0000000..5f6d07a
--- /dev/null
+++ b/src/cn-create.c
@@ -0,0 +1,168 @@
+#ifndef CN_CREATE_C
+#define CN_CREATE_C
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "cn-cbor/cn-cbor.h"
+#include "cbor.h"
+
+#define INIT_CB(v) \
+ if (errp) {errp->err = CN_CBOR_NO_ERROR;} \
+ (v) = CN_CALLOC_CONTEXT(); \
+ if (!(v)) { if (errp) {errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;} return NULL; }
+
+cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
+{
+ cn_cbor* ret;
+ INIT_CB(ret);
+
+ ret->type = CN_CBOR_MAP;
+ ret->flags |= CN_CBOR_FL_COUNT;
+
+ return ret;
+}
+
+cn_cbor* cn_cbor_data_create(const char* data, int len
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp)
+{
+ cn_cbor* ret;
+ INIT_CB(ret);
+
+ ret->type = CN_CBOR_BYTES;
+ ret->length = len;
+ ret->v.str = data;
+
+ return ret;
+}
+
+cn_cbor* cn_cbor_string_create(const char* data
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp)
+{
+ cn_cbor* ret;
+ INIT_CB(ret);
+
+ ret->type = CN_CBOR_TEXT;
+ ret->length = strlen(data);
+ ret->v.str = data;
+
+ return ret;
+}
+
+cn_cbor* cn_cbor_int_create(int64_t value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp)
+{
+ cn_cbor* ret;
+ INIT_CB(ret);
+
+ if (value<0) {
+ ret->type = CN_CBOR_INT;
+ ret->v.sint = value;
+ } else {
+ ret->type = CN_CBOR_UINT;
+ ret->v.uint = value;
+ }
+
+ return ret;
+}
+
+static void _append_kv(cn_cbor *cb_map, cn_cbor *key, cn_cbor *val)
+{
+ //Connect key and value and insert them into the map.
+ key->parent = cb_map;
+ key->next = val;
+ val->parent = cb_map;
+ val->next = NULL;
+
+ if(cb_map->last_child) {
+ cb_map->last_child->next = key;
+ } else {
+ cb_map->first_child = key;
+ }
+ cb_map->last_child = val;
+ cb_map->length += 2;
+}
+
+void cn_cbor_mapput_int(cn_cbor* cb_map,
+ int64_t key, cn_cbor* cb_value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp)
+{
+ cn_cbor* cb_key;
+
+ //Make sure input is a map. Otherwise
+ if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
+ {
+ if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
+ return;
+ }
+
+ cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp);
+ if (!cb_key) { return; }
+ _append_kv(cb_map, cb_key, cb_value);
+}
+
+void cn_cbor_mapput_string(cn_cbor* cb_map,
+ char* key, cn_cbor* cb_value
+ CBOR_CONTEXT,
+ cn_cbor_errback *errp)
+{
+ cn_cbor* cb_key;
+
+ //Make sure input is a map. Otherwise
+ if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
+ {
+ if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
+ return;
+ }
+
+ cb_key = cn_cbor_string_create(key CBOR_CONTEXT_PARAM, errp);
+ if (!cb_key) { return; }
+ _append_kv(cb_map, cb_key, cb_value);
+}
+
+cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
+{
+ cn_cbor* ret;
+ INIT_CB(ret);
+
+ ret->type = CN_CBOR_ARRAY;
+ ret->flags |= CN_CBOR_FL_COUNT;
+
+ return ret;
+}
+
+void cn_cbor_array_append(cn_cbor* cb_array,
+ cn_cbor* cb_value,
+ cn_cbor_errback *errp)
+{
+ //Make sure input is an array.
+ if(!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY)
+ {
+ if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
+ return;
+ }
+
+ cb_value->parent = cb_array;
+ cb_value->next = NULL;
+ if(cb_array->last_child) {
+ cb_array->last_child->next = cb_value;
+ } else {
+ cb_array->first_child = cb_value;
+ }
+ cb_array->last_child = cb_value;
+ cb_array->length++;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CN_CBOR_C */
diff --git a/src/cn-encoder.c b/src/cn-encoder.c
index 14fab64..974d06c 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -11,7 +11,6 @@ extern "C" {
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
-#include <stdint.h>
#include <assert.h>
#include "cn-cbor/cn-cbor.h"
diff --git a/test/cbor_test.c b/test/cbor_test.c
index a8e5a0e..2bb60ed 100644
--- a/test/cbor_test.c
+++ b/test/cbor_test.c
@@ -20,8 +20,10 @@ int main(int argc, const char *argv[])
#ifdef USE_CBOR_CONTEXT
#define CONTEXT_NULL , NULL
+#define CONTEXT_NULL_COMMA NULL,
#else
#define CONTEXT_NULL
+#define CONTEXT_NULL_COMMA
#endif
typedef struct _buffer {
@@ -225,3 +227,86 @@ CTEST(cbor, getset)
free(b.ptr);
cn_cbor_free(cb CONTEXT_NULL);
}
+
+CTEST(cbor, create)
+{
+ cn_cbor_errback err;
+ const cn_cbor* val;
+ const char* data = "abc";
+ cn_cbor *cb_map = cn_cbor_map_create(CONTEXT_NULL_COMMA &err);
+ cn_cbor *cb_int;
+ cn_cbor *cb_data;
+
+ ASSERT_NOT_NULL(cb_map);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+
+ cb_int = cn_cbor_int_create(256 CONTEXT_NULL, &err);
+ ASSERT_NOT_NULL(cb_int);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+
+ cb_data = cn_cbor_data_create(data, 4 CONTEXT_NULL, &err);
+ ASSERT_NOT_NULL(cb_data);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+
+ cn_cbor_mapput_int(cb_map, 5, cb_int CONTEXT_NULL, &err);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_TRUE(cb_map->length == 2);
+
+ cn_cbor_mapput_int(cb_map, -7, cb_data CONTEXT_NULL, &err);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_TRUE(cb_map->length == 4);
+
+ cn_cbor_mapput_string(cb_map, "foo",
+ cn_cbor_string_create(data CONTEXT_NULL, &err)
+ CONTEXT_NULL, &err);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_TRUE(cb_map->length == 6);
+
+ val = cn_cbor_mapget_int(cb_map, 5);
+ ASSERT_NOT_NULL(val);
+ ASSERT_TRUE(val->v.sint == 256);
+
+ val = cn_cbor_mapget_int(cb_map, -7);
+ ASSERT_NOT_NULL(val);
+ ASSERT_STR(val->v.str, "abc");
+
+ cn_cbor_free(cb_map CONTEXT_NULL);
+}
+
+CTEST(cbor, map_errors)
+{
+ cn_cbor_errback err;
+ cn_cbor *ci;
+ ci = cn_cbor_int_create(65536, CONTEXT_NULL_COMMA &err);
+ cn_cbor_mapput_int(ci, -5, NULL, CONTEXT_NULL_COMMA &err);
+ ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
+ cn_cbor_mapput_string(ci, "foo", NULL, CONTEXT_NULL_COMMA &err);
+ ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
+}
+
+CTEST(cbor, array)
+{
+ cn_cbor_errback err;
+ cn_cbor *a = cn_cbor_array_create(CONTEXT_NULL_COMMA &err);
+ ASSERT_NOT_NULL(a);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_EQUAL(a->length, 0);
+
+ cn_cbor_array_append(a, cn_cbor_int_create(256, CONTEXT_NULL_COMMA &err), &err);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_EQUAL(a->length, 1);
+
+ cn_cbor_array_append(a, cn_cbor_string_create("five", CONTEXT_NULL_COMMA &err), &err);
+ ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+ ASSERT_EQUAL(a->length, 2);
+}
+
+CTEST(cbor, array_errors)
+{
+ cn_cbor_errback err;
+ cn_cbor *ci = cn_cbor_int_create(12, CONTEXT_NULL_COMMA &err);
+ cn_cbor_array_append(NULL, ci, &err);
+ ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
+ cn_cbor_array_append(ci, NULL, &err);
+ ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
+}