Merge branch 'hildjj-master'
diff --git a/Makefile b/Makefile
index 554c767..1752a6d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,8 @@
env MallocStackLogging=true ./cntest >new.out
-diff new.out expected.out
-cntest: test.c cbor.h cn-cbor.h cn-cbor.c
- clang $(CFLAGS) cn-cbor.c test.c -o cntest
+cntest: test.c cbor.h cn-cbor.h cn-cbor.c cn-manip.c
+ clang $(CFLAGS) cn-cbor.c cn-error.c cn-manip.c test.c -o cntest
size: cn-cbor.o
size cn-cbor.o
diff --git a/cn-cbor.c b/cn-cbor.c
index 0a9779f..e0fd53b 100644
--- a/cn-cbor.c
+++ b/cn-cbor.c
@@ -14,7 +14,10 @@
#include <assert.h>
#include <math.h>
+#include <arpa/inet.h>
+
#include "cn-cbor.h"
+#include "cbor.h"
// can be redefined, e.g. for pool allocation
#ifndef CN_CBOR_CALLOC
@@ -84,8 +87,22 @@
unsigned char *pos = pb->buf;
unsigned char *ebuf = pb->ebuf;
cn_cbor* parent = top_parent;
+ int ib;
+ unsigned int mt;
+ int ai;
+ uint64_t val;
+ cn_cbor* cb = NULL;
+ union {
+ float f;
+ uint32_t u;
+ } u32;
+ union {
+ double d;
+ uint64_t u;
+ } u64;
+
again:
- TAKE(pos, ebuf, 1, int ib = ntoh8p(pos) );
+ TAKE(pos, ebuf, 1, ib = ntoh8p(pos) );
if (ib == IB_BREAK) {
if (!(parent->flags & CN_CBOR_FL_INDEF))
CN_CBOR_FAIL(CN_CBOR_ERR_BREAK_OUTSIDE_INDEF);
@@ -100,11 +117,11 @@
}
goto complete;
}
- unsigned int mt = ib >> 5;
- int ai = ib & 0x1f;
- uint64_t val = ai;
+ mt = ib >> 5;
+ ai = ib & 0x1f;
+ val = ai;
- cn_cbor* cb = CN_CBOR_CALLOC();
+ cb = CN_CBOR_CALLOC();
if (!cb)
CN_CBOR_FAIL(CN_CBOR_ERR_OUT_OF_MEMORY);
@@ -166,19 +183,11 @@
case AI_2: cb->type = CN_CBOR_DOUBLE; cb->v.dbl = decode_half(val); break;
case AI_4:
cb->type = CN_CBOR_DOUBLE;
- union {
- float f;
- uint32_t u;
- } u32;
u32.u = val;
cb->v.dbl = u32.f;
break;
case AI_8:
cb->type = CN_CBOR_DOUBLE;
- union {
- double d;
- uint64_t u;
- } u64;
u64.u = val;
cb->v.dbl = u64.d;
break;
@@ -216,22 +225,22 @@
}
const cn_cbor* cn_cbor_decode(const char* buf, size_t len, cn_cbor_errback *errp) {
- cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, 0, 0, 0, 0};
+ cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL};
struct parse_buf pb = {(unsigned char *)buf, (unsigned char *)buf+len, CN_CBOR_NO_ERROR};
cn_cbor* ret = decode_item(&pb, &catcher);
- if (ret) {
- ret->parent = 0; /* mark as top node */
+ if (ret != NULL) {
+ /* mark as top node */
+ ret->parent = NULL;
} else {
if (catcher.first_child) {
catcher.first_child->parent = 0;
cn_cbor_free(catcher.first_child);
}
- //fail:
if (errp) {
errp->err = pb.err;
errp->pos = pb.buf - (unsigned char *)buf;
}
- return 0;
+ return NULL;
}
return ret;
}
diff --git a/cn-cbor.h b/cn-cbor.h
index 62d8b78..7764190 100644
--- a/cn-cbor.h
+++ b/cn-cbor.h
@@ -8,9 +8,6 @@
} /* Duh. */
#endif
-/* protocol constants: */
-#include "cbor.h"
-
typedef enum cn_cbor_type {
CN_CBOR_NULL,
CN_CBOR_FALSE, CN_CBOR_TRUE,
@@ -58,6 +55,8 @@
CN_CBOR_ERR_OUT_OF_MEMORY,
} cn_cbor_error;
+extern const char *cn_cbor_error_str[];
+
typedef struct cn_cbor_errback {
int pos;
cn_cbor_error err;
diff --git a/cn-error.c b/cn-error.c
new file mode 100644
index 0000000..b1dd58c
--- /dev/null
+++ b/cn-error.c
@@ -0,0 +1,11 @@
+const char *cn_cbor_error_str[] = {
+ "CN_CBOR_NO_ERROR",
+ "CN_CBOR_ERR_OUT_OF_DATA",
+ "CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED",
+ "CN_CBOR_ERR_ODD_SIZE_INDEF_MAP",
+ "CN_CBOR_ERR_BREAK_OUTSIDE_INDEF",
+ "CN_CBOR_ERR_MT_UNDEF_FOR_INDEF",
+ "CN_CBOR_ERR_RESERVED_AI",
+ "CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING",
+ "CN_CBOR_ERR_OUT_OF_MEMORY"
+};
diff --git a/cn-manip.c b/cn-manip.c
new file mode 100644
index 0000000..4f91c45
--- /dev/null
+++ b/cn-manip.c
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "cn-cbor.h"
+
+const 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) {
+ switch(cp->type) {
+ case CN_CBOR_UINT:
+ if (cp->v.uint == (unsigned long)key) {
+ return cp->next;
+ }
+ case CN_CBOR_INT:
+ if (cp->v.sint == (long)key) {
+ return cp->next;
+ }
+ break;
+ default:
+ ; // skip non-integer keys
+ }
+ }
+ return NULL;
+}
+
+const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
+ cn_cbor *cp;
+ int keylen;
+ assert(cb);
+ assert(key);
+ keylen = strlen(key);
+ for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) {
+ switch(cp->type) {
+ case CN_CBOR_TEXT:
+ if (keylen != cp->length) {
+ continue;
+ }
+ if (strncmp(key, cp->v.str, cp->length) == 0) {
+ return cp->next;
+ }
+ break;
+ case CN_CBOR_BYTES:
+ if (keylen != cp->length) {
+ continue;
+ }
+ if (memcmp(key, cp->v.str, keylen) == 0) {
+ return cp->next;
+ }
+ default:
+ ; // skip non-string keys
+ }
+ }
+ return NULL;
+}
+
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, int idx) {
+ cn_cbor *cp;
+ int i = 0;
+ assert(cb);
+ for (cp = cb->first_child; cp; cp = cp->next) {
+ if (i == idx) {
+ return cp;
+ }
+ i++;
+ }
+ return NULL;
+}