Merge in changes from SPUDlib, in preparation for moving to cmake
diff --git a/Makefile b/Makefile
index 40c5ee1..68e59ce 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,8 @@
env MallocStackLogging=true ./cntest >new.out
-diff new.out expected.out
-cntest: cbor.h cn-cbor.h cn-cbor.c cn-error.c cn-manip.c test.c
- clang $(CFLAGS) cn-cbor.c cn-error.c cn-manip.c test.c -o cntest
+cntest: cbor.h cn-cbor.h cn-cbor.c cn-error.c cn-get.c test.c
+ clang $(CFLAGS) cn-cbor.c cn-error.c cn-get.c test.c -o cntest
size: cn-cbor.o
size cn-cbor.o
diff --git a/cn-cbor.c b/cn-cbor.c
index 6336ee4..8136880 100644
--- a/cn-cbor.c
+++ b/cn-cbor.c
@@ -17,15 +17,19 @@
#include "cn-cbor.h"
#include "cbor.h"
-// can be redefined, e.g. for pool allocation
-#ifndef CN_CBOR_CALLOC
-#define CN_CBOR_CALLOC() calloc(1, sizeof(cn_cbor))
-#define CN_CBOR_FREE(cb) free((void*)(cb))
-#endif
-
#define CN_CBOR_FAIL(code) do { pb->err = code; goto fail; } while(0)
-void cn_cbor_free(const cn_cbor* cb) {
+#ifdef USE_CBOR_CONTEXT
+#define CBOR_CONTEXT_PARAM , context
+#define CN_CALLOC_CONTEXT() CN_CALLOC(context)
+#define CN_CBOR_FREE_CONTEXT(p) CN_FREE(p, context)
+#else
+#define CBOR_CONTEXT_PARAM
+#define CN_CALLOC_CONTEXT() CN_CALLOC
+#define CN_CBOR_FREE_CONTEXT(p) CN_FREE(p)
+#endif
+
+void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT) {
cn_cbor* p = (cn_cbor*) cb;
while (p) {
cn_cbor* p1;
@@ -36,7 +40,7 @@
if ((p1 = p->parent))
p1->first_child = 0;
}
- CN_CBOR_FREE(p);
+ CN_CBOR_FREE_CONTEXT(p);
p = p1;
}
}
@@ -81,7 +85,7 @@
stmt; \
pos += n;
-static cn_cbor *decode_item (struct parse_buf *pb, cn_cbor* top_parent) {
+static cn_cbor *decode_item (struct parse_buf *pb CBOR_CONTEXT, cn_cbor* top_parent) {
unsigned char *pos = pb->buf;
unsigned char *ebuf = pb->ebuf;
cn_cbor* parent = top_parent;
@@ -89,7 +93,7 @@
unsigned int mt;
int ai;
uint64_t val;
- cn_cbor* cb;
+ cn_cbor* cb = NULL;
union {
float f;
uint32_t u;
@@ -119,7 +123,7 @@
ai = ib & 0x1f;
val = ai;
- cb = CN_CBOR_CALLOC();
+ cb = CN_CALLOC_CONTEXT();
if (!cb)
CN_CBOR_FAIL(CN_CBOR_ERR_OUT_OF_MEMORY);
@@ -159,7 +163,7 @@
case MT_BYTES: case MT_TEXT:
cb->v.str = (char *) pos;
cb->length = val;
- TAKE(pos, ebuf, val, );
+ TAKE(pos, ebuf, val, ;);
break;
case MT_MAP:
val <<= 1;
@@ -222,19 +226,24 @@
return 0;
}
-const cn_cbor* cn_cbor_decode(const char* buf, size_t len, cn_cbor_errback *errp) {
+const 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 = {(unsigned char *)buf, (unsigned char *)buf+len, CN_CBOR_NO_ERROR};
- cn_cbor* ret = decode_item(&pb, &catcher);
+ struct parse_buf pb;
+ cn_cbor* ret;
+
+ pb.buf = (unsigned char *)buf;
+ pb.ebuf = (unsigned char *)buf+len;
+ pb.err = CN_CBOR_NO_ERROR;
+ ret = decode_item(&pb CBOR_CONTEXT_PARAM, &catcher);
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);
+ cn_cbor_free(catcher.first_child CBOR_CONTEXT_PARAM);
}
- //fail:
+//fail:
if (errp) {
errp->err = pb.err;
errp->pos = pb.buf - (unsigned char *)buf;
diff --git a/cn-cbor.h b/cn-cbor.h
index 2bf9416..c0ecfa9 100644
--- a/cn-cbor.h
+++ b/cn-cbor.h
@@ -52,7 +52,8 @@
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,
+ CN_CBOR_ERR_INVALID_PARAMETER,
+ CN_CBOR_ERR_OUT_OF_MEMORY
} cn_cbor_error;
extern const char *cn_cbor_error_str[];
@@ -62,13 +63,44 @@
cn_cbor_error err;
} cn_cbor_errback;
-const cn_cbor* cn_cbor_decode(const char* buf, size_t len, cn_cbor_errback *errp);
+#ifdef USE_CBOR_CONTEXT
+
+typedef void* (*cn_alloc_func)(size_t count, size_t size, void *context);
+typedef void (*cn_free_func)(void *ptr, void *context);
+
+typedef struct cn_cbor_context {
+ cn_alloc_func calloc_func;
+ cn_free_func free_func;
+ void *context;
+} cn_cbor_context;
+
+#define CN_CALLOC(ctx) ((ctx) && (ctx)->calloc_func) ? \
+ (ctx)->calloc_func(1, sizeof(cn_cbor), (ctx)->context) : \
+ calloc(1, sizeof(cn_cbor));
+#define CN_FREE(ptr, ctx) ((ctx) && (ctx)->free_func) ? \
+ (ctx)->free_func((ptr), (ctx)->context) : \
+ free((ptr));
+#define CBOR_CONTEXT , cn_cbor_context *context
+#define CBOR_CONTEXT_COMMA cn_cbor_context *context,
+
+#else
+
+#define CBOR_CONTEXT
+#define CBOR_CONTEXT_COMMA
+#ifndef CN_CALLOC
+#define CN_CALLOC calloc(1, sizeof(cn_cbor))
+#endif
+#ifndef CN_FREE
+#define CN_FREE free
+#endif
+
+#endif
+
+const cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
-const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
-
-const cn_cbor* cn_cbor_alloc(cn_cbor_type t);
-void cn_cbor_free(const cn_cbor* js);
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, int idx);
+void cn_cbor_free(const cn_cbor* js CBOR_CONTEXT);
#ifdef __cplusplus
}
diff --git a/cn-get.c b/cn-get.c
index 130ab97..4f91c45 100644
--- a/cn-get.c
+++ b/cn-get.c
@@ -33,7 +33,14 @@
keylen = strlen(key);
for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) {
switch(cp->type) {
- case CN_CBOR_TEXT: // fall through
+ 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;
@@ -48,9 +55,9 @@
return NULL;
}
-const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, int idx) {
cn_cbor *cp;
- unsigned int i = 0;
+ int i = 0;
assert(cb);
for (cp = cb->first_child; cp; cp = cp->next) {
if (i == idx) {
diff --git a/test.c b/test.c
index 5b949ee..0b8ef3f 100644
--- a/test.c
+++ b/test.c
@@ -8,7 +8,7 @@
#define ERROR(msg, p) fprintf(stderr, "ERROR: " msg " %s\n", (p));
-static char* load_file(const char* filepath, char **end) {
+static unsigned char* load_file(const char* filepath, unsigned char **end) {
struct stat st;
if (stat(filepath, &st)==-1) {
ERROR("can't find file", filepath);
@@ -19,7 +19,7 @@
ERROR("can't open file", filepath);
return 0;
}
- char* text=malloc(st.st_size+1); // this is not going to be freed
+ unsigned char* text=malloc(st.st_size+1); // this is not going to be freed
if (st.st_size!=read(fd, text, st.st_size)) {
ERROR("can't read file", filepath);
close(fd);
@@ -92,7 +92,7 @@
"CN_CBOR_ERR_OUT_OF_MEMORY",
};
-static void cn_cbor_decode_test(const char *buf, int len) {
+static void cn_cbor_decode_test(const unsigned char *buf, int len) {
struct cn_cbor_errback back;
const cn_cbor *ret = cn_cbor_decode(buf, len, &back);
if (ret)
@@ -102,24 +102,25 @@
int main() {
char buf[100000];
- char *end;
- char *s = load_file("cases.cbor", &end);
+ unsigned char *end;
+ 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, 0);
if (cb) {
- dump(cb, buf, &end, 0);
- *end = 0;
+ dump(cb, buf, &bufend, 0);
+ *bufend = 0;
printf("%s\n", buf);
cn_cbor_free(cb);
cb = 0; /* for leaks testing */
}
- cn_cbor_decode_test("\xff", 1); /* break outside indef */
- cn_cbor_decode_test("\x1f", 1); /* mt undef for indef */
- cn_cbor_decode_test("\x00\x00", 2); /* not all data consumed */
- cn_cbor_decode_test("\x81", 1); /* out of data */
- cn_cbor_decode_test("\x1c", 1); /* reserved ai */
- cn_cbor_decode_test("\xbf\x00\xff", 3); /* odd size indef map */
- cn_cbor_decode_test("\x7f\x40\xff", 3); /* wrong nesting in indef string */
+ cn_cbor_decode_test((const unsigned char*)"\xff", 1); /* break outside indef */
+ cn_cbor_decode_test((const unsigned char*)"\x1f", 1); /* mt undef for indef */
+ cn_cbor_decode_test((const unsigned char*)"\x00\x00", 2); /* not all data consumed */
+ cn_cbor_decode_test((const unsigned char*)"\x81", 1); /* out of data */
+ cn_cbor_decode_test((const unsigned char*)"\x1c", 1); /* reserved ai */
+ cn_cbor_decode_test((const unsigned char*)"\xbf\x00\xff", 3); /* odd size indef map */
+ cn_cbor_decode_test((const unsigned char*)"\x7f\x40\xff", 3); /* wrong nesting in indef string */
system("leaks test");
}