diff --git a/build.sh b/build.sh index a07f37f..69dd2e9 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ +#!/bin/sh if [ ! -d "build" ]; then mkdir build fi diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h index 7dc67a3..2973581 100644 --- a/include/cn-cbor/cn-cbor.h +++ b/include/cn-cbor/cn-cbor.h @@ -216,7 +216,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 uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp); +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. @@ -225,7 +225,7 @@ const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cb * @param[in] key The string to look up in the map * @return The matching value, or NULL if the key is not found */ -const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); +cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); /** * Get a value from a CBOR map that has the given integer as a key. @@ -234,7 +234,7 @@ const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); * @param[in] key The int to look up in the map * @return The matching value, or NULL if the key is not found */ -const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); +cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); /** * Get the item with the given index from a CBOR array. @@ -243,15 +243,17 @@ const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); * @param[in] idx The array index * @return The matching value, or NULL if the index is invalid */ -const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); +cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); /** * Free the given CBOR structure. + * You MUST NOT try to free a cn_cbor structure with a parent (i.e., one + * that is not a root in the tree). * - * @param[in] cb The CBOR value to free + * @param[in] cb The CBOR value to free. May be NULL, or a root object. * @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined) */ -void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT); +void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT); /** * Write a CBOR value and all of the child values. @@ -263,10 +265,10 @@ void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT); * @param[in] cb [description] * @return -1 on fail, or number of bytes written */ -ssize_t cbor_encoder_write(uint8_t *buf, - size_t buf_offset, - size_t buf_size, - const cn_cbor *cb); +ssize_t cn_cbor_encoder_write(uint8_t *buf, + size_t buf_offset, + size_t buf_size, + const cn_cbor *cb); /** * Create a CBOR map. diff --git a/src/cn-cbor.c b/src/cn-cbor.c index a0cd06c..84c524c 100644 --- a/src/cn-cbor.c +++ b/src/cn-cbor.c @@ -13,15 +13,18 @@ extern "C" { #include #include #include +#ifdef CBOR_CAN_DO_UNALIGNED_READS #include // needed for ntohl (e.g.) on Linux +#endif #include "cn-cbor/cn-cbor.h" #include "cbor.h" #define CN_CBOR_FAIL(code) do { pb->err = code; goto fail; } while(0) -void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT) { - cn_cbor* p = (cn_cbor*) cb; +void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT) { + cn_cbor* p = cb; + assert(!p || !p->parent); while (p) { cn_cbor* p1; while ((p1 = p->first_child)) { /* go down */ @@ -50,8 +53,23 @@ static double decode_half(int half) { /* Fix these if you can't do non-aligned reads */ #define ntoh8p(p) (*(unsigned char*)(p)) +#ifdef CBOR_CAN_DO_UNALIGNED_READS #define ntoh16p(p) (ntohs(*(unsigned short*)(p))) #define ntoh32p(p) (ntohl(*(unsigned long*)(p))) +#else +static uint16_t ntoh16p(unsigned char *p) { + uint16_t ret = ntoh8p(p); + ret <<= 8; + ret += ntoh8p(p+1); + return ret; +} +static uint32_t ntoh32p(unsigned char *p) { + uint64_t ret = ntoh16p(p); + ret <<= 16; + ret += ntoh16p(p+2); + return ret; +} +#endif static uint64_t ntoh64p(unsigned char *p) { uint64_t ret = ntoh32p(p); ret <<= 32; @@ -237,7 +255,7 @@ static cn_cbor *decode_item (struct parse_buf *pb CBOR_CONTEXT, cn_cbor* top_par return 0; } -const cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) { +cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) { cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL}; struct parse_buf pb; cn_cbor* ret; diff --git a/src/cn-encoder.c b/src/cn-encoder.c index f53e2c6..8593b39 100644 --- a/src/cn-encoder.c +++ b/src/cn-encoder.c @@ -291,10 +291,10 @@ void _encoder_breaker(const cn_cbor *cb, int depth, void *context) write_byte_ensured(IB_BREAK); } -ssize_t cbor_encoder_write(uint8_t *buf, - size_t buf_offset, - size_t buf_size, - const cn_cbor *cb) +ssize_t cn_cbor_encoder_write(uint8_t *buf, + size_t buf_offset, + size_t buf_size, + const cn_cbor *cb) { cn_write_state ws = { buf, buf_offset, buf_size }; _visit(cb, _encoder_visitor, _encoder_breaker, &ws); diff --git a/src/cn-get.c b/src/cn-get.c index f4585b9..cc276a5 100644 --- a/src/cn-get.c +++ b/src/cn-get.c @@ -4,7 +4,7 @@ #include "cn-cbor/cn-cbor.h" -const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { +cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { cn_cbor* cp; assert(cb); for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) { @@ -25,7 +25,7 @@ const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { return NULL; } -const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { +cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { cn_cbor *cp; int keylen; assert(cb); @@ -48,7 +48,7 @@ const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { return NULL; } -const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) { +cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) { cn_cbor *cp; unsigned int i = 0; assert(cb); diff --git a/test/cbor_test.c b/test/cbor_test.c index 43f73a4..3326497 100644 --- a/test/cbor_test.c +++ b/test/cbor_test.c @@ -111,7 +111,7 @@ CTEST(cbor, parse) "9f009f00ff00ff", // [_ 0, [_ 0], 0] "bf61610161629f0203ffff", // {_ "a": 1, "b": [_ 2, 3]} }; - const cn_cbor *cb; + cn_cbor *cb; buffer b; size_t i; unsigned char encoded[1024]; @@ -125,7 +125,7 @@ CTEST(cbor, parse) ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR); ASSERT_NOT_NULL(cb); - enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); + enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz); free(b.ptr); cn_cbor_free(cb CONTEXT_NULL); @@ -159,7 +159,7 @@ CTEST(cbor, parse_normalize) "fb3e78000000000000", "fa33c00000", // 8.940696716308594e-08 "fb3e80000000000000", "f90002", // 1.1920928955078125e-07 }; - const cn_cbor *cb; + cn_cbor *cb; buffer b, b2; size_t i; unsigned char encoded[1024]; @@ -174,7 +174,7 @@ CTEST(cbor, parse_normalize) ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR); ASSERT_NOT_NULL(cb); - enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); + enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); free(b.ptr); free(b2.ptr); @@ -195,7 +195,7 @@ CTEST(cbor, parse_normalize) ASSERT_NULL(cb); #endif /* CBOR_NO_FLOAT */ - /* enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */ + /* enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */ /* ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); */ free(b.ptr); free(b2.ptr); @@ -221,13 +221,13 @@ CTEST(cbor, fail) {"1c", CN_CBOR_ERR_RESERVED_AI}, {"7f4100", CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING}, }; - const cn_cbor *cb; + cn_cbor *cb; buffer b; size_t i; uint8_t buf[10]; cn_cbor inv = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL}; - ASSERT_EQUAL(-1, cbor_encoder_write(buf, 0, sizeof(buf), &inv)); + ASSERT_EQUAL(-1, cn_cbor_encoder_write(buf, 0, sizeof(buf), &inv)); for (i=0; i