refactor blobmsg creation (parsing may still be broken!)

This commit is contained in:
Martin Schröder 2015-12-11 15:01:34 +01:00
parent 4611dca32b
commit 03368cb350
9 changed files with 198 additions and 212 deletions

View file

@ -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

View file

@ -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.

153
blob.c
View file

@ -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");
}

58
blob.h
View file

@ -25,6 +25,7 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#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

129
blobmsg.c
View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -1,4 +1,4 @@
#include <blobpack.h>
#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");
}