diff options
| author | Joe Hildebrand <joe-github@cursive.net> | 2015-04-01 00:04:32 -0600 |
|---|---|---|
| committer | Joe Hildebrand <joe-github@cursive.net> | 2015-04-01 00:04:32 -0600 |
| commit | be754341be643c83c7f7bccd34a8bb4f2824744e (patch) | |
| tree | d06173da69488a5d53f365a349bd740741d23568 | |
| parent | 086317455574684ee2923e3b7bab9cb51ef03531 (diff) | |
| download | platform_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.h | 34 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/cn-create.c | 168 | ||||
| -rw-r--r-- | src/cn-encoder.c | 1 | ||||
| -rw-r--r-- | test/cbor_test.c | 85 |
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); +} |
