RetroArch/libretro-db/rmsgpack_dom.c

544 lines
14 KiB
C
Raw Normal View History

2015-01-19 22:47:09 +01:00
#include "rmsgpack_dom.h"
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "rmsgpack.h"
#define MAX_DEPTH 128
2015-01-27 04:02:10 +01:00
struct dom_reader_state
{
2015-06-03 16:57:51 +02:00
int i;
struct rmsgpack_dom_value *stack[MAX_DEPTH];
2015-01-19 22:47:09 +01:00
};
2015-02-01 15:47:02 +01:00
static struct rmsgpack_dom_value *dom_reader_state_pop(
struct dom_reader_state *s)
2015-01-27 04:02:10 +01:00
{
2015-06-03 16:57:51 +02:00
struct rmsgpack_dom_value *v = s->stack[s->i];
s->i--;
return v;
2015-01-19 22:47:09 +01:00
}
static void puts_i64(int64_t dec)
{
2015-06-25 17:29:44 +02:00
unsigned i;
2015-06-25 18:07:13 +02:00
signed j;
2015-06-13 00:33:31 +02:00
signed char digits[19 + 1] = {0}; /* max i64: 9,223,372,036,854,775,807 */
uint64_t decimal = (dec < 0) ? (uint64_t)-dec : (uint64_t)+dec;
2015-06-03 16:57:51 +02:00
digits[19] = '\0';
2015-06-25 18:07:13 +02:00
for (j = sizeof(digits) - 2; j >= 0; j--)
2015-06-03 16:57:51 +02:00
{
2015-06-25 18:07:13 +02:00
digits[j] = decimal % 10;
2015-06-03 16:57:51 +02:00
decimal /= 10;
}
for (i = 0; i < sizeof(digits) - 1; i++)
digits[i] += '0';
2015-06-25 18:07:13 +02:00
2015-06-03 16:57:51 +02:00
for (i = 0; i < sizeof(digits) - 2; i++)
if (digits[i] != '0')
break; /* Don't print leading zeros to the console. */
if (dec < 0)
putchar('-');
fputs((char *)&digits[i], stdout);
}
static void puts_u64(uint64_t decimal)
{
2015-06-25 18:07:13 +02:00
signed j;
2015-06-25 17:29:44 +02:00
unsigned i;
2015-06-13 00:33:31 +02:00
char digits[20 + 1] = {0}; /* max u64: 18,446,744,073,709,551,616 */
2015-06-03 16:57:51 +02:00
2015-06-25 18:07:13 +02:00
for (j = sizeof(digits) - 2; j >= 0; j--)
2015-06-03 16:57:51 +02:00
{
2015-06-25 18:07:13 +02:00
digits[j] = decimal % 10;
2015-06-03 16:57:51 +02:00
decimal /= 10;
}
for (i = 0; i < sizeof(digits) - 1; i++)
digits[i] += '0';
for (i = 0; i < sizeof(digits) - 2; i++)
if (digits[i] != '0')
break; /* Don't print leading zeros to the console. */
fputs(&digits[i], stdout);
}
2015-02-01 15:47:02 +01:00
static int dom_reader_state_push(struct dom_reader_state *s,
struct rmsgpack_dom_value *v)
2015-01-27 04:02:10 +01:00
{
2015-06-03 16:57:51 +02:00
if ((s->i + 1) == MAX_DEPTH)
return -ENOMEM;
s->i++;
s->stack[s->i] = v;
return 0;
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
static int dom_read_nil(void *data)
2015-01-27 04:02:10 +01:00
{
2015-02-01 15:47:02 +01:00
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_NULL;
return 0;
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
static int dom_read_bool(int value, void *data)
2015-01-27 04:02:10 +01:00
{
2015-02-01 15:47:02 +01:00
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_BOOL;
2015-06-26 20:33:40 +02:00
v->val.bool_ = value;
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-01-27 04:02:10 +01:00
static int dom_read_int(int64_t value, void *data)
{
2015-02-01 15:47:02 +01:00
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_INT;
2015-06-26 20:33:40 +02:00
v->val.int_ = value;
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
static int dom_read_uint(uint64_t value, void *data)
2015-01-27 04:02:10 +01:00
{
2015-02-01 15:47:02 +01:00
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_UINT;
2015-06-26 20:33:40 +02:00
v->val.uint_ = value;
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-01-27 04:02:10 +01:00
static int dom_read_string(char *value, uint32_t len, void *data)
{
2015-02-01 15:47:02 +01:00
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_STRING;
2015-06-26 20:33:40 +02:00
v->val.string.len = len;
v->val.string.buff = value;
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-01-27 04:02:10 +01:00
static int dom_read_bin(void *value, uint32_t len, void *data)
{
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v =
2015-02-01 15:47:02 +01:00
(struct rmsgpack_dom_value*)dom_reader_state_pop(dom_state);
2015-06-03 16:57:51 +02:00
2015-01-27 04:02:10 +01:00
v->type = RDT_BINARY;
2015-06-26 20:33:40 +02:00
v->val.binary.len = len;
v->val.binary.buff = (char *)value;
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-01-27 04:02:10 +01:00
static int dom_read_map_start(uint32_t len, void *data)
{
unsigned i;
2015-02-01 15:47:02 +01:00
struct rmsgpack_dom_pair *items = NULL;
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v = dom_reader_state_pop(dom_state);
2015-01-27 04:02:10 +01:00
v->type = RDT_MAP;
2015-06-26 20:33:40 +02:00
v->val.map.len = len;
v->val.map.items = NULL;
2015-01-27 04:02:10 +01:00
items = (struct rmsgpack_dom_pair *)calloc(len,
sizeof(struct rmsgpack_dom_pair));
if (!items)
return -ENOMEM;
2015-06-26 20:33:40 +02:00
v->val.map.items = items;
2015-02-01 15:47:02 +01:00
2015-01-27 04:02:10 +01:00
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].key) < 0)
return -ENOMEM;
}
2015-02-01 15:47:02 +01:00
2015-01-27 04:02:10 +01:00
return 0;
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
static int dom_read_array_start(uint32_t len, void *data)
{
2015-06-03 16:57:51 +02:00
unsigned i;
struct dom_reader_state *dom_state = (struct dom_reader_state *)data;
struct rmsgpack_dom_value *v = dom_reader_state_pop(dom_state);
struct rmsgpack_dom_value *items = NULL;
2015-01-19 22:47:09 +01:00
2015-06-26 20:33:40 +02:00
v->type = RDT_ARRAY;
v->val.array.len = len;
v->val.array.items = NULL;
2015-01-19 22:47:09 +01:00
2015-06-03 16:57:51 +02:00
items = (struct rmsgpack_dom_value *)calloc(len, sizeof(struct rmsgpack_dom_pair));
2015-01-19 22:47:09 +01:00
2015-06-03 16:57:51 +02:00
if (!items)
return -ENOMEM;
2015-01-19 22:47:09 +01:00
2015-06-26 20:33:40 +02:00
v->val.array.items = items;
2015-01-19 22:47:09 +01:00
2015-06-03 16:57:51 +02:00
for (i = 0; i < len; i++)
2015-02-01 15:47:02 +01:00
{
if (dom_reader_state_push(dom_state, &items[i]) < 0)
return -ENOMEM;
}
2015-06-03 16:57:51 +02:00
return 0;
2015-01-19 22:47:09 +01:00
}
static struct rmsgpack_read_callbacks dom_reader_callbacks = {
2015-06-03 16:57:51 +02:00
dom_read_nil,
dom_read_bool,
dom_read_int,
dom_read_uint,
dom_read_string,
dom_read_bin,
dom_read_map_start,
dom_read_array_start
2015-01-19 22:47:09 +01:00
};
2015-02-01 15:47:02 +01:00
void rmsgpack_dom_value_free(struct rmsgpack_dom_value *v)
{
unsigned i;
2015-01-19 22:47:09 +01:00
2015-02-01 15:47:02 +01:00
switch (v->type)
{
case RDT_STRING:
2015-06-26 20:33:40 +02:00
free(v->val.string.buff);
v->val.string.buff = NULL;
2015-02-01 15:47:02 +01:00
break;
case RDT_BINARY:
2015-06-26 20:33:40 +02:00
free(v->val.binary.buff);
v->val.binary.buff = NULL;
2015-02-01 15:47:02 +01:00
break;
case RDT_MAP:
2015-06-26 20:33:40 +02:00
for (i = 0; i < v->val.map.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
rmsgpack_dom_value_free(&v->val.map.items[i].key);
rmsgpack_dom_value_free(&v->val.map.items[i].value);
2015-02-01 15:47:02 +01:00
}
2015-06-26 20:33:40 +02:00
free(v->val.map.items);
v->val.map.items = NULL;
2015-02-01 15:47:02 +01:00
break;
case RDT_ARRAY:
2015-06-26 20:33:40 +02:00
for (i = 0; i < v->val.array.len; i++)
rmsgpack_dom_value_free(&v->val.array.items[i]);
free(v->val.array.items);
v->val.array.items = NULL;
2015-02-01 15:47:02 +01:00
break;
case RDT_NULL:
case RDT_INT:
case RDT_BOOL:
case RDT_UINT:
2015-06-26 18:35:35 +02:00
/* Do nothing */
2015-02-01 15:47:02 +01:00
break;
}
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
struct rmsgpack_dom_value *rmsgpack_dom_value_map_value(
const struct rmsgpack_dom_value *map,
const struct rmsgpack_dom_value *key)
{
unsigned i;
if (map->type != RDT_MAP)
return NULL;
2015-06-26 20:33:40 +02:00
for (i = 0; i < map->val.map.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
if (rmsgpack_dom_value_cmp(key, &map->val.map.items[i].key) == 0)
return &map->val.map.items[i].value;
2015-02-01 15:47:02 +01:00
}
return NULL;
2015-01-19 22:47:09 +01:00
}
int rmsgpack_dom_value_cmp(
2015-02-01 15:47:02 +01:00
const struct rmsgpack_dom_value *a,
const struct rmsgpack_dom_value *b
2015-06-03 16:57:51 +02:00
)
2015-02-01 15:47:02 +01:00
{
int rv;
unsigned i;
if (a == b)
return 1;
if (a->type != b->type)
return 1;
switch (a->type)
{
case RDT_NULL:
return 0;
case RDT_BOOL:
2015-06-26 20:33:40 +02:00
return (a->val.bool_ == b->val.bool_) ? 0 : 1;
2015-02-01 15:47:02 +01:00
case RDT_INT:
2015-06-26 20:33:40 +02:00
return (a->val.int_ == b->val.int_) ? 0 : 1;
2015-02-01 15:47:02 +01:00
case RDT_UINT:
2015-06-26 20:33:40 +02:00
return (a->val.uint_ == b->val.uint_) ? 0 : 1;
2015-02-01 15:47:02 +01:00
case RDT_STRING:
2015-06-26 20:33:40 +02:00
if (a->val.string.len != b->val.string.len)
2015-02-01 15:47:02 +01:00
return 1;
2015-06-26 20:33:40 +02:00
return strncmp(a->val.string.buff, b->val.string.buff, a->val.string.len);
2015-02-01 15:47:02 +01:00
case RDT_BINARY:
2015-06-26 20:33:40 +02:00
if (a->val.binary.len != b->val.binary.len)
2015-02-01 15:47:02 +01:00
return 1;
2015-06-26 20:33:40 +02:00
return memcmp(a->val.binary.buff, b->val.binary.buff, a->val.binary.len);
2015-02-01 15:47:02 +01:00
case RDT_MAP:
2015-06-26 20:33:40 +02:00
if (a->val.map.len != b->val.map.len)
2015-02-01 15:47:02 +01:00
return 1;
2015-06-26 20:33:40 +02:00
for (i = 0; i < a->val.map.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_value_cmp(&a->val.map.items[i].key,
&b->val.map.items[i].key)) != 0)
2015-02-01 15:47:02 +01:00
return rv;
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_value_cmp(&a->val.map.items[i].value,
&b->val.map.items[i].value)) != 0)
2015-02-01 15:47:02 +01:00
return rv;
}
break;
case RDT_ARRAY:
2015-06-26 20:33:40 +02:00
if (a->val.array.len != b->val.array.len)
2015-02-01 15:47:02 +01:00
return 1;
2015-06-26 20:33:40 +02:00
for (i = 0; i < a->val.array.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_value_cmp(&a->val.array.items[i],
&b->val.array.items[i])) != 0)
2015-02-01 15:47:02 +01:00
return rv;
}
break;
}
2015-01-19 22:47:09 +01:00
2015-02-01 15:47:02 +01:00
return 1;
2015-01-19 22:47:09 +01:00
}
2015-02-01 15:47:02 +01:00
void rmsgpack_dom_value_print(struct rmsgpack_dom_value *obj)
{
unsigned i;
2015-01-19 22:47:09 +01:00
2015-02-01 15:47:02 +01:00
switch (obj->type)
{
case RDT_NULL:
printf("nil");
break;
case RDT_BOOL:
2015-06-26 20:33:40 +02:00
if (obj->val.bool_)
2015-02-01 15:47:02 +01:00
printf("true");
else
printf("false");
break;
case RDT_INT:
2015-06-26 20:33:40 +02:00
puts_i64(obj->val.int_);
2015-02-01 15:47:02 +01:00
break;
case RDT_UINT:
2015-06-26 20:33:40 +02:00
puts_u64(obj->val.uint_);
2015-02-01 15:47:02 +01:00
break;
case RDT_STRING:
2015-06-26 20:33:40 +02:00
printf("\"%s\"", obj->val.string.buff);
2015-02-01 15:47:02 +01:00
break;
case RDT_BINARY:
printf("\"");
2015-06-26 20:33:40 +02:00
for (i = 0; i < obj->val.binary.len; i++)
printf("%02X", (unsigned char) obj->val.binary.buff[i]);
2015-02-01 15:47:02 +01:00
printf("\"");
break;
case RDT_MAP:
printf("{");
2015-06-26 20:33:40 +02:00
for (i = 0; i < obj->val.map.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
rmsgpack_dom_value_print(&obj->val.map.items[i].key);
2015-02-01 15:47:02 +01:00
printf(": ");
2015-06-26 20:33:40 +02:00
rmsgpack_dom_value_print(&obj->val.map.items[i].value);
if (i < (obj->val.map.len - 1))
2015-02-01 15:47:02 +01:00
printf(", ");
}
printf("}");
break;
case RDT_ARRAY:
printf("[");
2015-06-26 20:33:40 +02:00
for (i = 0; i < obj->val.array.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
rmsgpack_dom_value_print(&obj->val.array.items[i]);
if (i < (obj->val.array.len - 1))
2015-02-01 15:47:02 +01:00
printf(", ");
}
printf("]");
}
2015-01-19 22:47:09 +01:00
}
2015-05-30 13:17:11 -03:00
int rmsgpack_dom_write(FILE *fp, const struct rmsgpack_dom_value *obj)
2015-02-01 15:47:02 +01:00
{
unsigned i;
2015-06-03 16:26:54 +02:00
int rv = 0;
2015-02-01 15:47:02 +01:00
int written = 0;
switch (obj->type)
{
case RDT_NULL:
2015-05-30 13:17:11 -03:00
return rmsgpack_write_nil(fp);
2015-02-01 15:47:02 +01:00
case RDT_BOOL:
2015-06-26 20:33:40 +02:00
return rmsgpack_write_bool(fp, obj->val.bool_);
2015-02-01 15:47:02 +01:00
case RDT_INT:
2015-06-26 20:33:40 +02:00
return rmsgpack_write_int(fp, obj->val.int_);
2015-02-01 15:47:02 +01:00
case RDT_UINT:
2015-06-26 20:33:40 +02:00
return rmsgpack_write_uint(fp, obj->val.uint_);
2015-02-01 15:47:02 +01:00
case RDT_STRING:
2015-06-26 20:33:40 +02:00
return rmsgpack_write_string(fp, obj->val.string.buff, obj->val.string.len);
2015-02-01 15:47:02 +01:00
case RDT_BINARY:
2015-06-26 20:33:40 +02:00
return rmsgpack_write_bin(fp, obj->val.binary.buff, obj->val.binary.len);
2015-02-01 15:47:02 +01:00
case RDT_MAP:
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_write_map_header(fp, obj->val.map.len)) < 0)
2015-02-01 15:47:02 +01:00
return rv;
written += rv;
2015-06-26 20:33:40 +02:00
for (i = 0; i < obj->val.map.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_write(fp, &obj->val.map.items[i].key)) < 0)
2015-02-01 15:47:02 +01:00
return rv;
written += rv;
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_write(fp, &obj->val.map.items[i].value)) < 0)
2015-02-01 15:47:02 +01:00
return rv;
written += rv;
}
break;
case RDT_ARRAY:
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_write_array_header(fp, obj->val.array.len)) < 0)
2015-02-01 15:47:02 +01:00
return rv;
written += rv;
2015-06-26 20:33:40 +02:00
for (i = 0; i < obj->val.array.len; i++)
2015-02-01 15:47:02 +01:00
{
2015-06-26 20:33:40 +02:00
if ((rv = rmsgpack_dom_write(fp, &obj->val.array.items[i])) < 0)
2015-02-01 15:47:02 +01:00
return rv;
written += rv;
}
}
return written;
2015-01-19 22:47:09 +01:00
}
2015-05-30 13:17:11 -03:00
int rmsgpack_dom_read(FILE *fp, struct rmsgpack_dom_value *out)
2015-02-01 15:47:02 +01:00
{
2015-06-03 16:26:54 +02:00
struct dom_reader_state s = {0};
int rv = 0;
2015-02-01 15:47:02 +01:00
s.stack[0] = out;
2015-05-30 13:17:11 -03:00
rv = rmsgpack_read(fp, &dom_reader_callbacks, &s);
2015-01-19 22:47:09 +01:00
2015-02-01 15:47:02 +01:00
if (rv < 0)
rmsgpack_dom_value_free(out);
2015-01-19 22:47:09 +01:00
2015-02-01 15:47:02 +01:00
return rv;
2015-01-19 22:47:09 +01:00
}
2015-05-30 13:17:11 -03:00
int rmsgpack_dom_read_into(FILE *fp, ...)
2015-01-27 04:02:10 +01:00
{
va_list ap;
int rv;
2015-06-13 00:33:31 +02:00
struct rmsgpack_dom_value map;
2015-01-27 04:02:10 +01:00
struct rmsgpack_dom_value key;
2015-02-01 15:47:02 +01:00
struct rmsgpack_dom_value *value;
int64_t *int_value;
uint64_t *uint_value;
int *bool_value;
2015-01-27 04:02:10 +01:00
uint64_t min_len;
2015-06-13 00:33:31 +02:00
char *buff_value = NULL;
const char *key_name = NULL;
int value_type = 0;
2015-01-27 04:02:10 +01:00
2015-05-30 13:17:11 -03:00
va_start(ap, fp);
2015-02-01 15:47:02 +01:00
2015-05-30 13:17:11 -03:00
rv = rmsgpack_dom_read(fp, &map);
2015-01-27 04:02:10 +01:00
(void)value_type;
if (rv < 0)
2015-01-28 09:26:22 -05:00
{
va_end(ap);
2015-01-27 04:02:10 +01:00
return rv;
2015-01-28 09:26:22 -05:00
}
2015-01-27 04:02:10 +01:00
if (map.type != RDT_MAP)
{
rv = -EINVAL;
goto clean;
}
while (1)
{
key_name = va_arg(ap, const char *);
2015-02-01 15:47:02 +01:00
if (!key_name)
2015-01-27 04:02:10 +01:00
{
rv = 0;
goto clean;
}
2015-02-01 15:47:02 +01:00
key.type = RDT_STRING;
2015-06-26 20:33:40 +02:00
key.val.string.len = strlen(key_name);
key.val.string.buff = (char *) key_name;
2015-01-27 04:02:10 +01:00
value = rmsgpack_dom_value_map_value(&map, &key);
switch (value->type)
{
case RDT_INT:
2015-02-01 15:47:02 +01:00
int_value = va_arg(ap, int64_t *);
2015-06-26 20:33:40 +02:00
*int_value = value->val.int_;
2015-01-27 04:02:10 +01:00
break;
case RDT_BOOL:
2015-02-01 15:47:02 +01:00
bool_value = va_arg(ap, int *);
2015-06-26 20:33:40 +02:00
*bool_value = value->val.bool_;
2015-01-27 04:02:10 +01:00
break;
case RDT_UINT:
2015-02-01 15:47:02 +01:00
uint_value = va_arg(ap, uint64_t *);
2015-06-26 20:33:40 +02:00
*uint_value = value->val.uint_;
2015-01-27 04:02:10 +01:00
break;
case RDT_BINARY:
2015-02-01 15:47:02 +01:00
buff_value = va_arg(ap, char *);
uint_value = va_arg(ap, uint64_t *);
2015-06-26 20:33:40 +02:00
*uint_value = value->val.binary.len;
min_len = (value->val.binary.len > *uint_value) ?
*uint_value : value->val.binary.len;
2015-01-27 04:02:10 +01:00
2015-06-30 16:22:51 +02:00
memcpy(buff_value, value->val.binary.buff, (size_t)min_len);
2015-01-27 04:02:10 +01:00
break;
case RDT_STRING:
buff_value = va_arg(ap, char *);
uint_value = va_arg(ap, uint64_t *);
2015-06-26 20:33:40 +02:00
min_len = (value->val.string.len + 1 > *uint_value) ?
*uint_value : value->val.string.len + 1;
2015-01-27 04:02:10 +01:00
*uint_value = min_len;
2015-02-01 15:47:02 +01:00
2015-06-30 16:22:51 +02:00
memcpy(buff_value, value->val.string.buff, (size_t)min_len);
2015-01-27 04:02:10 +01:00
break;
default:
rv = -1;
goto clean;
}
}
2015-01-19 22:47:09 +01:00
clean:
2015-01-27 04:02:10 +01:00
va_end(ap);
rmsgpack_dom_value_free(&map);
return 0;
2015-01-19 22:47:09 +01:00
}