From e0a5769d06ca4cd91ea5e65a95add92d00fe0682 Mon Sep 17 00:00:00 2001 From: James McKaskill Date: Mon, 6 May 2013 00:03:17 -0400 Subject: [PATCH] Add capn_init_malloc to provide a malloc based create function --- .gitignore | 4 ++-- Makefile | 2 +- capn-malloc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ capn.h | 18 +++++++++++++++--- 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 capn-malloc.c diff --git a/.gitignore b/.gitignore index 6059fa5..925b4b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -/capn.o -/capn.so +/*.o +/*.so diff --git a/Makefile b/Makefile index 28e9b8c..5943eb3 100644 --- a/Makefile +++ b/Makefile @@ -8,5 +8,5 @@ clean: %.o: %.c *.h *.inc $(CC) -Wall -Werror -g -O2 -c $< -o $@ -capn.so: capn.o +capn.so: capn-malloc.o capn.o $(CC) -shared -Wall -Werror -fPIC -g -O2 $^ -o $@ diff --git a/capn-malloc.c b/capn-malloc.c new file mode 100644 index 0000000..db97a66 --- /dev/null +++ b/capn-malloc.c @@ -0,0 +1,42 @@ +/* vim: set sw=8 ts=8 sts=8 noet: */ +#include "capn.h" +#include +#include + +static struct capn_segment *create(void *u, uint32_t id, int sz) { + struct capn_segment *s; + if (sz < 4096) { + sz = 4096; + } else { + sz = (sz + 4095) & ~4095; + } + s = (struct capn_segment*) calloc(1, sizeof(*s)); + s->data = calloc(1, sz); + s->len = 0; + s->cap = sz; + return s; +} + +void capn_init_malloc(struct capn *c) { + memset(c, 0, sizeof(*c)); + c->create = &create; +} + +void capn_free_all(struct capn *c) { + struct capn_segment *s = c->seglist; + while (s != NULL) { + struct capn_segment *n = s->next; + free(s->data); + free(s); + s = n; + } + s = c->copylist; + while (s != NULL) { + struct capn_segment *n = s->next; + free(s->data); + free(s); + s = n; + } +} + + diff --git a/capn.h b/capn.h index 5aa987f..0f0d863 100644 --- a/capn.h +++ b/capn.h @@ -15,6 +15,8 @@ * create is used to create or lookup an alternate segment that has at least * sz available (ie returned seg->len + sz <= seg->cap) * + * Allocated segments must be zero initialized. + * * create and lookup can be NULL if you don't need multiple segments and don't * want to support copying * @@ -56,7 +58,7 @@ struct capn_tree { * * data, len, and cap must all by 8 byte aligned * - * data, len, cap, id should all set by the user. Other values should be zero + * data, len, cap should all set by the user. Other values should be zero * initialized. */ struct capn_segment { @@ -150,7 +152,7 @@ int capn_write_data(struct capn_ptr *p, int off, struct capn_data tgt); * The function returns the number of elements read or -1 on an error. * off must be byte aligned for capn_read_1 */ -int capn_read_1(const struct capn_list1 *p, int off, uint8_t *data, int sz); +int capn_read1(const struct capn_list1 *p, int off, uint8_t *data, int sz); int capn_read8(const struct capn_list8 *p, int off, uint8_t *data, int sz); int capn_read16(const struct capn_list16 *p, int off, uint16_t *data, int sz); int capn_read32(const struct capn_list32 *p, int off, uint32_t *data, int sz); @@ -162,7 +164,7 @@ int capn_read64(const struct capn_list64 *p, int off, uint64_t *data, int sz); * The function returns the number of elemnts written or -1 on an error. * off must be byte aligned for capn_read_1 */ -int capn_write_1(struct capn_list1 *p, int off, const uint8_t *data, int sz); +int capn_write1(struct capn_list1 *p, int off, const uint8_t *data, int sz); int capn_write8(struct capn_list8 *p, int off, const uint8_t *data, int sz); int capn_write16(struct capn_list16 *p, int off, const uint16_t *data, int sz); int capn_write32(struct capn_list32 *p, int off, const uint32_t *data, int sz); @@ -201,6 +203,16 @@ CAPN_INLINE int capn_set32(struct capn_ptr *p, int off, uint32_t val); CAPN_INLINE int capn_set64(struct capn_ptr *p, int off, uint64_t val); +/* capn_init_malloc inits the capn struct with a create function which + * allocates segments on the heap using malloc + * + * capn_free_all frees all the segment headers and data created by the create + * function setup by capn_init_malloc + */ +void capn_init_malloc(struct capn *c); +void capn_free_all(struct capn *c); + + int capn_marshal_iptr(const union capn_iptr*, struct capn_ptr*, int off); /* Inline functions */