From 03368cb350df986fb0facda2ea637ac4bf7217e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Schr=C3=B6der?= Date: Fri, 11 Dec 2015 15:01:34 +0100 Subject: [PATCH] refactor blobmsg creation (parsing may still be broken!) --- Makefile | 2 +- README.md | 8 ++- blob.c | 153 ++++++++++++++++++---------------------------- blob.h | 58 ++++++++++-------- blobmsg.c | 129 ++++++++++++++++++++------------------ blobmsg.h | 18 +++--- blobmsg_json.c | 22 +++---- examples/simple.c | 11 +++- tests/random.c | 9 ++- 9 files changed, 198 insertions(+), 212 deletions(-) diff --git a/Makefile b/Makefile index 9b53a7d..2f9cda4 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ SOURCE:=$(wildcard *.c) HEADERS:=$(wildcard *.h) OBJECTS:=$(patsubst %.c,%.o,$(SOURCE)) LDFLAGS+=-ljson-c -CFLAGS+=-std=gnu99 -fPIC +CFLAGS+=-Werror -Wall -std=gnu99 -fPIC INSTALL_PREFIX:=/usr STATIC_LIB:=lib$(PACKAGE_NAME).a diff --git a/README.md b/README.md index f16cc1f..89c0e28 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Blobpack packs attributes into a blob buffer. Each attribute has an id which identifies the type of attribute inside the blob buffer. The data inside the buffer is packed as a list of blob\_attr structures like this: + attr attr +-----------------+-----------------+ | id + len | data | id + len | data | +-----------------+-----------------+ @@ -69,9 +70,10 @@ Note that all attributes in the blobmsg structure are named. If in the simple bl A blobmsg buffer looks like this: - +-----------------------------------+----------+------+------+ - | BLOBMSG_TYPE | EXTENDED + TOT_LEN | name_len | name | data | - +-----------------------------------+----------+------+------+ + | blobmsg | blobmsg_hdr | blobmsg_data | + +-----------------------------------+----------+------+--------------+ + | BLOBMSG_TYPE | EXTENDED + TOT_LEN | name_len | name | blob_attr | + +-----------------------------------+----------+------+--------------+ Note: each field is padded using BLOBMSG\_PADDING(len) macro. diff --git a/blob.c b/blob.c index 612934d..8ad51d3 100644 --- a/blob.c +++ b/blob.c @@ -19,25 +19,13 @@ #include "blob.h" static void blob_attr_init(struct blob_attr *attr, int id, unsigned int len){ + assert(attr); memset(attr, 0, sizeof(struct blob_attr)); len &= BLOB_ATTR_LEN_MASK; len |= (id << BLOB_ATTR_ID_SHIFT) & BLOB_ATTR_ID_MASK; attr->id_len = cpu_to_be32(len); } -static inline struct blob_attr * -_blob_buf_offset_to_attr(struct blob_buf *buf, int offset) -{ - void *ptr = (char *)buf->buf + offset; - return ptr; -} - -static inline int -_blob_buf_attr_to_offset(struct blob_buf *buf, struct blob_attr *attr) -{ - return (char *)attr - (char *) buf->buf; -} - //! Attepts to reallocate the buffer to fit the new payload data bool blob_buf_resize(struct blob_buf *buf, int minlen){ char *new = 0; @@ -46,12 +34,10 @@ bool blob_buf_resize(struct blob_buf *buf, int minlen){ if(newsize > buf->memlen){ new = realloc(buf->buf, newsize); if (new) { - int offset_head = _blob_buf_attr_to_offset(buf, buf->head); buf->buf = new; memset(buf->buf + buf->datalen, 0, newsize - buf->datalen); buf->datalen = minlen; buf->memlen = newsize; - buf->head = _blob_buf_offset_to_attr(buf, offset_head); } else { return false; } @@ -62,32 +48,12 @@ bool blob_buf_resize(struct blob_buf *buf, int minlen){ return true; } -static struct blob_attr * -_blob_buf_add(struct blob_buf *buf, struct blob_attr *pos, int id, int payload) -{ - int offset = _blob_buf_attr_to_offset(buf, pos); // get offset to attr header in the buffer - int newsize = offset + sizeof(struct blob_attr) + payload; - struct blob_attr *attr = pos; - - if (newsize > buf->datalen) { - // if buffer needs to grow then we grow it - if (!blob_buf_resize(buf, newsize)) - return NULL; - attr = _blob_buf_offset_to_attr(buf, offset); - } - - blob_attr_init(attr, id, payload + sizeof(struct blob_attr)); - blob_attr_fill_pad(attr); - - return attr; -} - -int blob_buf_reset(struct blob_buf *buf, int type){ - memset(buf->buf, 0, buf->memlen); - buf->head = buf->buf; - blob_attr_init(buf->head, type, sizeof(struct blob_attr)); - blob_attr_fill_pad(buf->head); - return 0; +void blob_buf_reset(struct blob_buf *buf){ + assert(buf); + assert(buf->buf); + if(buf->memlen) + memset(buf->buf, 0, buf->memlen); + buf->cursor = 0; } int blob_buf_init(struct blob_buf *buf, const char *data, size_t size){ @@ -95,16 +61,16 @@ int blob_buf_init(struct blob_buf *buf, const char *data, size_t size){ // default buffer is 256 bytes block with zero sized data buf->memlen = (size > 0)?size:256; + buf->cursor = 0; buf->buf = malloc(buf->memlen); if(!buf->buf) return -ENOMEM; if(data) { memcpy(buf->buf, data, size); - buf->head = buf->buf; buf->datalen = size; } else { memset(buf->buf, 0, buf->memlen); - blob_buf_reset(buf, 0); + blob_buf_reset(buf); } return 0; } @@ -133,16 +99,22 @@ blob_attr_set_raw_len(struct blob_attr *attr, unsigned int len) attr->id_len |= cpu_to_be32(len); } -struct blob_attr * -blob_buf_new_attr(struct blob_buf *buf, int id, int payload) -{ - struct blob_attr *attr; +struct blob_attr *blob_buf_new_attr(struct blob_buf *buf, int id, int payload){ + int newsize = buf->cursor + sizeof(struct blob_attr) + payload; - attr = _blob_buf_add(buf, blob_attr_next(buf->head), id, payload); - if (!attr) - return NULL; + if (newsize > buf->datalen) { + // if buffer needs to grow then we grow it + if (!blob_buf_resize(buf, newsize)) + return NULL; + } + + struct blob_attr *attr = blob_buf_current(buf); + + blob_attr_init(attr, id, payload + sizeof(struct blob_attr)); + blob_attr_fill_pad(attr); + + buf->cursor = newsize; - blob_attr_set_raw_len(buf->head, blob_attr_pad_len(buf->head) + blob_attr_pad_len(attr)); return attr; } @@ -154,11 +126,11 @@ blob_buf_put_raw(struct blob_buf *buf, const void *ptr, unsigned int len) if (len < sizeof(struct blob_attr) || !ptr) return NULL; - attr = _blob_buf_add(buf, blob_attr_next(buf->head), 0, len - sizeof(struct blob_attr)); + attr = blob_buf_new_attr(buf, 0, len - sizeof(struct blob_attr)); if (!attr) return NULL; - blob_attr_set_raw_len(buf->head, blob_attr_pad_len(buf->head) + len); - memcpy(attr, ptr, len); + + memcpy(attr->data, ptr, len); return attr; } @@ -178,22 +150,18 @@ blob_buf_put(struct blob_buf *buf, int id, const void *ptr, unsigned int len) return attr; } -void * -blob_buf_nest_start(struct blob_buf *buf, int id) -{ - unsigned long offset = _blob_buf_attr_to_offset(buf, buf->head); - buf->head = blob_buf_new_attr(buf, id, 0); - if (!buf->head) - return NULL; - return (void *) offset; +void *blob_buf_nest_start(struct blob_buf *buf, int id){ + struct blob_attr *attr = blob_buf_new_attr(buf, id, 0); + unsigned long offset = blob_buf_attr_to_offset(buf, attr); + return (void*)offset; } -void -blob_buf_nest_end(struct blob_buf *buf, void *cookie) -{ - struct blob_attr *attr = _blob_buf_offset_to_attr(buf, (unsigned long) cookie); - blob_attr_set_raw_len(attr, blob_attr_pad_len(attr) + blob_attr_len(buf->head)); - buf->head = attr; +#include "blobmsg.h" + +void blob_buf_nest_end(struct blob_buf *buf, void *cookie){ + struct blob_attr *attr = blob_buf_offset_to_attr(buf, (unsigned long) cookie); + int len = (char*)blob_buf_current(buf) + blob_attr_raw_len(blob_buf_current(buf)) - (char*)attr; + blob_attr_set_raw_len(attr, len); } static const int blob_type_minlen[BLOB_ATTR_LAST] = { @@ -372,36 +340,35 @@ struct blob_attr *blob_buf_put_double(struct blob_buf *buf, int id, double value return blob_buf_put_u64(buf, id, pack754_64(value)); } -void blob_buf_dump(struct blob_buf *self){ - struct blob_attr *pos; - if(!self) return; +static void _blob_attr_dump(struct blob_buf *self, struct blob_attr *owner, struct blob_attr *attr){ + if(blob_attr_id(attr) == BLOB_ATTR_NESTED){ + printf(">>\n"); + _blob_attr_dump(self, attr, blob_attr_data(attr)); + printf("<<\n"); + return; + } - struct blob_attr *cur = self->cursor; + char *data = (char*)attr; - printf("=========== blob ===========\n"); - for(int c = 0; c < blob_buf_size(self); c++){ + int id = blob_attr_id(attr); + int len = blob_attr_pad_len(attr); + + printf("blobfield: id=%d offset=%d\n", id, (int)((char*)attr - (char*)owner)); + printf("\tlength: %d\n", len); + printf("\tpadlen: %d\n", blob_attr_pad_len(attr)); + + for(int c = 0; c < blob_attr_len(attr); c++){ if(c > 0 && c % 10 == 0) printf("\n"); - printf(" %02x", ((char*)self->buf)[c] & 0xff); + printf(" %02x", data[c] & 0xff); } printf("\n"); - - for(pos = blob_buf_first(self); pos; pos = blob_buf_next(self)){ - int id = blob_attr_id(pos); - int len = blob_attr_len(pos); - - printf("blobfield: id=%d offset=%d\n", id, (int)((char*)pos - (char*)self->buf)); - printf("\tlength: %d\n", len); - printf("\tpadlen: %d\n", blob_attr_pad_len(pos)); - - for(int c = 0; c < blob_attr_len(pos); c++){ - if(c > 0 && c % 10 == 0) - printf("\n"); - printf(" %02x", ((char*)pos->data)[c] & 0xff); - } - } - printf("==\n"); - - self->cursor = cur; } +void blob_buf_dump(struct blob_buf *self){ + if(!self) return; + + printf("=========== blob ===========\n"); + _blob_attr_dump(self, NULL, blob_buf_first(self)); + printf("============================\n"); +} diff --git a/blob.h b/blob.h index 7ab1414..4f672b7 100644 --- a/blob.h +++ b/blob.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "utils.h" @@ -63,8 +64,9 @@ struct blob_attr_info { }; struct blob_buf { - struct blob_attr *head; // pointer to current head - struct blob_attr *cursor; + //struct blob_attr *head; // pointer to current head + //struct blob_attr *cursor; // pointer to current position in the buffer (when adding or removing items) + size_t cursor; size_t datalen; // length of filled data in the buffer size_t memlen; // total length of the allocated memory area void *buf; // raw buffer data @@ -192,10 +194,11 @@ blob_attr_get_raw(const struct blob_attr *attr, uint8_t *data, size_t data_size) float blob_attr_get_float(const struct blob_attr *attr); double blob_attr_get_double(const struct blob_attr *attr); -static inline struct blob_attr * -blob_attr_next(const struct blob_attr *attr) -{ - return (struct blob_attr *) ((char *) attr + blob_attr_pad_len(attr)); +static inline struct blob_attr *blob_attr_next(const struct blob_attr *owner, const struct blob_attr *attr){ + struct blob_attr *ret = (struct blob_attr *) ((char *) attr + blob_attr_raw_len(attr)); + size_t offset = (char*)ret - (char*)owner; + if(offset >= blob_attr_pad_len(owner)) return NULL; + return ret; } extern void blob_attr_fill_pad(struct blob_attr *attr); @@ -206,7 +209,7 @@ extern struct blob_attr *blob_attr_memdup(struct blob_attr *attr); extern bool blob_attr_check_type(const void *ptr, unsigned int len, int type); extern int blob_buf_init(struct blob_buf *buf, const char *data, size_t size); -extern int blob_buf_reset(struct blob_buf *buf, int id); +extern void blob_buf_reset(struct blob_buf *buf); extern void blob_buf_free(struct blob_buf *buf); extern bool blob_buf_resize(struct blob_buf *buf, int newsize); extern struct blob_attr *blob_buf_new_attr(struct blob_buf *buf, int id, int payload); @@ -216,26 +219,31 @@ extern struct blob_attr *blob_buf_put(struct blob_buf *buf, int id, const void * extern struct blob_attr *blob_buf_put_raw(struct blob_buf *buf, const void *ptr, unsigned int len); void blob_buf_dump(struct blob_buf *self); -static inline struct blob_attr * -blob_buf_first(struct blob_buf *self){ - self->cursor = blob_attr_data((struct blob_attr*)self->buf); - return self->cursor; +static inline struct blob_attr *blob_buf_offset_to_attr(struct blob_buf *buf, size_t offset){ + void *ptr = (char *)buf->buf + offset; + return ptr; } -static inline struct blob_attr * -blob_buf_next(struct blob_buf *self){ - if(!self->cursor) return NULL; - int len = blob_attr_pad_len(self->cursor); - if(len < 0 || ((char*)(self->cursor) + len) > ((char*)self->buf + self->datalen)) return NULL; - struct blob_attr *next = (struct blob_attr *) ((char *) self->cursor + len); - if((char*)next >= (char*)(self->buf + self->datalen)) { - return NULL; - } - - self->cursor = next; - return self->cursor; +static inline size_t blob_buf_attr_to_offset(struct blob_buf *buf, struct blob_attr *attr){ + return (char *)attr - (char *) buf->buf; } +static inline struct blob_attr *blob_buf_first(struct blob_buf *self){ + return (struct blob_attr*)self->buf; +} + +static inline struct blob_attr *blob_buf_current(struct blob_buf *self){ + return (struct blob_attr*)((char*)self->buf + self->cursor); +} + +/* +static inline struct blob_attr *blob_buf_next(struct blob_buf *self){ + int len = blob_attr_pad_len(blob_buf_current(self)); + if(len < 0 || (self->cursor + len) > self->datalen) return NULL; + self->cursor += len; + return blob_buf_current(self); +} +*/ static inline size_t blob_buf_size(struct blob_buf *self){ return self->datalen; } static inline struct blob_attr * blob_buf_put_string(struct blob_buf *buf, int id, const char *str) @@ -290,7 +298,7 @@ struct blob_attr *blob_buf_put_double(struct blob_buf *buf, int id, double value for (pos = (void *) attr; \ rem > 0 && (blob_attr_pad_len(pos) <= rem) && \ (blob_attr_pad_len(pos) >= sizeof(struct blob_attr)); \ - rem -= blob_attr_pad_len(pos), pos = blob_attr_next(pos)) + rem -= blob_attr_pad_len(pos), pos = blob_attr_next(attr, pos)) #define blob_buf_for_each_attr(pos, attr, rem) \ @@ -298,7 +306,7 @@ struct blob_attr *blob_buf_put_double(struct blob_buf *buf, int id, double value pos = attr ? blob_attr_data(attr) : 0; \ rem > 0 && (blob_attr_pad_len(pos) <= rem) && \ (blob_attr_pad_len(pos) >= sizeof(struct blob_attr)); \ - rem -= blob_attr_pad_len(pos), pos = blob_attr_next(pos)) + rem -= blob_attr_pad_len(pos), pos = blob_attr_next(attr, pos)) #endif diff --git a/blobmsg.c b/blobmsg.c index 6cd43a3..e1cab90 100644 --- a/blobmsg.c +++ b/blobmsg.c @@ -126,14 +126,53 @@ int blobmsg_parse_array(const struct blobmsg_policy *policy, int policy_len, return 0; } +static void _blobmsg_attr_dump(struct blob_buf *self, struct blob_attr *owner, struct blob_attr *attr){ + int id = blobmsg_type(attr); + char *data = (char*)attr; + int len = blob_attr_pad_len(attr); -int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, - struct blob_attr **tb, void *data, unsigned int len) + printf("%s: id=%d offset=%d\n", blobmsg_name(attr), id, (int)((char*)attr - (char*)owner)); + printf("\tlength: %d\n", len); + printf("\tpadlen: %d\n", blob_attr_pad_len(attr)); + + // dump memory + for(int c = 0; c < blob_attr_raw_len(attr); c++){ + if(c > 0 && c % 10 == 0) + printf("\n"); + printf(" %02x(%c)", data[c] & 0xff, (data[c]>50 && data[c]<127)?data[c]:'.'); + } + printf("\n"); + + // if nested, then go through all children + if(id == BLOBMSG_TYPE_ARRAY || id == BLOBMSG_TYPE_TABLE){ + printf(">>\n"); + + for(struct blob_attr *child = blobmsg_data(attr); child; child = blob_attr_next(attr, child)){ + printf("child:\n"); + _blobmsg_attr_dump(self, attr, child); + } + + printf("<<\n"); + } +} + +void blobmsg_dump(struct blob_buf *self){ + if(!self) return; + + printf("=========== blob ===========\n"); + _blobmsg_attr_dump(self, NULL, blob_buf_first(self)); + printf("============================\n"); +} + +int blobmsg_parse(struct blob_buf *buf, const struct blobmsg_policy *policy, int policy_len, + struct blob_attr **tb) { struct blobmsg_hdr *hdr; - struct blob_attr *attr; + struct blob_attr *pos; uint8_t *pslen; int i; + struct blob_attr *attr = blob_buf_first(buf); + //int len = blob_attr_len(attr); memset(tb, 0, policy_len * sizeof(*tb)); pslen = alloca(policy_len); @@ -143,21 +182,22 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, pslen[i] = strlen(policy[i].name); } - - __blob_buf_for_each_attr(attr, data, len) { - hdr = blob_attr_data(attr); + + //__blob_buf_for_each_attr(pos, attr, len) { + for(pos = blob_buf_first(buf); pos; pos = blob_attr_next(attr, pos)){ + hdr = blob_attr_data(pos); for (i = 0; i < policy_len; i++) { if (!policy[i].name) continue; if (policy[i].type != BLOBMSG_TYPE_UNSPEC && - blob_attr_id(attr) != policy[i].type) + blob_attr_id(pos) != policy[i].type) continue; if (blobmsg_namelen(hdr) != pslen[i]) continue; - if (!blobmsg_check_attr(attr, true)) + if (!blobmsg_check_attr(pos, true)) return -1; if (tb[i]) @@ -166,7 +206,7 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, if (strcmp(policy[i].name, (char *) hdr->name) != 0) continue; - tb[i] = attr; + tb[i] = pos; } } @@ -175,8 +215,7 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, static struct blob_attr * -blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len, void **data) -{ +blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len){ struct blob_attr *attr; struct blobmsg_hdr *hdr; int attrlen, namelen; @@ -194,8 +233,8 @@ blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len, v attr->id_len |= be32_to_cpu(BLOB_ATTR_EXTENDED); hdr = blob_attr_data(attr); hdr->namelen = cpu_to_be16(namelen); - strcpy((char *) hdr->name, (const char *)name); - pad_end = *data = blobmsg_data(attr); + strncpy((char *) hdr->name, (const char *)name, namelen); + pad_end = blobmsg_data(attr); pad_start = (char *) &hdr->name[namelen]; if (pad_start < pad_end) memset(pad_start, 0, pad_end - pad_start); @@ -203,35 +242,19 @@ blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len, v return attr; } -static inline int -attr_to_offset(struct blob_buf *buf, struct blob_attr *attr) -{ +static inline int attr_to_offset(struct blob_buf *buf, struct blob_attr *attr){ return (char *)attr - (char *) buf->buf; } - -void * -blobmsg_open_nested(struct blob_buf *buf, const char *name, bool array) -{ - struct blob_attr *head; +void *blobmsg_open_nested(struct blob_buf *buf, const char *name, bool array){ int type = array ? BLOBMSG_TYPE_ARRAY : BLOBMSG_TYPE_TABLE; - unsigned long offset = attr_to_offset(buf, buf->head); - void *data; - if (!name) name = ""; - - head = blobmsg_new(buf, type, name, 0, &data); - if (!head) - return NULL; - blob_attr_set_raw_len(buf->head, blob_attr_pad_len(buf->head) - blobmsg_hdrlen(strlen(name))); - buf->head = head; - return (void *)offset; + struct blob_attr *attr = blobmsg_new(buf, type, name, 0); + return (void*)blob_buf_attr_to_offset(buf, attr); } -void -blobmsg_vprintf(struct blob_buf *buf, const char *name, const char *format, va_list arg) -{ +void blobmsg_vprintf(struct blob_buf *buf, const char *name, const char *format, va_list arg){ va_list arg2; char cbuf; int len; @@ -239,9 +262,9 @@ blobmsg_vprintf(struct blob_buf *buf, const char *name, const char *format, va_l va_copy(arg2, arg); len = vsnprintf(&cbuf, sizeof(cbuf), format, arg2); va_end(arg2); - - vsprintf(blobmsg_alloc_string_buffer(buf, name, len + 1), format, arg); - blobmsg_add_string_buffer(buf); + + struct blob_attr *attr = blobmsg_new(buf, BLOBMSG_TYPE_STRING, name, len + 1); + vsprintf(blobmsg_data(attr), format, arg); } void @@ -254,25 +277,18 @@ blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, ...) va_end(ap); } -void * -blobmsg_alloc_string_buffer(struct blob_buf *buf, const char *name, unsigned int maxlen) -{ +struct blob_attr *blobmsg_alloc_string(struct blob_buf *buf, const char *name, unsigned int maxlen){ struct blob_attr *attr; - void *data_dest; - attr = blobmsg_new(buf, BLOBMSG_TYPE_STRING, name, maxlen, &data_dest); + attr = blobmsg_new(buf, BLOBMSG_TYPE_STRING, name, maxlen); if (!attr) return NULL; - blob_attr_set_raw_len(buf->head, blob_attr_pad_len(buf->head) - blob_attr_pad_len(attr)); - blob_attr_set_raw_len(attr, blob_attr_raw_len(attr) - maxlen); - - return data_dest; + return attr; } - +/* void * -blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen) -{ +blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen){ struct blob_attr *attr = blob_attr_next(buf->head); int offset = attr_to_offset(buf, blob_attr_next(buf->head)) + blob_attr_pad_len(attr); int required = maxlen - (buf->datalen - offset); @@ -286,10 +302,7 @@ blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen) out: return blobmsg_data(attr); } - -void -blobmsg_add_string_buffer(struct blob_buf *buf) -{ +void blobmsg_add_string_buffer(struct blob_buf *buf){ struct blob_attr *attr; int len, attrlen; @@ -302,20 +315,18 @@ blobmsg_add_string_buffer(struct blob_buf *buf) blob_attr_set_raw_len(buf->head, blob_attr_raw_len(buf->head) + blob_attr_pad_len(attr)); } - +*/ int blobmsg_add_field(struct blob_buf *buf, int type, const char *name, - const void *data, unsigned int len) -{ + const void *data, unsigned int len){ struct blob_attr *attr; - void *data_dest; - attr = blobmsg_new(buf, type, name, len, &data_dest); + attr = blobmsg_new(buf, type, name, len); if (!attr) return -1; if (len > 0) - memcpy(data_dest, data, len); + memcpy(blobmsg_data(attr), data, len); return 0; } diff --git a/blobmsg.h b/blobmsg.h index 5971cb5..f6ee614 100644 --- a/blobmsg.h +++ b/blobmsg.h @@ -69,7 +69,7 @@ static inline const char *blobmsg_name(const struct blob_attr *attr) static inline int blobmsg_type(const struct blob_attr *attr) { - if(!attr) return -1; + if(!attr) return BLOBMSG_TYPE_UNSPEC; return blob_attr_id(attr); } @@ -105,6 +105,7 @@ static inline int blobmsg_len(const struct blob_attr *attr) bool blobmsg_check_attr(const struct blob_attr *attr, bool name); bool blobmsg_check_attr_list(const struct blob_attr *attr, int type); +void blobmsg_dump(struct blob_buf *buf); /* * blobmsg_check_array: validate array/table and return size * @@ -113,8 +114,8 @@ bool blobmsg_check_attr_list(const struct blob_attr *attr, int type); */ int blobmsg_check_array(const struct blob_attr *attr, int type); -int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, - struct blob_attr **tb, void *data, unsigned int len); +int blobmsg_parse(struct blob_buf *self, const struct blobmsg_policy *policy, int policy_len, + struct blob_attr **tb); int blobmsg_parse_array(const struct blobmsg_policy *policy, int policy_len, struct blob_attr **tb, void *data, unsigned int len); @@ -201,11 +202,6 @@ blobmsg_close_table(struct blob_buf *buf, void *cookie) blob_buf_nest_end(buf, cookie); } -static inline int blobmsg_init(struct blob_buf *buf) -{ - return blob_buf_reset(buf, BLOBMSG_TYPE_TABLE); -} - static inline uint8_t blobmsg_get_u8(struct blob_attr *attr) { if(!attr) return 0; @@ -262,8 +258,8 @@ static inline char *blobmsg_get_string(struct blob_attr *attr) return (char *) blobmsg_data(attr); } -void *blobmsg_alloc_string_buffer(struct blob_buf *buf, const char *name, unsigned int maxlen); -void *blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen); +struct blob_attr *blobmsg_alloc_string(struct blob_buf *buf, const char *name, unsigned int maxlen); +//void *blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen); void blobmsg_add_string_buffer(struct blob_buf *buf); void blobmsg_vprintf(struct blob_buf *buf, const char *name, const char *format, va_list arg); @@ -278,6 +274,6 @@ void blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, pos = attr ? blobmsg_data(attr) : 0; \ rem > 0 && (blob_attr_pad_len(pos) <= rem) && \ (blob_attr_pad_len(pos) >= sizeof(struct blob_attr)); \ - rem -= blob_attr_pad_len(pos), pos = blob_attr_next(pos)) + rem -= blob_attr_pad_len(pos), pos = blob_attr_next(attr, pos)) #endif diff --git a/blobmsg_json.c b/blobmsg_json.c index 4239aaa..c1d21b1 100644 --- a/blobmsg_json.c +++ b/blobmsg_json.c @@ -205,14 +205,13 @@ static void blobmsg_format_string(struct strbuf *s, const char *str) blobmsg_puts(s, "\"", 1); } -static void blobmsg_format_json_list(struct strbuf *s, struct blob_attr *attr, int len, bool array); +static void blobmsg_format_json_list(struct strbuf *s, struct blob_attr *attr, bool array); static void blobmsg_format_element(struct strbuf *s, struct blob_attr *attr, bool array, bool head) { const char *data_str; char buf[32]; void *data; - int len; if (!blobmsg_check_attr(attr, false)) return; @@ -223,7 +222,6 @@ static void blobmsg_format_element(struct strbuf *s, struct blob_attr *attr, boo } data = blobmsg_data(attr); - len = blobmsg_data_len(attr); if (!head && s->custom_format) { data_str = s->custom_format(s->priv, attr); @@ -255,13 +253,13 @@ static void blobmsg_format_element(struct strbuf *s, struct blob_attr *attr, boo sprintf(buf, "%Le", unpack754_64(be64_to_cpu(*(uint64_t*)data))); break; case BLOBMSG_TYPE_STRING: - blobmsg_format_string(s, data); + blobmsg_format_string(s, blobmsg_data(attr)); return; case BLOBMSG_TYPE_ARRAY: - blobmsg_format_json_list(s, data, len, true); + blobmsg_format_json_list(s, attr, true); return; case BLOBMSG_TYPE_TABLE: - blobmsg_format_json_list(s, data, len, false); + blobmsg_format_json_list(s, attr, false); return; } @@ -269,16 +267,16 @@ out: blobmsg_puts(s, data_str, strlen(data_str)); } -static void blobmsg_format_json_list(struct strbuf *s, struct blob_attr *attr, int len, bool array) -{ +static void blobmsg_format_json_list(struct strbuf *s, struct blob_attr *attr, bool array){ struct blob_attr *pos; bool first = true; - int rem = len; blobmsg_puts(s, (array ? "[" : "{" ), 1); s->indent_level++; add_separator(s); - __blob_buf_for_each_attr(pos, attr, rem) { + + //__blob_buf_for_each_attr(pos, attr, rem) { + for(pos = blobmsg_data(attr); pos; pos = blob_attr_next(attr, pos)){ if (!first) { blobmsg_puts(s, ",", 1); add_separator(s); @@ -311,9 +309,9 @@ char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list, blobmsg_jso array = blob_attr_is_extended(attr) && blobmsg_type(attr) == BLOBMSG_TYPE_ARRAY; - + if (list) - blobmsg_format_json_list(&s, blobmsg_data(attr), blobmsg_data_len(attr), array); + blobmsg_format_json_list(&s, attr, array); else blobmsg_format_element(&s, attr, false, false); diff --git a/examples/simple.c b/examples/simple.c index b4b8a25..0eb6a12 100644 --- a/examples/simple.c +++ b/examples/simple.c @@ -93,7 +93,7 @@ static void dump_message(struct blob_buf *buf) { struct blob_attr *tb[ARRAY_SIZE(pol)]; - if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_attr_data(buf->head), blob_attr_len(buf->head)) != 0) { + if (blobmsg_parse(buf, pol, ARRAY_SIZE(pol), tb) != 0) { fprintf(stderr, "Parse failed\n"); return; } @@ -115,6 +115,8 @@ fill_message(struct blob_buf *buf) { void *tbl; + void *root = blobmsg_open_table(buf, NULL); + blobmsg_add_string(buf, "message", "Hello, world!"); tbl = blobmsg_open_table(buf, "testdata"); @@ -128,6 +130,8 @@ fill_message(struct blob_buf *buf) blobmsg_add_u32(buf, NULL, 2); blobmsg_add_f32(buf, NULL, 0.123); blobmsg_close_array(buf, tbl); + + blobmsg_close_table(buf, root); } int main(int argc, char **argv) @@ -136,10 +140,11 @@ int main(int argc, char **argv) blob_buf_init(&buf, 0, 0); for(int c = 0; c < 10; c++){ - blobmsg_init(&buf); + blob_buf_reset(&buf); fill_message(&buf); + //blobmsg_dump(&buf); dump_message(&buf); - char *json = blobmsg_format_json(buf.head, true); + char *json = blobmsg_format_json(blob_buf_first(&buf), false); printf("json: %s\n", json); free(json); } diff --git a/tests/random.c b/tests/random.c index 74dc47f..8c3391b 100644 --- a/tests/random.c +++ b/tests/random.c @@ -1,4 +1,4 @@ -#include +#include "blobpack.h" enum { FIELD_STRING, @@ -26,16 +26,15 @@ int main(int argc, char **argv){ struct blob_buf b; blob_buf_init(&b, 0, 0); - blobmsg_init(&b); blobmsg_add_string(&b, "string", "foo"); blobmsg_add_u32(&b, "int32", 123); - printf("raw len: %d\n", blob_attr_raw_len(b.head)); - blob_buf_init(&buf, data, 256); //b.buf, b.buflen); + printf("raw len: %u\n", (uint32_t)blob_buf_size(&b)); + blob_buf_init(&buf, data, 256); struct blob_attr *out[FIELD_MAX]; - if(-1 == blobmsg_parse(policy, FIELD_MAX, out, blob_attr_data(buf.head), blob_attr_len(buf.head))){ + if(-1 == blobmsg_parse(&buf, policy, FIELD_MAX, out)){ printf("Error parsing blob!\n"); }