refactor spaghetti blob code

This commit is contained in:
Martin Schröder 2015-12-06 20:54:33 +01:00
parent c0a6dd4d50
commit 4516817935
5 changed files with 65 additions and 61 deletions

View file

@ -1,4 +1,4 @@
all: libblobpack.a libblobpack.so simple-example
all: libblobpack.a libblobpack.so simple-example random-test
SOURCE:=$(wildcard *.c)
HEADERS:=$(wildcard *.h)
@ -15,8 +15,11 @@ libblobpack.so: $(OBJECTS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
simple-example: examples/simple.c libblob.a
$(CC) $(CFLAGS) -I. -o $@ $^ -L. -lblob -ljson-c
simple-example: examples/simple.c libblobpack.a
$(CC) $(CFLAGS) -I. -o $@ $^ -L. -lblobpack -ljson-c
random-test: tests/random.c libblobpack.a
$(CC) $(CFLAGS) -I. -o $@ $^ -L. -lblobpack -ljson-c
clean:
rm -f *.o *.a *.so
rm -f *.o *.a *.so *-example *-test

82
blob.c
View file

@ -18,23 +18,7 @@
#include "blob.h"
static bool
_blob_buf_grow(struct blob_buf *buf, int minlen)
{
struct blob_buf *new;
int delta = ((minlen / 256) + 1) * 256;
new = realloc(buf->buf, buf->buflen + delta);
if (new) {
buf->buf = new;
memset(buf->buf + buf->buflen, 0, delta);
buf->buflen += delta;
}
return !!new;
}
static void
blob_attr_init(struct blob_attr *attr, int id, unsigned int len)
{
static void blob_attr_init(struct blob_attr *attr, int id, unsigned int len){
memset(attr, 0, sizeof(struct blob_attr));
len &= BLOB_ATTR_LEN_MASK;
len |= (id << BLOB_ATTR_ID_SHIFT) & BLOB_ATTR_ID_MASK;
@ -44,33 +28,36 @@ blob_attr_init(struct blob_attr *attr, int id, unsigned int len)
static inline struct blob_attr *
_blob_buf_offset_to_attr(struct blob_buf *buf, int offset)
{
void *ptr = (char *)buf->buf + offset - BLOB_COOKIE;
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 + BLOB_COOKIE;
return (char *)attr - (char *) buf->buf;
}
bool
blob_buf_grow(struct blob_buf *buf, int required)
{
int offset_head = _blob_buf_attr_to_offset(buf, buf->head);
if (!buf->grow || !buf->grow(buf, required))
return false;
buf->head = _blob_buf_offset_to_attr(buf, offset_head);
return true;
//! Attepts to reallocate the buffer to fit the new payload data
bool blob_buf_grow(struct blob_buf *buf, int minlen){
char *new = 0;
int delta = ((minlen / 256) + 1) * 256;
new = realloc(buf->buf, buf->buflen + delta);
if (new) {
int offset_head = _blob_buf_attr_to_offset(buf, buf->head);
buf->buf = new;
memset(buf->buf + buf->buflen, 0, delta);
buf->buflen += delta;
buf->head = _blob_buf_offset_to_attr(buf, offset_head);
}
return !!new;
}
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);
int required = (offset - BLOB_COOKIE + sizeof(struct blob_attr) + payload) - buf->buflen;
int required = (offset + sizeof(struct blob_attr) + payload) - buf->buflen;
struct blob_attr *attr;
if (required > 0) {
@ -83,37 +70,42 @@ _blob_buf_add(struct blob_buf *buf, struct blob_attr *pos, int id, int payload)
blob_attr_init(attr, id, payload + sizeof(struct blob_attr));
blob_attr_fill_pad(attr);
return attr;
}
int blob_buf_reinit(struct blob_buf *buf, int type){
buf->grow = _blob_buf_grow;
if (_blob_buf_add(buf, buf->buf, type, 0) == NULL)
return -ENOMEM;
buf->buf = buf->head;
return 0;
}
int
blob_buf_init(struct blob_buf *buf)
{
int blob_buf_init(struct blob_buf *buf, const char *data, size_t size){
memset(buf, 0, sizeof(struct blob_buf));
return blob_buf_reinit(buf, 0);
buf->buflen = (size > 0)?size:256;
buf->buf = malloc(buf->buflen);
if(!buf->buf) return -ENOMEM;
if(data) {
memcpy(buf->buf, data, size);
buf->head = buf->buf;
} else {
memset(buf->buf, 0, buf->buflen);
buf->head = buf->buf;
blob_attr_init(buf->head, 0, sizeof(struct blob_attr));
blob_attr_fill_pad(buf->head);
}
return 0;
}
void
blob_buf_free(struct blob_buf *buf)
{
void blob_buf_free(struct blob_buf *buf){
free(buf->buf);
buf->buf = NULL;
buf->buflen = 0;
}
void
blob_attr_fill_pad(struct blob_attr *attr)
{
void blob_attr_fill_pad(struct blob_attr *attr) {
char *buf = (char *) attr;
int len = blob_attr_pad_len(attr);
int delta = len - blob_attr_raw_len(attr);

11
blob.h
View file

@ -28,7 +28,7 @@
#include "utils.h"
#define BLOB_COOKIE 0x01234567
//#define BLOB_COOKIE 0x01234567
enum {
BLOB_ATTR_UNSPEC,
@ -61,10 +61,9 @@ struct blob_attr_info {
};
struct blob_buf {
struct blob_attr *head;
bool (*grow)(struct blob_buf *buf, int minlen);
int buflen;
void *buf;
struct blob_attr *head; // pointer to current head
size_t buflen; // total length of buffer
void *buf; // raw buffer data
};
/*
@ -193,7 +192,7 @@ extern int blob_attr_parse(struct blob_attr *attr, struct blob_attr **data, cons
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);
extern int blob_buf_init(struct blob_buf *buf, const char *data, size_t size);
extern int blob_buf_reinit(struct blob_buf *buf, int id);
extern void blob_buf_free(struct blob_buf *buf);
extern bool blob_buf_grow(struct blob_buf *buf, int required);

View file

@ -204,7 +204,7 @@ blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len, v
static inline int
attr_to_offset(struct blob_buf *buf, struct blob_attr *attr)
{
return (char *)attr - (char *) buf->buf + BLOB_COOKIE;
return (char *)attr - (char *) buf->buf;
}
@ -272,7 +272,7 @@ void *
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) - BLOB_COOKIE;
int offset = attr_to_offset(buf, blob_attr_next(buf->head)) + blob_attr_pad_len(attr);
int required = maxlen - (buf->buflen - offset);
if (required <= 0)

View file

@ -53,23 +53,27 @@ static inline int blobmsg_hdrlen(unsigned int namelen)
static inline void blobmsg_clear_name(struct blob_attr *attr)
{
if(!attr) return;
struct blobmsg_hdr *hdr = (struct blobmsg_hdr *) blob_attr_data(attr);
hdr->name[0] = 0;
}
static inline const char *blobmsg_name(const struct blob_attr *attr)
{
if(!attr) return 0;
struct blobmsg_hdr *hdr = (struct blobmsg_hdr *) blob_attr_data(attr);
return (const char *) hdr->name;
}
static inline int blobmsg_type(const struct blob_attr *attr)
{
if(!attr) return -1;
return blob_attr_id(attr);
}
static inline void *blobmsg_data(const struct blob_attr *attr)
{
static inline void *blobmsg_data(const struct blob_attr *attr){
if(!attr) return 0;
struct blobmsg_hdr *hdr = (struct blobmsg_hdr *) blob_attr_data(attr);
char *data = (char *) blob_attr_data(attr);
@ -81,6 +85,7 @@ static inline void *blobmsg_data(const struct blob_attr *attr)
static inline int blobmsg_data_len(const struct blob_attr *attr)
{
if(!attr) return 0;
uint8_t *start, *end;
start = (uint8_t *) blob_attr_data(attr);
@ -91,6 +96,7 @@ static inline int blobmsg_data_len(const struct blob_attr *attr)
static inline int blobmsg_len(const struct blob_attr *attr)
{
if(!attr) return 0;
return blobmsg_data_len(attr);
}
@ -186,26 +192,31 @@ static inline int blobmsg_init(struct blob_buf *buf)
static inline uint8_t blobmsg_get_u8(struct blob_attr *attr)
{
if(!attr) return 0;
return *(uint8_t *) blobmsg_data(attr);
}
static inline bool blobmsg_get_bool(struct blob_attr *attr)
{
if(!attr) return 0;
return *(uint8_t *) blobmsg_data(attr);
}
static inline uint16_t blobmsg_get_u16(struct blob_attr *attr)
{
if(!attr) return 0;
return be16_to_cpu(*(uint16_t *) blobmsg_data(attr));
}
static inline uint32_t blobmsg_get_u32(struct blob_attr *attr)
{
if(!attr) return 0;
return be32_to_cpu(*(uint32_t *) blobmsg_data(attr));
}
static inline uint64_t blobmsg_get_u64(struct blob_attr *attr)
{
if(!attr) return 0;
uint32_t *ptr = (uint32_t *) blobmsg_data(attr);
uint64_t tmp = ((uint64_t) be32_to_cpu(ptr[0])) << 32;
tmp |= be32_to_cpu(ptr[1]);
@ -214,8 +225,7 @@ static inline uint64_t blobmsg_get_u64(struct blob_attr *attr)
static inline char *blobmsg_get_string(struct blob_attr *attr)
{
if (!attr)
return NULL;
if (!attr) return 0;
return (char *) blobmsg_data(attr);
}