(LibretroDB) Cleanups

This commit is contained in:
twinaphex 2015-01-27 04:02:10 +01:00
parent 8971f4538a
commit e212f61114
7 changed files with 916 additions and 879 deletions

View File

@ -1,123 +1,126 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <retro_inline.h>
#include "bintree.h" #include "bintree.h"
#if 0 static void *NIL_NODE = &NIL_NODE;
static int NIL_VALUE = 1;
#endif
static void * NIL_NODE = &NIL_NODE;
static struct bintree_node * new_nil_node(struct bintree_node * parent); static struct bintree_node *new_nil_node(struct bintree_node *parent);
void bintree_new( void bintree_new(struct bintree *t, bintree_cmp_func cmp,
struct bintree * t, void *ctx)
bintree_cmp_func cmp, {
void * ctx t->root = new_nil_node(NULL);
){ t->cmp = cmp;
t->root = new_nil_node(NULL); t->ctx = ctx;
t->cmp = cmp;
t->ctx = ctx;
} }
static struct bintree_node * new_nil_node(struct bintree_node * parent){ static struct bintree_node *new_nil_node(struct bintree_node *parent)
struct bintree_node * node = (struct bintree_node *)calloc(1, sizeof(struct bintree_node)); {
if (!node) struct bintree_node *node = (struct bintree_node *)calloc(1, sizeof(struct bintree_node));
return NULL;
node->value = NIL_NODE; if (!node)
node->parent = parent; return NULL;
node->left = NULL;
node->right = NULL; node->value = NIL_NODE;
return node; node->parent = parent;
node->left = NULL;
node->right = NULL;
return node;
} }
static inline int is_nil(const struct bintree_node * node){ static INLINE int is_nil(const struct bintree_node *node)
{
return node == NULL || node->value == NIL_NODE; return node == NULL || node->value == NIL_NODE;
} }
static int insert( static int insert(struct bintree *t, struct bintree_node *root,
struct bintree * t, void *value)
struct bintree_node * root, {
void * value int cmp_res = 0;
){
int cmp_res = 0; if (is_nil(root))
if (is_nil(root)) { {
root->left = new_nil_node(root); root->left = new_nil_node(root);
root->right = new_nil_node(root); root->right = new_nil_node(root);
if (!root->left || !root->right) {
if (root->left) { if (!root->left || !root->right)
free(root->left); {
root->left = NULL; if (root->left)
} {
if (root->right) { free(root->left);
free(root->right); root->left = NULL;
root->right = NULL; }
} if (root->right)
return -ENOMEM; {
} free(root->right);
root->value = value; root->right = NULL;
} else { }
cmp_res = t->cmp(root->value, value, t->ctx); return -ENOMEM;
if (cmp_res > 0) }
return insert(t, root->left, value); root->value = value;
else if (cmp_res < 0)
return insert(t, root->right, value); return 0;
else }
return -EINVAL;
} cmp_res = t->cmp(root->value, value, t->ctx);
return 0;
if (cmp_res > 0)
return insert(t, root->left, value);
else if (cmp_res < 0)
return insert(t, root->right, value);
return -EINVAL;
} }
int bintree_insert( int bintree_insert(struct bintree *t, void *value)
struct bintree * t, {
void * value return insert(t, t->root, value);
){
return insert(t, t->root, value);
} }
static int _bintree_iterate( static int _bintree_iterate(struct bintree_node *n,
struct bintree_node * n, bintree_iter_cb cb, void *ctx)
bintree_iter_cb cb, {
void * ctx int rv;
){
int rv;
if (is_nil(n))
return 0;
else {
if ((rv = _bintree_iterate(n->left, cb, ctx)) != 0)
return rv;
if ((rv = cb(n->value, ctx)) != 0)
return rv;
if ((rv = _bintree_iterate(n->right, cb, ctx)) != 0)
return rv;
}
return 0; if (is_nil(n))
return 0;
if ((rv = _bintree_iterate(n->left, cb, ctx)) != 0)
return rv;
if ((rv = cb(n->value, ctx)) != 0)
return rv;
if ((rv = _bintree_iterate(n->right, cb, ctx)) != 0)
return rv;
return 0;
} }
int bintree_iterate( int bintree_iterate(const struct bintree *t, bintree_iter_cb cb,
const struct bintree * t, void *ctx)
bintree_iter_cb cb, {
void * ctx return _bintree_iterate(t->root, cb, ctx);
){
return _bintree_iterate(t->root, cb, ctx);
} }
static void bintree_free_node(struct bintree_node * n){ static void bintree_free_node(struct bintree_node *n)
if (n == NULL) {
return; if (!n)
return;
if (n->value == NIL_NODE) { if (n->value == NIL_NODE)
free(n); {
return; free(n);
} return;
n->value = NULL; }
bintree_free_node(n->left); n->value = NULL;
bintree_free_node(n->right); bintree_free_node(n->left);
free(n); bintree_free_node(n->right);
free(n);
} }
void bintree_free(struct bintree * t){ void bintree_free(struct bintree *t)
bintree_free_node(t->root); {
bintree_free_node(t->root);
} }

View File

@ -328,13 +328,18 @@ retry:
**/ **/
void libretrodb_cursor_close(libretrodb_cursor_t *cursor) void libretrodb_cursor_close(libretrodb_cursor_t *cursor)
{ {
if (!cursor)
return;
close(cursor->fd); close(cursor->fd);
cursor->is_valid = 0; cursor->is_valid = 0;
cursor->fd = -1; cursor->fd = -1;
cursor->eof = 1; cursor->eof = 1;
cursor->db = NULL; cursor->db = NULL;
if (cursor->query) if (cursor->query)
libretrodb_query_free(cursor->query); libretrodb_query_free(cursor->query);
cursor->query = NULL; cursor->query = NULL;
} }
@ -348,26 +353,23 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor)
* *
* Returns: 0 if successful, otherwise negative. * Returns: 0 if successful, otherwise negative.
**/ **/
int libretrodb_cursor_open( int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor,
libretrodb_t *db, libretrodb_query_t *q)
libretrodb_cursor_t *cursor,
libretrodb_query_t *q
)
{ {
cursor->fd = dup(db->fd); cursor->fd = dup(db->fd);
if (cursor->fd == -1) if (cursor->fd == -1)
return -errno; return -errno;
cursor->db = db; cursor->db = db;
cursor->is_valid = 1; cursor->is_valid = 1;
libretrodb_cursor_reset(cursor); libretrodb_cursor_reset(cursor);
cursor->query = q; cursor->query = q;
if (q) if (q)
libretrodb_query_inc_ref(q); libretrodb_query_inc_ref(q);
return 0; return 0;
} }
static int node_iter(void * value, void * ctx) static int node_iter(void * value, void * ctx)

View File

@ -103,5 +103,7 @@ int main(int argc, char ** argv)
printf("Unknown command %s\n", argv[2]); printf("Unknown command %s\n", argv[2]);
return 1; return 1;
} }
libretrodb_close(&db); libretrodb_close(&db);
return 1;
} }

View File

@ -27,14 +27,14 @@ struct buffer
}; };
/* Errors */ /* Errors */
static void raise_too_many_arguments(const char ** error) static void raise_too_many_arguments(const char **error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(tmp_error_buff, MAX_ERROR_LEN,
"Too many arguments in function call."); "Too many arguments in function call.");
*error = tmp_error_buff; *error = tmp_error_buff;
} }
static void raise_expected_number(off_t where, const char ** error) static void raise_expected_number(off_t where, const char **error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(tmp_error_buff, MAX_ERROR_LEN,
#ifdef _WIN32 #ifdef _WIN32
@ -161,7 +161,6 @@ static void argument_free(struct argument * arg)
{ {
rmsgpack_dom_value_free(&arg->value); rmsgpack_dom_value_free(&arg->value);
return; return;
} }
for (i = 0; i < arg->invocation.argc; i++) for (i = 0; i < arg->invocation.argc; i++)
@ -403,11 +402,12 @@ struct registered_func registered_functions[100] = {
{NULL, NULL} {NULL, NULL}
}; };
static struct buffer chomp(struct buffer buff) { static struct buffer chomp(struct buffer buff)
off_t i = 0; {
off_t i = 0;
(void)i; (void)i;
for (; buff.offset < buff.len && isspace(buff.data[buff.offset]); buff.offset++) ; for (; buff.offset < buff.len && isspace(buff.data[buff.offset]); buff.offset++);
return buff; return buff;
} }
static struct buffer expect_char(struct buffer buff, static struct buffer expect_char(struct buffer buff,
@ -463,12 +463,11 @@ static void peek_char(struct buffer buff, char * c, const char ** error)
*c = buff.data[buff.offset]; *c = buff.data[buff.offset];
} }
static struct buffer get_char( static struct buffer get_char(struct buffer buff, char * c,
struct buffer buff, const char ** error)
char * c, {
const char ** error if (is_eot(buff))
) { {
if (is_eot(buff)) {
raise_unexpected_eof(buff.offset, error); raise_unexpected_eof(buff.offset, error);
return buff; return buff;
} }
@ -481,35 +480,36 @@ static struct buffer parse_string(
struct buffer buff, struct buffer buff,
struct rmsgpack_dom_value * value, struct rmsgpack_dom_value * value,
const char ** error const char ** error
) { )
char terminator = '\0'; {
char c = '\0'; char terminator = '\0';
const char * str_start; char c = '\0';
const char * str_start;
(void)c; (void)c;
buff = get_char(buff, &terminator, error); buff = get_char(buff, &terminator, error);
if (*error) if (*error)
return buff; return buff;
if (terminator != '"' && terminator != '\'') if (terminator != '"' && terminator != '\'')
{ {
buff.offset--; buff.offset--;
raise_expected_string(buff.offset, error); raise_expected_string(buff.offset, error);
} }
str_start = buff.data + buff.offset; str_start = buff.data + buff.offset;
buff = get_char(buff, &c, error); buff = get_char(buff, &c, error);
while (!*error) while (!*error)
{ {
if (c == terminator) if (c == terminator)
break; break;
buff = get_char(buff, &c, error); buff = get_char(buff, &c, error);
} }
if (!*error) if (!*error)
{ {
value->type = RDT_STRING; value->type = RDT_STRING;
value->string.len = (buff.data + buff.offset) - str_start - 1; value->string.len = (buff.data + buff.offset) - str_start - 1;
@ -524,7 +524,7 @@ static struct buffer parse_string(
value->string.len value->string.len
); );
} }
return buff; return buff;
} }
static struct buffer parse_integer(struct buffer buff, static struct buffer parse_integer(struct buffer buff,
@ -539,9 +539,7 @@ static struct buffer parse_integer(struct buffer buff,
"%lld", "%lld",
#endif #endif
(signed long long*)&value->int_) == 0) (signed long long*)&value->int_) == 0)
{
raise_expected_number(buff.offset, error); raise_expected_number(buff.offset, error);
}
else else
{ {
while (isdigit(buff.data[buff.offset])) while (isdigit(buff.data[buff.offset]))
@ -550,31 +548,32 @@ static struct buffer parse_integer(struct buffer buff,
return buff; return buff;
} }
static struct buffer parse_value( static struct buffer parse_value(struct buffer buff,
struct buffer buff, struct rmsgpack_dom_value * value, const char ** error)
struct rmsgpack_dom_value * value, {
const char ** error buff = chomp(buff);
) { if (peek(buff, "nil"))
buff = chomp(buff); {
if (peek(buff, "nil")) { buff.offset += strlen("nil");
buff.offset += strlen("nil"); value->type = RDT_NULL;
value->type = RDT_NULL; }
} else if (peek(buff, "true")) { else if (peek(buff, "true"))
buff.offset += strlen("true"); {
value->type = RDT_BOOL; buff.offset += strlen("true");
value->bool_ = 1; value->type = RDT_BOOL;
} else if (peek(buff, "false")) { value->bool_ = 1;
buff.offset += strlen("false"); }
value->type = RDT_BOOL; else if (peek(buff, "false"))
value->bool_ = 0; {
//} else if (peek(buff, "[")) { buff.offset += strlen("false");
//} else if (peek(buff, "b\"") || peek(buff, "b'")) { value->type = RDT_BOOL;
} else if (peek(buff, "\"") || peek(buff, "'")) { value->bool_ = 0;
buff = parse_string(buff, value, error); }
} else if (isdigit(buff.data[buff.offset])) { else if (peek(buff, "\"") || peek(buff, "'"))
buff = parse_integer(buff, value, error); buff = parse_string(buff, value, error);
} else if (isdigit(buff.data[buff.offset]))
return buff; buff = parse_integer(buff, value, error);
return buff;
} }
static struct buffer get_ident(struct buffer buff, const char ** ident, static struct buffer get_ident(struct buffer buff, const char ** ident,
@ -617,26 +616,27 @@ static struct buffer parse_method_call(
struct buffer buff, struct buffer buff,
struct invocation * invocation, struct invocation * invocation,
const char ** error const char ** error
) { )
const char * func_name; {
size_t func_name_len; const char * func_name;
struct argument args[MAX_ARGS]; size_t func_name_len;
unsigned argi = 0; struct argument args[MAX_ARGS];
unsigned i; unsigned argi = 0;
struct registered_func * rf = registered_functions; unsigned i;
struct registered_func * rf = registered_functions;
invocation->func = NULL; invocation->func = NULL;
buff = get_ident(buff, &func_name, &func_name_len, error); buff = get_ident(buff, &func_name, &func_name_len, error);
if (*error) if (*error)
goto clean; goto clean;
buff = chomp(buff); buff = chomp(buff);
buff = expect_char(buff, '(', error); buff = expect_char(buff, '(', error);
if (*error) if (*error)
goto clean; goto clean;
while (rf->name) while (rf->name)
{ {
if (strncmp(rf->name, func_name, func_name_len) == 0) if (strncmp(rf->name, func_name, func_name_len) == 0)
{ {
@ -646,15 +646,15 @@ static struct buffer parse_method_call(
rf++; rf++;
} }
if (!invocation->func) if (!invocation->func)
{ {
raise_unknown_function(buff.offset, func_name, raise_unknown_function(buff.offset, func_name,
func_name_len, error); func_name_len, error);
goto clean; goto clean;
} }
buff = chomp(buff); buff = chomp(buff);
while (!peek(buff, ")")) while (!peek(buff, ")"))
{ {
if (argi >= MAX_ARGS) if (argi >= MAX_ARGS)
{ {
@ -678,27 +678,29 @@ static struct buffer parse_method_call(
} }
buff = chomp(buff); buff = chomp(buff);
} }
buff = expect_char(buff, ')', error); buff = expect_char(buff, ')', error);
if (*error) if (*error)
goto clean; goto clean;
invocation->argc = argi; invocation->argc = argi;
invocation->argv = (struct argument*)malloc(sizeof(struct argument) * argi); invocation->argv = (struct argument*)
malloc(sizeof(struct argument) * argi);
if (!invocation->argv) if (!invocation->argv)
{ {
raise_enomem(error); raise_enomem(error);
goto clean; goto clean;
} }
memcpy(invocation->argv, args, sizeof(struct argument) * argi); memcpy(invocation->argv, args,
sizeof(struct argument) * argi);
goto success; goto success;
clean: clean:
for (i = 0; i < argi; i++) for (i = 0; i < argi; i++)
argument_free(&args[i]); argument_free(&args[i]);
success: success:
return buff; return buff;
} }
static struct buffer parse_argument(struct buffer buff, static struct buffer parse_argument(struct buffer buff,
@ -749,6 +751,7 @@ static struct buffer parse_table(struct buffer buff,
goto clean; goto clean;
buff = chomp(buff); buff = chomp(buff);
while (!peek(buff, "}")) while (!peek(buff, "}"))
{ {
if (argi >= MAX_ARGS) if (argi >= MAX_ARGS)
@ -825,14 +828,16 @@ static struct buffer parse_table(struct buffer buff,
invocation->func = all_map; invocation->func = all_map;
invocation->argc = argi; invocation->argc = argi;
invocation->argv = (struct argument*)malloc(sizeof(struct argument) * argi); invocation->argv = (struct argument*)
malloc(sizeof(struct argument) * argi);
if (!invocation->argv) if (!invocation->argv)
{ {
raise_enomem(error); raise_enomem(error);
goto clean; goto clean;
} }
memcpy(invocation->argv, args, sizeof(struct argument) * argi); memcpy(invocation->argv, args,
sizeof(struct argument) * argi);
goto success; goto success;
clean: clean:
@ -874,6 +879,7 @@ void *libretrodb_query_compile(libretrodb_t * db,
*error = NULL; *error = NULL;
buff = chomp(buff); buff = chomp(buff);
if (peek(buff, "{")) if (peek(buff, "{"))
{ {
buff = parse_table(buff, &q->root, error); buff = parse_table(buff, &q->root, error);

View File

@ -76,291 +76,313 @@ int rmsgpack_write_array_header(int fd, uint32_t size)
return -errno; return -errno;
return sizeof(int8_t) + sizeof(uint16_t); return sizeof(int8_t) + sizeof(uint16_t);
} }
if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1)
return -errno;
tmp_i32 = httobe32(size);
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1)
return -errno;
return sizeof(int8_t) + sizeof(uint32_t);
}
int rmsgpack_write_map_header(int fd, uint32_t size)
{
uint16_t tmp_i16;
uint32_t tmp_i32;
if (size < 16)
{
size = (size | MPF_FIXMAP);
if (write(fd, &size, sizeof(int8_t)) == -1)
return -errno;
return sizeof(int8_t);
}
else if (size < (uint16_t)size)
{
if (write(fd, &MPF_MAP16, sizeof(MPF_MAP16)) == -1)
return -errno;
tmp_i16 = httobe16(size);
if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1)
return -errno;
return sizeof(uint8_t) + sizeof(uint16_t);
}
tmp_i32 = httobe32(size);
if (write(fd, &MPF_MAP32, sizeof(MPF_MAP32)) == -1)
return -errno;
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1)
return -errno;
return sizeof(int8_t) + sizeof(uint32_t);
}
int rmsgpack_write_string(int fd, const char *s, uint32_t len)
{
int8_t fixlen = 0;
uint16_t tmp_i16;
uint32_t tmp_i32;
int written = sizeof(int8_t);
if (len < 32)
{
fixlen = len | MPF_FIXSTR;
if (write(fd, &fixlen, sizeof(int8_t)) == -1)
return -errno;
}
else if (len < 1<<8)
{
if (write(fd, &MPF_STR8, sizeof(MPF_STR8)) == -1)
return -errno;
if (write(fd, &len, sizeof(uint8_t)) == -1)
return -errno;
written += sizeof(uint8_t);
}
else if (len < 1<<16)
{
if (write(fd, &MPF_STR16, sizeof(MPF_STR16)) == -1)
return -errno;
tmp_i16 = httobe16(len);
if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1)
return -errno;
written += sizeof(uint16_t);
}
else else
{ {
if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1) if (write(fd, &MPF_STR32, sizeof(MPF_STR32)) == -1)
return -errno; return -errno;
tmp_i32 = httobe32(size); tmp_i32 = httobe32(len);
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1)
return -errno; return -errno;
return sizeof(int8_t) + sizeof(uint32_t); written += sizeof(uint32_t);
} }
if (write(fd, s, len) == -1)
return -errno;
written += len;
return written;
} }
int rmsgpack_write_map_header( int rmsgpack_write_bin(int fd, const void *s, uint32_t len)
int fd, {
uint32_t size uint16_t tmp_i16;
){ uint32_t tmp_i32;
uint16_t tmp_i16; int written = sizeof(int8_t);
uint32_t tmp_i32; if (len == (uint8_t)len)
if (size < 16) { {
size = (size | MPF_FIXMAP); if (write(fd, &MPF_BIN8, sizeof(MPF_BIN8)) == -1)
if (write(fd, &size, sizeof(int8_t)) == -1) return -errno;
return -errno; if (write(fd, &len, sizeof(uint8_t)) == -1)
return sizeof(int8_t); return -errno;
} else if (size < (uint16_t)size) { written += sizeof(uint8_t);
if (write(fd, &MPF_MAP16, sizeof(MPF_MAP16)) == -1) }
return -errno; else if (len == (uint16_t)len)
tmp_i16 = httobe16(size); {
if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1) if (write(fd, &MPF_BIN16, sizeof(MPF_BIN16)) == -1)
return -errno; return -errno;
return sizeof(uint8_t) + sizeof(uint16_t); tmp_i16 = httobe16(len);
} else { if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1)
tmp_i32 = httobe32(size); return -errno;
if (write(fd, &MPF_MAP32, sizeof(MPF_MAP32)) == -1) written += sizeof(uint16_t);
return -errno; }
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1) else
return -errno; {
return sizeof(int8_t) + sizeof(uint32_t); if (write(fd, &MPF_BIN32, sizeof(MPF_BIN32)) == -1)
} return -errno;
tmp_i32 = httobe32(len);
if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1)
return -errno;
written += sizeof(uint32_t);
}
if (write(fd, s, len) == -1)
return -errno;
written += len;
return 0;
} }
int rmsgpack_write_string( int rmsgpack_write_nil(int fd)
int fd, {
const char * s, if (write(fd, &MPF_NIL, sizeof(MPF_NIL)) == -1)
uint32_t len return -errno;
){ return sizeof(uint8_t);
int8_t fixlen = 0;
uint16_t tmp_i16;
uint32_t tmp_i32;
int written = sizeof(int8_t);
if (len < 32) {
fixlen = len | MPF_FIXSTR;
if (write(fd, &fixlen, sizeof(int8_t)) == -1)
return -errno;
} else if (len < 1<<8) {
if (write(fd, &MPF_STR8, sizeof(MPF_STR8)) == -1)
return -errno;
if (write(fd, &len, sizeof(uint8_t)) == -1)
return -errno;
written += sizeof(uint8_t);
} else if (len < 1<<16) {
if (write(fd, &MPF_STR16, sizeof(MPF_STR16)) == -1)
return -errno;
tmp_i16 = httobe16(len);
if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1)
return -errno;
written += sizeof(uint16_t);
} else {
if (write(fd, &MPF_STR32, sizeof(MPF_STR32)) == -1)
return -errno;
tmp_i32 = httobe32(len);
if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1)
return -errno;
written += sizeof(uint32_t);
}
if (write(fd, s, len) == -1)
return -errno;
written += len;
return written;
} }
int rmsgpack_write_bin( int rmsgpack_write_bool(int fd, int value)
int fd, {
const void * s, if (value)
uint32_t len {
){ if (write(fd, &MPF_TRUE, sizeof(MPF_TRUE)) == -1)
uint16_t tmp_i16; return -errno;
uint32_t tmp_i32; }
int written = sizeof(int8_t); else
if (len == (uint8_t)len) { {
if (write(fd, &MPF_BIN8, sizeof(MPF_BIN8)) == -1) if (write(fd, &MPF_FALSE, sizeof(MPF_FALSE)) == -1)
return -errno; return -errno;
if (write(fd, &len, sizeof(uint8_t)) == -1) }
return -errno; return sizeof(uint8_t);
written += sizeof(uint8_t);
} else if (len == (uint16_t)len) {
if (write(fd, &MPF_BIN16, sizeof(MPF_BIN16)) == -1)
return -errno;
tmp_i16 = httobe16(len);
if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1)
return -errno;
written += sizeof(uint16_t);
} else {
if (write(fd, &MPF_BIN32, sizeof(MPF_BIN32)) == -1)
return -errno;
tmp_i32 = httobe32(len);
if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1)
return -errno;
written += sizeof(uint32_t);
}
if (write(fd, s, len) == -1)
return -errno;
written += len;
return 0;
} }
int rmsgpack_write_nil(int fd){ int rmsgpack_write_int(int fd, int64_t value)
if (write(fd, &MPF_NIL, sizeof(MPF_NIL)) == -1) {
return -errno; int16_t tmp_i16;
return sizeof(uint8_t); int32_t tmp_i32;
uint8_t tmpval = 0;
int written = sizeof(uint8_t);
if (value >=0 && value < 128)
{
if (write(fd, &value, sizeof(int8_t)) == -1)
return -errno;
}
else if (value < 0 && value > -32)
{
tmpval = (value) | 0xe0;
if (write(fd, &tmpval, sizeof(uint8_t)) == -1)
return -errno;
}
else if (value == (int8_t)value)
{
if (write(fd, &MPF_INT8, sizeof(MPF_INT8)) == -1)
return -errno;
if (write(fd, &value, sizeof(int8_t)) == -1)
return -errno;
written += sizeof(int8_t);
}
else if (value == (int16_t)value)
{
if (write(fd, &MPF_INT16, sizeof(MPF_INT16)) == -1)
return -errno;
tmp_i16 = httobe16(value);
if (write(fd, &tmp_i16, sizeof(int16_t)) == -1)
return -errno;
written += sizeof(int16_t);
}
else if (value == (int32_t)value)
{
if (write(fd, &MPF_INT32, sizeof(MPF_INT32)) == -1)
return -errno;
tmp_i32 = httobe32(value);
if (write(fd, &tmp_i32, sizeof(int32_t)) == -1)
return -errno;
written += sizeof(int32_t);
}
else
{
if (write(fd, &MPF_INT64, sizeof(MPF_INT64)) == -1)
return -errno;
value = httobe64(value);
if (write(fd, &value, sizeof(int64_t)) == -1)
return -errno;
written += sizeof(int64_t);
}
return written;
} }
int rmsgpack_write_bool( int rmsgpack_write_uint(int fd, uint64_t value)
int fd, {
int value uint16_t tmp_i16;
){ uint32_t tmp_i32;
if (value) { int written = sizeof(uint8_t);
if (write(fd, &MPF_TRUE, sizeof(MPF_TRUE)) == -1)
return -errno; if (value == (uint8_t)value)
} else { {
if (write(fd, &MPF_FALSE, sizeof(MPF_FALSE)) == -1) if (write(fd, &MPF_UINT8, sizeof(MPF_UINT8)) == -1)
return -errno; return -errno;
}
return sizeof(uint8_t); if (write(fd, &value, sizeof(uint8_t)) == -1)
return -errno;
written += sizeof(uint8_t);
}
else if (value == (uint16_t)value)
{
if (write(fd, &MPF_UINT16, sizeof(MPF_UINT16)) == -1)
return -errno;
tmp_i16 = httobe16(value);
if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1)
return -errno;
written += sizeof(uint16_t);
}
else if (value == (uint32_t)value)
{
if (write(fd, &MPF_UINT32, sizeof(MPF_UINT32)) == -1)
return -errno;
tmp_i32 = httobe32(value);
if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1)
return -errno;
written += sizeof(uint32_t);
}
else
{
if (write(fd, &MPF_UINT64, sizeof(MPF_UINT64)) == -1)
return -errno;
value = httobe64(value);
if (write(fd, &value, sizeof(uint64_t)) == -1)
return -errno;
written += sizeof(uint64_t);
}
return written;
} }
int rmsgpack_write_int( static int read_uint(int fd, uint64_t *out, size_t size)
int fd, {
int64_t value uint64_t tmp;
){
uint8_t tmpval = 0;
int16_t tmp_i16; if (read(fd, &tmp, size) == -1)
int32_t tmp_i32; return -errno;
int written = sizeof(uint8_t);
if (value >=0 && value < 128) {
if (write(fd, &value, sizeof(int8_t)) == -1)
return -errno;
} else if (value < 0 && value > -32) {
tmpval = (value) | 0xe0;
if (write(fd, &tmpval, sizeof(uint8_t)) == -1)
return -errno;
} else if (value == (int8_t)value) {
if (write(fd, &MPF_INT8, sizeof(MPF_INT8)) == -1)
return -errno;
if (write(fd, &value, sizeof(int8_t)) == -1) switch (size)
return -errno; {
written += sizeof(int8_t); case 1:
} else if (value == (int16_t)value) { *out = *(uint8_t *)(&tmp);
if (write(fd, &MPF_INT16, sizeof(MPF_INT16)) == -1) break;
return -errno; case 2:
*out = betoht16(tmp);
tmp_i16 = httobe16(value); break;
if (write(fd, &tmp_i16, sizeof(int16_t)) == -1) case 4:
return -errno; *out = betoht32(tmp);
written += sizeof(int16_t); break;
} else if (value == (int32_t)value) { case 8:
if (write(fd, &MPF_INT32, sizeof(MPF_INT32)) == -1) *out = betoht64(tmp);
return -errno; break;
}
tmp_i32 = httobe32(value); return 0;
if (write(fd, &tmp_i32, sizeof(int32_t)) == -1)
return -errno;
written += sizeof(int32_t);
} else {
if (write(fd, &MPF_INT64, sizeof(MPF_INT64)) == -1)
return -errno;
value = httobe64(value);
if (write(fd, &value, sizeof(int64_t)) == -1)
return -errno;
written += sizeof(int64_t);
}
return written;
} }
int rmsgpack_write_uint( static int read_int(int fd, int64_t *out, size_t size)
int fd, {
uint64_t value uint8_t tmp8 = 0;
){ uint16_t tmp16;
uint16_t tmp_i16; uint32_t tmp32;
uint32_t tmp_i32; uint64_t tmp64;
int written = sizeof(uint8_t); if (read(fd, &tmp64, size) == -1)
return -errno;
if (value == (uint8_t)value) { (void)tmp8;
if (write(fd, &MPF_UINT8, sizeof(MPF_UINT8)) == -1)
return -errno;
if (write(fd, &value, sizeof(uint8_t)) == -1) switch (size)
return -errno; {
written += sizeof(uint8_t); case 1:
} else if (value == (uint16_t)value) { *out = *((int8_t *)(&tmp64));
if (write(fd, &MPF_UINT16, sizeof(MPF_UINT16)) == -1) break;
return -errno; case 2:
tmp16 = betoht16(tmp64);
tmp_i16 = httobe16(value); *out = *((int16_t *)(&tmp16));
if (write(fd, &tmp_i16, sizeof(uint16_t)) == -1) break;
return -errno; case 4:
written += sizeof(uint16_t); tmp32 = betoht32(tmp64);
} else if (value == (uint32_t)value) { *out = *((int32_t *)(&tmp32));
if (write(fd, &MPF_UINT32, sizeof(MPF_UINT32)) == -1) break;
return -errno; case 8:
tmp64 = betoht64(tmp64);
tmp_i32 = httobe32(value); *out = *((int64_t *)(&tmp64));
if (write(fd, &tmp_i32, sizeof(uint32_t)) == -1) break;
return -errno; }
written += sizeof(uint32_t); return 0;
} else {
if (write(fd, &MPF_UINT64, sizeof(MPF_UINT64)) == -1)
return -errno;
value = httobe64(value);
if (write(fd, &value, sizeof(uint64_t)) == -1)
return -errno;
written += sizeof(uint64_t);
}
return written;
}
static int read_uint(
int fd,
uint64_t * out,
size_t size
){
uint64_t tmp;
if (read(fd, &tmp, size) == -1)
return -errno;
switch (size) {
case 1:
*out = *(uint8_t *)(&tmp);
break;
case 2:
*out = betoht16(tmp);
break;
case 4:
*out = betoht32(tmp);
break;
case 8:
*out = betoht64(tmp);
break;
}
return 0;
}
static int read_int(
int fd,
int64_t * out,
size_t size
){
uint8_t tmp8 = 0;
uint16_t tmp16;
uint32_t tmp32;
uint64_t tmp64;
if (read(fd, &tmp64, size) == -1)
return -errno;
(void)tmp8;
switch (size) {
case 1:
*out = *((int8_t *)(&tmp64));
break;
case 2:
tmp16 = betoht16(tmp64);
*out = *((int16_t *)(&tmp16));
break;
case 4:
tmp32 = betoht32(tmp64);
*out = *((int32_t *)(&tmp32));
break;
case 8:
tmp64 = betoht64(tmp64);
*out = *((int64_t *)(&tmp64));
break;
}
return 0;
} }
static int read_buff( static int read_buff(
@ -374,7 +396,8 @@ static int read_buff(
return -errno; return -errno;
*pbuff = (char *)calloc(tmp_len + 1, sizeof(char)); *pbuff = (char *)calloc(tmp_len + 1, sizeof(char));
if (read(fd, *pbuff, tmp_len) == -1) { if (read(fd, *pbuff, tmp_len) == -1)
{
free(*pbuff); free(*pbuff);
return -errno; return -errno;
} }
@ -391,12 +414,12 @@ static int read_map(
int rv; int rv;
unsigned i; unsigned i;
if ( if (callbacks->read_map_start &&
callbacks->read_map_start &&
(rv = callbacks->read_map_start(len, data)) < 0) (rv = callbacks->read_map_start(len, data)) < 0)
return rv; return rv;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++)
{
if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) if ((rv = rmsgpack_read(fd, callbacks, data)) < 0)
return rv; return rv;
if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) if ((rv = rmsgpack_read(fd, callbacks, data)) < 0)
@ -411,136 +434,147 @@ static int read_array(
uint32_t len, uint32_t len,
struct rmsgpack_read_callbacks * callbacks, struct rmsgpack_read_callbacks * callbacks,
void * data void * data
){ )
int rv; {
unsigned i; int rv;
unsigned i;
if ( if (callbacks->read_array_start &&
callbacks->read_array_start && (rv = callbacks->read_array_start(len, data)) < 0)
(rv = callbacks->read_array_start(len, data)) < 0) return rv;
return rv;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++)
if ((rv = rmsgpack_read(fd, callbacks, data)) < 0) {
return rv; if ((rv = rmsgpack_read(fd, callbacks, data)) < 0)
} return rv;
}
return 0; return 0;
} }
int rmsgpack_read( int rmsgpack_read(int fd, struct rmsgpack_read_callbacks * callbacks,
int fd, void * data)
struct rmsgpack_read_callbacks * callbacks, {
void * data int rv;
){ uint64_t tmp_len = 0;
int rv; uint64_t tmp_uint = 0;
uint64_t tmp_len = 0; int64_t tmp_int = 0;
uint64_t tmp_uint = 0; uint8_t type = 0;
int64_t tmp_int = 0; char * buff = NULL;
uint8_t type = 0; if (read(fd, &type, sizeof(uint8_t)) == -1)
char * buff = NULL; return -errno;
if (read(fd, &type, sizeof(uint8_t)) == -1)
return -errno;
if (type < MPF_FIXMAP) { if (type < MPF_FIXMAP)
if (!callbacks->read_int) {
return 0; if (!callbacks->read_int)
return callbacks->read_int(type, data); return 0;
} else if (type < MPF_FIXARRAY) { return callbacks->read_int(type, data);
tmp_len = type - MPF_FIXMAP; }
return read_map(fd, tmp_len, callbacks, data); else if (type < MPF_FIXARRAY)
} else if (type < MPF_FIXSTR) { {
tmp_len = type - MPF_FIXARRAY; tmp_len = type - MPF_FIXMAP;
return read_array(fd, tmp_len, callbacks, data); return read_map(fd, tmp_len, callbacks, data);
} else if (type < MPF_NIL) { }
tmp_len = type - MPF_FIXSTR; else if (type < MPF_FIXSTR)
buff = (char *)calloc(tmp_len + 1, sizeof(char)); {
if (!buff) tmp_len = type - MPF_FIXARRAY;
return -ENOMEM; return read_array(fd, tmp_len, callbacks, data);
if (read(fd, buff, tmp_len) == -1) { }
free(buff); else if (type < MPF_NIL)
return -errno; {
} tmp_len = type - MPF_FIXSTR;
buff[tmp_len] = '\0'; buff = (char *)calloc(tmp_len + 1, sizeof(char));
if (!callbacks->read_string) { if (!buff)
free(buff); return -ENOMEM;
return 0; if (read(fd, buff, tmp_len) == -1)
} {
return callbacks->read_string(buff, tmp_len, data); free(buff);
} else if (type > MPF_MAP32) { return -errno;
if (!callbacks->read_int) }
return 0; buff[tmp_len] = '\0';
return callbacks->read_int(type - 0xff - 1, data); if (!callbacks->read_string)
} {
free(buff);
return 0;
}
return callbacks->read_string(buff, tmp_len, data);
}
else if (type > MPF_MAP32)
{
if (!callbacks->read_int)
return 0;
return callbacks->read_int(type - 0xff - 1, data);
}
switch (type) { switch (type)
case 0xc0: {
if (callbacks->read_nil) case 0xc0:
return callbacks->read_nil(data); if (callbacks->read_nil)
break; return callbacks->read_nil(data);
case 0xc2: break;
if (callbacks->read_bool) case 0xc2:
return callbacks->read_bool(0, data); if (callbacks->read_bool)
break; return callbacks->read_bool(0, data);
case 0xc3: break;
if (callbacks->read_bool) case 0xc3:
return callbacks->read_bool(1, data); if (callbacks->read_bool)
break; return callbacks->read_bool(1, data);
case 0xc4: break;
case 0xc5: case 0xc4:
case 0xc6: case 0xc5:
if ((rv = read_buff(fd, 1<<(type - 0xc4), &buff, &tmp_len)) < 0) case 0xc6:
return rv; if ((rv = read_buff(fd, 1<<(type - 0xc4), &buff, &tmp_len)) < 0)
return rv;
if (callbacks->read_bin) if (callbacks->read_bin)
return callbacks->read_bin(buff, tmp_len, data); return callbacks->read_bin(buff, tmp_len, data);
break; break;
case 0xcc: case 0xcc:
case 0xcd: case 0xcd:
case 0xce: case 0xce:
case 0xcf: case 0xcf:
tmp_len = 1ULL << (type - 0xcc); tmp_len = 1ULL << (type - 0xcc);
tmp_uint = 0; tmp_uint = 0;
if (read_uint(fd, &tmp_uint, tmp_len) == -1) if (read_uint(fd, &tmp_uint, tmp_len) == -1)
return -errno; return -errno;
if (callbacks->read_uint) if (callbacks->read_uint)
return callbacks->read_uint(tmp_uint, data); return callbacks->read_uint(tmp_uint, data);
break; break;
case 0xd0: case 0xd0:
case 0xd1: case 0xd1:
case 0xd2: case 0xd2:
case 0xd3: case 0xd3:
tmp_len = 1ULL << (type - 0xd0); tmp_len = 1ULL << (type - 0xd0);
tmp_int = 0; tmp_int = 0;
if (read_int(fd, &tmp_int, tmp_len) == -1) if (read_int(fd, &tmp_int, tmp_len) == -1)
return -errno; return -errno;
if (callbacks->read_int) if (callbacks->read_int)
return callbacks->read_int(tmp_int, data); return callbacks->read_int(tmp_int, data);
break; break;
case 0xd9: case 0xd9:
case 0xda: case 0xda:
case 0xdb: case 0xdb:
if ((rv = read_buff(fd, 1<<(type - 0xd9), &buff, &tmp_len)) < 0) if ((rv = read_buff(fd, 1<<(type - 0xd9), &buff, &tmp_len)) < 0)
return rv; return rv;
if (callbacks->read_string) if (callbacks->read_string)
return callbacks->read_string(buff, tmp_len, data); return callbacks->read_string(buff, tmp_len, data);
break; break;
case 0xdc: case 0xdc:
case 0xdd: case 0xdd:
if (read_uint(fd, &tmp_len, 2<<(type - 0xdc)) == -1) if (read_uint(fd, &tmp_len, 2<<(type - 0xdc)) == -1)
return -errno; return -errno;
return read_array(fd, tmp_len, callbacks, data); return read_array(fd, tmp_len, callbacks, data);
case 0xde: case 0xde:
case 0xdf: case 0xdf:
if (read_uint(fd, &tmp_len, 2<<(type - 0xde)) == -1) if (read_uint(fd, &tmp_len, 2<<(type - 0xde)) == -1)
return -errno; return -errno;
return read_map(fd, tmp_len, callbacks, data); return read_map(fd, tmp_len, callbacks, data);
} }
return 0; return 0;
} }

View File

@ -9,130 +9,120 @@
#include "rmsgpack.h" #include "rmsgpack.h"
#define MAX_DEPTH 128 #define MAX_DEPTH 128
struct dom_reader_state {
struct dom_reader_state
{
int i; int i;
struct rmsgpack_dom_value * stack[MAX_DEPTH]; struct rmsgpack_dom_value * stack[MAX_DEPTH];
}; };
static struct rmsgpack_dom_value * dom_reader_state_pop(struct dom_reader_state * s){ static struct rmsgpack_dom_value * dom_reader_state_pop(
struct dom_reader_state * s)
{
struct rmsgpack_dom_value * v = s->stack[s->i]; struct rmsgpack_dom_value * v = s->stack[s->i];
s->i--; s->i--;
return v; return v;
} }
static int dom_reader_state_push( static int dom_reader_state_push(struct dom_reader_state * s,
struct dom_reader_state * s, struct rmsgpack_dom_value * v)
struct rmsgpack_dom_value * v {
){ if ((s->i + 1) == MAX_DEPTH)
if ((s->i + 1) == MAX_DEPTH) {
return -ENOMEM; return -ENOMEM;
}
s->i++; s->i++;
s->stack[s->i] = v; s->stack[s->i] = v;
return 0; return 0;
} }
static int dom_read_nil(void * data){ static int dom_read_nil(void * data)
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; {
struct rmsgpack_dom_value * v = struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); struct rmsgpack_dom_value * v =
v->type = RDT_NULL; (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
return 0; v->type = RDT_NULL;
return 0;
} }
static int dom_read_bool( static int dom_read_bool(int value, void * data)
int value, {
void * data struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
){ struct rmsgpack_dom_value * v =
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
struct rmsgpack_dom_value * v = v->type = RDT_BOOL;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); v->bool_ = value;
v->type = RDT_BOOL; return 0;
v->bool_ = value;
return 0;
} }
static int dom_read_int( static int dom_read_int(int64_t value, void *data)
int64_t value, {
void * data struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
){ struct rmsgpack_dom_value * v =
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
struct rmsgpack_dom_value * v = v->type = RDT_INT;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); v->int_ = value;
v->type = RDT_INT; return 0;
v->int_ = value;
return 0;
} }
static int dom_read_uint( static int dom_read_uint(uint64_t value, void * data)
uint64_t value, {
void * data struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
){ struct rmsgpack_dom_value * v =
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
struct rmsgpack_dom_value * v = v->type = RDT_UINT;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); v->uint_ = value;
v->type = RDT_UINT; return 0;
v->uint_ = value;
return 0;
} }
static int dom_read_string( static int dom_read_string(char *value, uint32_t len, void *data)
char * value, {
uint32_t len, struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
void * data struct rmsgpack_dom_value * v =
){ (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; v->type = RDT_STRING;
struct rmsgpack_dom_value * v = v->string.len = len;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); v->string.buff = value;
v->type = RDT_STRING; return 0;
v->string.len = len;
v->string.buff = value;
return 0;
} }
static int dom_read_bin( static int dom_read_bin(void *value, uint32_t len, void *data)
void * value, {
uint32_t len, struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
void * data struct rmsgpack_dom_value *v =
){ (struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state);
struct dom_reader_state * dom_state = (struct dom_reader_state *)data; v->type = RDT_BINARY;
struct rmsgpack_dom_value * v = v->binary.len = len;
(struct rmsgpack_dom_value *)dom_reader_state_pop(dom_state); v->binary.buff = (char *)value;
v->type = RDT_BINARY; return 0;
v->binary.len = len;
v->binary.buff = (char *)value;
return 0;
} }
static int dom_read_map_start( static int dom_read_map_start(uint32_t len, void *data)
uint32_t len, {
void * data unsigned i;
){ struct rmsgpack_dom_pair * items = NULL;
unsigned i; struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_pair * items = NULL; struct rmsgpack_dom_value * v = dom_reader_state_pop(dom_state);
struct dom_reader_state * dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value * v = dom_reader_state_pop(dom_state);
v->type = RDT_MAP; v->type = RDT_MAP;
v->map.len = len; v->map.len = len;
v->map.items = NULL; v->map.items = NULL;
items = (struct rmsgpack_dom_pair *)calloc(len, sizeof(struct rmsgpack_dom_pair)); items = (struct rmsgpack_dom_pair *)calloc(len,
sizeof(struct rmsgpack_dom_pair));
if (!items) if (!items)
return -ENOMEM; return -ENOMEM;
v->map.items = items; v->map.items = items;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++)
if (dom_reader_state_push(dom_state, &items[i].value) < 0) {
return -ENOMEM; if (dom_reader_state_push(dom_state, &items[i].value) < 0)
if (dom_reader_state_push(dom_state, &items[i].key) < 0) return -ENOMEM;
return -ENOMEM; if (dom_reader_state_push(dom_state, &items[i].key) < 0)
} return -ENOMEM;
return 0; }
return 0;
} }
static int dom_read_array_start( static int dom_read_array_start(
@ -392,94 +382,96 @@ int rmsgpack_dom_read(
return rv; return rv;
} }
int rmsgpack_dom_read_into( int rmsgpack_dom_read_into(int fd, ...)
int fd, {
... va_list ap;
){ struct rmsgpack_dom_value map;
va_list ap; int rv;
struct rmsgpack_dom_value map; const char * key_name;
int rv; struct rmsgpack_dom_value key;
const char * key_name; struct rmsgpack_dom_value * value;
struct rmsgpack_dom_value key; int64_t * int_value;
struct rmsgpack_dom_value * value; uint64_t * uint_value;
int64_t * int_value; int * bool_value;
uint64_t * uint_value; char * buff_value;
int * bool_value; uint64_t min_len;
char * buff_value;
uint64_t min_len;
int value_type = 0; int value_type = 0;
va_start(ap, fd); va_start(ap, fd);
rv = rmsgpack_dom_read(fd, &map); rv = rmsgpack_dom_read(fd, &map);
(void)value_type; (void)value_type;
if (rv < 0) if (rv < 0)
return rv; return rv;
if (map.type != RDT_MAP) { if (map.type != RDT_MAP)
rv = -EINVAL; {
goto clean; rv = -EINVAL;
} goto clean;
}
while (1) { while (1)
key_name = va_arg(ap, const char *); {
if (key_name == NULL) { key_name = va_arg(ap, const char *);
rv = 0; if (key_name == NULL)
goto clean; {
} rv = 0;
goto clean;
}
key.type = RDT_STRING; key.type = RDT_STRING;
key.string.len = strlen(key_name); key.string.len = strlen(key_name);
key.string.buff = (char *) key_name; key.string.buff = (char *) key_name;
value = rmsgpack_dom_value_map_value(&map, &key); value = rmsgpack_dom_value_map_value(&map, &key);
switch (value->type) { switch (value->type)
case RDT_INT: {
int_value = va_arg(ap, int64_t *); case RDT_INT:
*int_value = value->int_; int_value = va_arg(ap, int64_t *);
break; *int_value = value->int_;
case RDT_BOOL: break;
bool_value = va_arg(ap, int *); case RDT_BOOL:
*bool_value = value->bool_; bool_value = va_arg(ap, int *);
break; *bool_value = value->bool_;
case RDT_UINT: break;
uint_value = va_arg(ap, uint64_t *); case RDT_UINT:
*uint_value = value->uint_; uint_value = va_arg(ap, uint64_t *);
break; *uint_value = value->uint_;
case RDT_BINARY: break;
buff_value = va_arg(ap, char *); case RDT_BINARY:
uint_value = va_arg(ap, uint64_t *); buff_value = va_arg(ap, char *);
*uint_value = value->binary.len; uint_value = va_arg(ap, uint64_t *);
min_len = value->binary.len > *uint_value ? *uint_value : value->binary.len; *uint_value = value->binary.len;
memcpy( min_len = value->binary.len > *uint_value ? *uint_value : value->binary.len;
buff_value, memcpy(
value->binary.buff, buff_value,
min_len value->binary.buff,
); min_len
);
break; break;
case RDT_STRING: case RDT_STRING:
buff_value = va_arg(ap, char *); buff_value = va_arg(ap, char *);
uint_value = va_arg(ap, uint64_t *); uint_value = va_arg(ap, uint64_t *);
min_len = value->string.len + 1 > *uint_value ? *uint_value : value->string.len + 1; min_len = value->string.len + 1 > *uint_value ? *uint_value : value->string.len + 1;
*uint_value = min_len; *uint_value = min_len;
memcpy( memcpy(
buff_value, buff_value,
value->string.buff, value->string.buff,
min_len min_len
); );
break; break;
default: default:
rv = -1; rv = -1;
goto clean; goto clean;
} }
} }
clean: clean:
va_end(ap); va_end(ap);
rmsgpack_dom_value_free(&map); rmsgpack_dom_value_free(&map);
return 0; return 0;
} }

View File

@ -7,15 +7,14 @@
#include "rmsgpack.h" #include "rmsgpack.h"
struct stub_state { struct stub_state
{
int i; int i;
uint64_t stack[256]; uint64_t stack[256];
}; };
static void stub_state_push_map( static void stub_state_push_map(struct stub_state *s, uint32_t size)
struct stub_state * s, {
uint32_t size
){
s->i++; s->i++;
s->stack[s->i] = 1; s->stack[s->i] = 1;
s->i++; s->i++;
@ -23,10 +22,8 @@ static void stub_state_push_map(
printf("{"); printf("{");
} }
static void stub_state_push_array( static void stub_state_push_array(struct stub_state *s, uint32_t size)
struct stub_state * s, {
uint32_t size
){
s->i++; s->i++;
s->stack[s->i] = 2; s->stack[s->i] = 2;
s->i++; s->i++;
@ -34,64 +31,67 @@ static void stub_state_push_array(
printf("["); printf("[");
} }
static void stub_state_pre_print(struct stub_state * s) static void stub_state_pre_print(struct stub_state *s)
{} {
static void stub_state_post_print(struct stub_state * s){
switch (s->stack[s->i - 1]) {
case 1:
if (s->stack[s->i] % 2 == 0) {
printf(": ");
s->stack[s->i]--;
} else if (s->stack[s->i] == 1) {
printf("}");
s->i -= 2;
stub_state_post_print(s);
} else {
printf(", ");
s->stack[s->i]--;
}
break;
case 2:
if (s->stack[s->i] == 1) {
printf("]");
s->i -= 2;
stub_state_post_print(s);
} else {
printf(", ");
s->stack[s->i]--;
}
break;
}
} }
static int stub_read_map_start( static void stub_state_post_print(struct stub_state *s)
uint32_t size, {
void * data switch (s->stack[s->i - 1])
){ {
stub_state_push_map(data, size); case 1:
return 0; if (s->stack[s->i] % 2 == 0)
{
printf(": ");
s->stack[s->i]--;
}
else if (s->stack[s->i] == 1)
{
printf("}");
s->i -= 2;
stub_state_post_print(s);
}
else
{
printf(", ");
s->stack[s->i]--;
}
break;
case 2:
if (s->stack[s->i] == 1)
{
printf("]");
s->i -= 2;
stub_state_post_print(s);
}
else
{
printf(", ");
s->stack[s->i]--;
}
break;
}
} }
static int stub_read_array_start( static int stub_read_map_start(uint32_t size, void *data)
uint32_t size, {
void * data stub_state_push_map(data, size);
){ return 0;
}
static int stub_read_array_start(uint32_t size, void *data)
{
stub_state_push_array(data, size); stub_state_push_array(data, size);
return 0; return 0;
} }
static int stub_read_string( static int stub_read_string(char *s, uint32_t len, void *data)
char * s, {
uint32_t len, stub_state_pre_print(data);
void * data printf("'%s'", s);
){ stub_state_post_print(data);
stub_state_pre_print(data); free(s);
printf("'%s'", s); return 0;
stub_state_post_print(data);
free(s);
return 0;
} }
static int stub_read_bin( static int stub_read_bin(
@ -106,51 +106,47 @@ static int stub_read_bin(
return 0; return 0;
} }
static int stub_read_uint( static int stub_read_uint(uint64_t value, void *data)
uint64_t value, {
void * data stub_state_pre_print(data);
){
stub_state_pre_print(data);
#ifdef _WIN32 #ifdef _WIN32
printf("%I64u", (unsigned long long)value); printf("%I64u", (unsigned long long)value);
#else #else
printf("%llu", (unsigned long long)value); printf("%llu", (unsigned long long)value);
#endif #endif
stub_state_post_print(data); stub_state_post_print(data);
return 0; return 0;
} }
static int stub_read_nil(void * data){ static int stub_read_nil(void * data)
stub_state_pre_print(data); {
printf("nil"); stub_state_pre_print(data);
stub_state_post_print(data); printf("nil");
return 0; stub_state_post_print(data);
return 0;
} }
static int stub_read_int(
int64_t value, static int stub_read_int(int64_t value, void * data)
void * data {
){ stub_state_pre_print(data);
stub_state_pre_print(data);
#ifdef _WIN32 #ifdef _WIN32
printf("%I64d", (signed long long)value); printf("%I64d", (signed long long)value);
#else #else
printf("%lld", (signed long long)value); printf("%lld", (signed long long)value);
#endif #endif
stub_state_post_print(data); stub_state_post_print(data);
return 0; return 0;
} }
static int stub_read_bool( static int stub_read_bool(int value, void * data)
int value, {
void * data stub_state_pre_print(data);
){ if (value)
stub_state_pre_print(data); printf("true");
if (value) else
printf("true"); printf("false");
else stub_state_post_print(data);
printf("false"); return 0;
stub_state_post_print(data);
return 0;
} }
static struct rmsgpack_read_callbacks stub_callbacks = { static struct rmsgpack_read_callbacks stub_callbacks = {
@ -164,42 +160,44 @@ static struct rmsgpack_read_callbacks stub_callbacks = {
stub_read_array_start stub_read_array_start
}; };
int main(void){ int main(void)
int fd; {
/* int fd;
int fd = open("test.msgpack", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); /*
int rv = 0; int fd = open("test.msgpack", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd == -1) int rv = 0;
{ if (fd == -1)
printf("Could not open file: %s", strerror(errno)); {
return errno; printf("Could not open file: %s", strerror(errno));
} return errno;
rmsgpack_write_map_header(fd, 2); }
rmsgpack_write_string(fd, "compact", strlen("compact")); rmsgpack_write_map_header(fd, 2);
rmsgpack_write_bool(fd, 1); rmsgpack_write_string(fd, "compact", strlen("compact"));
rmsgpack_write_string(fd, "schema", strlen("schema")); rmsgpack_write_bool(fd, 1);
rmsgpack_write_array_header(fd, 10); rmsgpack_write_string(fd, "schema", strlen("schema"));
rmsgpack_write_string(fd, "schema", strlen("schema")); rmsgpack_write_array_header(fd, 10);
rmsgpack_write_uint(fd, 1<<17); rmsgpack_write_string(fd, "schema", strlen("schema"));
rmsgpack_write_int(fd, (1<<17) + 1); rmsgpack_write_uint(fd, 1<<17);
rmsgpack_write_int(fd, 4); rmsgpack_write_int(fd, (1<<17) + 1);
rmsgpack_write_int(fd, -3); rmsgpack_write_int(fd, 4);
rmsgpack_write_int(fd, -22); rmsgpack_write_int(fd, -3);
rmsgpack_write_int(fd, -35); rmsgpack_write_int(fd, -22);
rmsgpack_write_int(fd, -421421412); rmsgpack_write_int(fd, -35);
rmsgpack_write_int(fd, 4214); rmsgpack_write_int(fd, -421421412);
rmsgpack_write_int(fd, -4214); rmsgpack_write_int(fd, 4214);
rmsgpack_write_uint(fd, 1<<17); rmsgpack_write_int(fd, -4214);
close(fd); rmsgpack_write_uint(fd, 1<<17);
*/ close(fd);
*/
struct stub_state state; struct stub_state state;
state.i = 0;
state.stack[0] = 0;
fd = open("test.msgpack", O_RDONLY);
rmsgpack_read(fd, &stub_callbacks, &state);
printf("\n");
close(fd);
return 0; state.i = 0;
state.stack[0] = 0;
fd = open("test.msgpack", O_RDONLY);
rmsgpack_read(fd, &stub_callbacks, &state);
printf("\n");
close(fd);
return 0;
} }