mirror of
https://github.com/vale981/libblobpack
synced 2025-03-05 09:51:42 -05:00
refactor blobmsg creation (parsing may still be broken!)
This commit is contained in:
parent
4611dca32b
commit
03368cb350
9 changed files with 198 additions and 212 deletions
2
Makefile
2
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
|
||||
|
|
|
@ -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
153
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");
|
||||
}
|
||||
|
|
58
blob.h
58
blob.h
|
@ -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
129
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;
|
||||
}
|
||||
|
|
18
blobmsg.h
18
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue