Skip to content
This repository has been archived by the owner on Apr 9, 2020. It is now read-only.

Address CPUs that do not provide for unaligned accesses #39

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/sh
if [ ! -d "build" ]; then
mkdir build
fi
Expand Down
22 changes: 12 additions & 10 deletions include/cn-cbor/cn-cbor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand Down
24 changes: 21 additions & 3 deletions src/cn-cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ extern "C" {
#include <string.h>
#include <assert.h>
#include <math.h>
#ifdef CBOR_CAN_DO_UNALIGNED_READS
#include <arpa/inet.h> // 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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src/cn-encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/cn-get.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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);
Expand Down
24 changes: 12 additions & 12 deletions test/cbor_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);
Expand Down Expand Up @@ -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];
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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<sizeof(tests)/sizeof(cbor_failure); i++) {
ASSERT_TRUE(parse_hex(tests[i].hex, &b));
Expand All @@ -253,7 +253,7 @@ CTEST(cbor, float)
"f9fc00", // -Inf
"f97c00", // Inf
};
const cn_cbor *cb;
cn_cbor *cb;
buffer b;
size_t i;
unsigned char encoded[1024];
Expand All @@ -264,7 +264,7 @@ CTEST(cbor, float)
cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
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);
Expand All @@ -276,8 +276,8 @@ CTEST(cbor, float)
CTEST(cbor, getset)
{
buffer b;
const cn_cbor *cb;
const cn_cbor *val;
cn_cbor *cb;
cn_cbor *val;
cn_cbor_errback err;

ASSERT_TRUE(parse_hex("a40000436363630262626201616100", &b));
Expand Down Expand Up @@ -425,6 +425,6 @@ CTEST(cbor, create_encode)
ASSERT_NOT_NULL(cdata);

ASSERT_TRUE(cn_cbor_mapput_int(map, 0, cdata, CONTEXT_NULL_COMMA NULL));
enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), map);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), map);
ASSERT_EQUAL(7, enc_sz);
}
2 changes: 1 addition & 1 deletion test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int main() {
char *bufend;
unsigned char *s = load_file("cases.cbor", &end);
printf("%zd\n", end-s);
const cn_cbor *cb = cn_cbor_decode(s, end-s CBOR_CONTEXT_PARAM, 0);
cn_cbor *cb = cn_cbor_decode(s, end-s CBOR_CONTEXT_PARAM, 0);
if (cb) {
dump(cb, buf, &bufend, 0);
*bufend = 0;
Expand Down