Implement JSON printing function
This commit is contained in:
parent
030c364615
commit
08bb217747
4 changed files with 324 additions and 18 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.vscode/
|
||||||
|
examples/empack_cli
|
||||||
50
examples/empack_cli.c
Normal file
50
examples/empack_cli.c
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "empack.h"
|
||||||
|
|
||||||
|
#define USAGE \
|
||||||
|
"empack_cli [OPTIONS] <file | msgpack hex>\r\n" \
|
||||||
|
" file: File to read binary Msgpack data from, \"-\" for stdin\r\n" \
|
||||||
|
" msgpack hex: Hex string of Msgpack data\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"OPTIONS\r\n" \
|
||||||
|
" -h/--help: Print this message\r\n"
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_func(const char *buf, uint32_t buflen, void *arg)
|
||||||
|
{
|
||||||
|
printf("%.*s", buflen, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const uint8_t input[] = { 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 };
|
||||||
|
size_t input_len = sizeof(input);
|
||||||
|
empack_t empack;
|
||||||
|
uint8_t arena[256];
|
||||||
|
uint32_t chars_printed;
|
||||||
|
|
||||||
|
empack_init(&empack, arena, sizeof(arena));
|
||||||
|
|
||||||
|
if (empack_parse(&empack, input, input_len)) {
|
||||||
|
fprintf(stderr, "Parsing error\r\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
chars_printed = empack_print(&empack, print_func, NULL, " ");
|
||||||
|
printf("\r\n-- Stats --\r\n"
|
||||||
|
"Characters Printed: %u\r\n"
|
||||||
|
"Arena Memory Used: %u/%uB (%u%%)\r\n"
|
||||||
|
"-----------\r\n",
|
||||||
|
chars_printed,
|
||||||
|
empack.arena_used,
|
||||||
|
empack.arena_sz,
|
||||||
|
(empack.arena_used * 100) / empack.arena_sz);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
259
src/empack.c
259
src/empack.c
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ empack_init(empack_t *empack, void *arena, uint32_t arena_sz)
|
||||||
empack->arena_used = 0;
|
empack->arena_used = 0;
|
||||||
|
|
||||||
memset(arena, 0, arena_sz);
|
memset(arena, 0, arena_sz);
|
||||||
|
memset(&empack->root, 0, sizeof(empack->root));
|
||||||
}
|
}
|
||||||
|
|
||||||
empack_status_e
|
empack_status_e
|
||||||
|
|
@ -62,16 +64,17 @@ empack_parse(empack_t *empack, const void *msgpack, uint32_t len)
|
||||||
{
|
{
|
||||||
empack_array_t *parr = &parent->val.array;
|
empack_array_t *parr = &parent->val.array;
|
||||||
|
|
||||||
if (parr->object_count == parr->object_count_real) {
|
if (parr->object_count == parr->objects_parsed) {
|
||||||
ret = EMPACK_STATUS_ERROR;
|
ret = EMPACK_STATUS_ERROR;
|
||||||
goto empack_parse_return;
|
goto empack_parse_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = &parr->objects[parr->object_count_real];
|
cur->next = &parr->objects[parr->objects_parsed];
|
||||||
|
cur = cur->next;
|
||||||
cur->parent = parent;
|
cur->parent = parent;
|
||||||
|
|
||||||
parr->object_count_real++;
|
parr->objects_parsed++;
|
||||||
if (parr->object_count == parr->object_count_real) {
|
if (parr->object_count == parr->objects_parsed) {
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -82,21 +85,22 @@ empack_parse(empack_t *empack, const void *msgpack, uint32_t len)
|
||||||
{
|
{
|
||||||
empack_map_t *pmap = &parent->val.map;
|
empack_map_t *pmap = &parent->val.map;
|
||||||
|
|
||||||
if (pmap->pair_count == pmap->pair_count_real) {
|
if (pmap->pair_count == pmap->pairs_parsed) {
|
||||||
ret = EMPACK_STATUS_ERROR;
|
ret = EMPACK_STATUS_ERROR;
|
||||||
goto empack_parse_return;
|
goto empack_parse_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pmap->pairs[pmap->pair_count_real].key.type == EMPACK_TYPE_ERROR) {
|
if (pmap->pairs[pmap->pairs_parsed].key.type == EMPACK_TYPE_ERROR) {
|
||||||
/* We haven't parsed the key yet */
|
/* We haven't parsed the key yet */
|
||||||
cur = &pmap->pairs[pmap->pair_count_real].key;
|
cur->next = &pmap->pairs[pmap->pairs_parsed].key;
|
||||||
} else {
|
} else {
|
||||||
cur = &pmap->pairs[pmap->pair_count_real].value;
|
cur->next = &pmap->pairs[pmap->pairs_parsed].value;
|
||||||
pmap->pair_count_real++;
|
pmap->pairs_parsed++;
|
||||||
}
|
}
|
||||||
|
cur = cur->next;
|
||||||
cur->parent = parent;
|
cur->parent = parent;
|
||||||
|
|
||||||
if (pmap->pair_count == pmap->pair_count_real) {
|
if (pmap->pair_count == pmap->pairs_parsed) {
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -117,9 +121,6 @@ empack_parse(empack_t *empack, const void *msgpack, uint32_t len)
|
||||||
|
|
||||||
p += len_used;
|
p += len_used;
|
||||||
tokens_needed--;
|
tokens_needed--;
|
||||||
if ((tokens_needed == 0) && (ret == EMPACK_STATUS_EXTRA)) {
|
|
||||||
goto empack_parse_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
|
|
@ -166,6 +167,10 @@ empack_parse(empack_t *empack, const void *msgpack, uint32_t len)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tokens_needed == 0) && (ret == EMPACK_STATUS_EXTRA)) {
|
||||||
|
goto empack_parse_return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prioritize errors over incomplete status */
|
/* prioritize errors over incomplete status */
|
||||||
|
|
@ -184,7 +189,7 @@ empack_parse_one(empack_obj_t *object, const void *msgpack, uint32_t *len)
|
||||||
uint32_t p = 0;
|
uint32_t p = 0;
|
||||||
empack_status_e ret = EMPACK_STATUS_EXTRA;
|
empack_status_e ret = EMPACK_STATUS_EXTRA;
|
||||||
|
|
||||||
memset(object, 0, sizeof(*object));
|
memset(&object->val, 0, sizeof(object->val));
|
||||||
|
|
||||||
#define EMPACK_PARSEONE_ASSERT(need) do { \
|
#define EMPACK_PARSEONE_ASSERT(need) do { \
|
||||||
if ((p + (need)) > (*len)) { \
|
if ((p + (need)) > (*len)) { \
|
||||||
|
|
@ -440,7 +445,10 @@ empack_parse_one(empack_obj_t *object, const void *msgpack, uint32_t *len)
|
||||||
}
|
}
|
||||||
else if ((object->type >= EMPACK_TYPE_FIXSTR) && (object->type <= EMPACK_FIXSTR_MAX)) {
|
else if ((object->type >= EMPACK_TYPE_FIXSTR) && (object->type <= EMPACK_FIXSTR_MAX)) {
|
||||||
object->val.str.size = ((uint8_t)object->type) & 0x1f;
|
object->val.str.size = ((uint8_t)object->type) & 0x1f;
|
||||||
|
EMPACK_PARSEONE_ASSERT(object->val.str.size);
|
||||||
|
object->val.str.data = (const char *)&buf[p];
|
||||||
object->type = EMPACK_TYPE_FIXSTR;
|
object->type = EMPACK_TYPE_FIXSTR;
|
||||||
|
p += object->val.str.size;
|
||||||
}
|
}
|
||||||
else if ((object->type >= EMPACK_TYPE_NEG_FIXINT) && (object->type <= EMPACK_NEG_FIXINT_MAX)) {
|
else if ((object->type >= EMPACK_TYPE_NEG_FIXINT) && (object->type <= EMPACK_NEG_FIXINT_MAX)) {
|
||||||
object->val.int8 = (int8_t)object->type;
|
object->val.int8 = (int8_t)object->type;
|
||||||
|
|
@ -462,6 +470,229 @@ empack_parse_one_return:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
empack_print(empack_t *empack,
|
||||||
|
void (*print_func)(const char *buf, uint32_t buflen, void *arg),
|
||||||
|
void *arg,
|
||||||
|
const char *indent)
|
||||||
|
{
|
||||||
|
uint32_t ret = 0;
|
||||||
|
int indent_depth = 0;
|
||||||
|
size_t indent_len = indent ? strlen(indent) : 0;
|
||||||
|
empack_obj_t *cur = &empack->root;
|
||||||
|
|
||||||
|
#define EMPACK_PRINT(buf, len) do { \
|
||||||
|
const char *__buf = (buf); \
|
||||||
|
uint32_t __len = (len); \
|
||||||
|
ret += __len; \
|
||||||
|
print_func(__buf, len, arg); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define EMPACK_PRINT_INDENT() do { \
|
||||||
|
if (indent) { \
|
||||||
|
for (int __i = 0; __i < indent_depth; __i++) { \
|
||||||
|
EMPACK_PRINT(indent, indent_len); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMPACK_PRINT_NEWLINE() do { \
|
||||||
|
if (indent) { \
|
||||||
|
EMPACK_PRINT("\r\n", 2); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
/* Large enough for uint64/double */
|
||||||
|
char tmp[24];
|
||||||
|
int tmp_len;
|
||||||
|
|
||||||
|
/* Print indent for everything except map value */
|
||||||
|
if (cur->parent && EMPACK_IS_MAP(cur->parent->type)) {
|
||||||
|
empack_map_t *pmap = &cur->parent->val.map;
|
||||||
|
|
||||||
|
if (cur == &pmap->pairs[pmap->pairs_parsed].key) {
|
||||||
|
EMPACK_PRINT_INDENT();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EMPACK_PRINT_INDENT();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cur->type) {
|
||||||
|
case EMPACK_TYPE_FIXMAP:
|
||||||
|
case EMPACK_TYPE_MAP16:
|
||||||
|
case EMPACK_TYPE_MAP32:
|
||||||
|
EMPACK_PRINT("{", 1);
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
cur->val.map.pairs_parsed = 0;
|
||||||
|
indent_depth++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMPACK_TYPE_FIXARRAY:
|
||||||
|
case EMPACK_TYPE_ARRAY16:
|
||||||
|
case EMPACK_TYPE_ARRAY32:
|
||||||
|
EMPACK_PRINT("[", 1);
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
cur->val.array.objects_parsed = 0;
|
||||||
|
indent_depth++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMPACK_TYPE_FIXSTR:
|
||||||
|
case EMPACK_TYPE_STR8:
|
||||||
|
case EMPACK_TYPE_STR16:
|
||||||
|
case EMPACK_TYPE_STR32:
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
EMPACK_PRINT(cur->val.str.data, cur->val.str.size);
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMPACK_TYPE_BIN8:
|
||||||
|
case EMPACK_TYPE_BIN16:
|
||||||
|
case EMPACK_TYPE_BIN32:
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
for (uint32_t i = 0; i < cur->val.bin.size; i++) {
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%02X", ((uint8_t *)cur->val.bin.data)[i]);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
}
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMPACK_TYPE_EXT8:
|
||||||
|
case EMPACK_TYPE_EXT16:
|
||||||
|
case EMPACK_TYPE_EXT32:
|
||||||
|
case EMPACK_TYPE_FIXEXT1:
|
||||||
|
case EMPACK_TYPE_FIXEXT2:
|
||||||
|
case EMPACK_TYPE_FIXEXT4:
|
||||||
|
case EMPACK_TYPE_FIXEXT8:
|
||||||
|
case EMPACK_TYPE_FIXEXT16:
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
for (uint32_t i = 0; i < cur->val.ext.size; i++) {
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%02X", ((uint8_t *)cur->val.ext.data)[i]);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
}
|
||||||
|
EMPACK_PRINT("\"", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMPACK_TYPE_NIL:
|
||||||
|
EMPACK_PRINT("null", 4);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_ERROR:
|
||||||
|
EMPACK_PRINT("ERROR", 5);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_FALSE:
|
||||||
|
EMPACK_PRINT("false", 5);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_TRUE:
|
||||||
|
EMPACK_PRINT("true", 4);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_FLOAT32:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%f", cur->val.float32);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_FLOAT64:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%f", cur->val.float64);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_POS_FIXINT:
|
||||||
|
case EMPACK_TYPE_UINT8:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%u", cur->val.uint8);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_UINT16:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%u", cur->val.uint16);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_UINT32:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%u", cur->val.uint32);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_UINT64:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%u%u",
|
||||||
|
(uint32_t)(cur->val.uint64 >> 32),
|
||||||
|
(uint32_t)cur->val.uint64);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_NEG_FIXINT:
|
||||||
|
case EMPACK_TYPE_INT8:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%d", cur->val.int8);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_INT16:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%d", cur->val.int16);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_INT32:
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%d", cur->val.int32);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
break;
|
||||||
|
case EMPACK_TYPE_INT64:
|
||||||
|
{
|
||||||
|
uint64_t tmp_num;
|
||||||
|
const char *sign = "";
|
||||||
|
|
||||||
|
if (cur->val.int64 < 0) {
|
||||||
|
tmp_num = -cur->val.int64;
|
||||||
|
sign = "-";
|
||||||
|
} else {
|
||||||
|
tmp_num = cur->val.int64;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_len = snprintf(tmp, sizeof(tmp), "%s%u%u",
|
||||||
|
sign,
|
||||||
|
(uint32_t)(tmp_num >> 32),
|
||||||
|
(uint32_t)tmp_num);
|
||||||
|
EMPACK_PRINT(tmp, tmp_len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur->parent && EMPACK_IS_MAP(cur->parent->type)) {
|
||||||
|
empack_map_t *pmap = &cur->parent->val.map;
|
||||||
|
|
||||||
|
if (cur == &pmap->pairs[pmap->pairs_parsed].key) {
|
||||||
|
EMPACK_PRINT(":", 1);
|
||||||
|
if (indent) {
|
||||||
|
EMPACK_PRINT(" ", 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pmap->pairs_parsed != (pmap->pair_count - 1)) {
|
||||||
|
EMPACK_PRINT(",", 1);
|
||||||
|
}
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
|
||||||
|
pmap->pairs_parsed++;
|
||||||
|
if (pmap->pairs_parsed == pmap->pair_count) {
|
||||||
|
indent_depth--;
|
||||||
|
EMPACK_PRINT_INDENT();
|
||||||
|
EMPACK_PRINT("}", 1);
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cur->parent && EMPACK_IS_ARRAY(cur->parent->type)) {
|
||||||
|
empack_array_t *parr = &cur->parent->val.array;
|
||||||
|
|
||||||
|
if (parr->objects_parsed != (parr->object_count - 1)) {
|
||||||
|
EMPACK_PRINT(",", 1);
|
||||||
|
}
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
|
||||||
|
parr->objects_parsed++;
|
||||||
|
if (parr->objects_parsed == parr->object_count) {
|
||||||
|
indent_depth--;
|
||||||
|
EMPACK_PRINT_INDENT();
|
||||||
|
EMPACK_PRINT("]", 1);
|
||||||
|
EMPACK_PRINT_NEWLINE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
empack_allocate(empack_t *empack, uint32_t size)
|
empack_allocate(empack_t *empack, uint32_t size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
31
src/empack.h
31
src/empack.h
|
|
@ -71,8 +71,8 @@ struct empack_map_struct {
|
||||||
empack_map_pair_t *pairs;
|
empack_map_pair_t *pairs;
|
||||||
/** Number of key-value pairs expected to be in the map */
|
/** Number of key-value pairs expected to be in the map */
|
||||||
uint32_t pair_count;
|
uint32_t pair_count;
|
||||||
/** Number of key-value pairs actually in the map */
|
/** Parsed count utilized in tree traversal */
|
||||||
uint32_t pair_count_real;
|
uint32_t pairs_parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct empack_array_struct {
|
struct empack_array_struct {
|
||||||
|
|
@ -80,8 +80,8 @@ struct empack_array_struct {
|
||||||
empack_obj_t *objects;
|
empack_obj_t *objects;
|
||||||
/** Number of objects expected to be in the array */
|
/** Number of objects expected to be in the array */
|
||||||
uint32_t object_count;
|
uint32_t object_count;
|
||||||
/** Number of objects actually in the array */
|
/** Parsed count utilized in tree traversal */
|
||||||
uint32_t object_count_real;
|
uint32_t objects_parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct empack_str_struct {
|
struct empack_str_struct {
|
||||||
|
|
@ -137,6 +137,11 @@ struct empack_obj_struct {
|
||||||
* parsing. NULL if no parent is present.
|
* parsing. NULL if no parent is present.
|
||||||
*/
|
*/
|
||||||
empack_obj_t *parent;
|
empack_obj_t *parent;
|
||||||
|
/**
|
||||||
|
* Object that comes immediately after this one in the original Msgpack
|
||||||
|
* buffer, NULL if last object
|
||||||
|
*/
|
||||||
|
empack_obj_t *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct empack_map_pair_struct {
|
struct empack_map_pair_struct {
|
||||||
|
|
@ -173,6 +178,16 @@ struct empack_struct {
|
||||||
uint32_t arena_used;
|
uint32_t arena_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Macro for whether the given type is a map */
|
||||||
|
#define EMPACK_IS_MAP(type) ((type == EMPACK_TYPE_FIXMAP) || \
|
||||||
|
(type == EMPACK_TYPE_MAP16) || \
|
||||||
|
(type == EMPACK_TYPE_MAP32))
|
||||||
|
|
||||||
|
/** Macro for whether the given type is an array */
|
||||||
|
#define EMPACK_IS_ARRAY(type) ((type == EMPACK_TYPE_FIXARRAY) || \
|
||||||
|
(type == EMPACK_TYPE_ARRAY16) || \
|
||||||
|
(type == EMPACK_TYPE_ARRAY16))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize an empack struct, allowing it to be used for parsing. Calling this
|
* Initialize an empack struct, allowing it to be used for parsing. Calling this
|
||||||
* on a previously initialzed empack struct will effectively reset it.
|
* on a previously initialzed empack struct will effectively reset it.
|
||||||
|
|
@ -213,4 +228,12 @@ empack_status_e empack_parse(empack_t *empack, const void *msgpack, uint32_t len
|
||||||
*/
|
*/
|
||||||
empack_status_e empack_parse_one(empack_obj_t *object, const void *msgpack, uint32_t *len);
|
empack_status_e empack_parse_one(empack_obj_t *object, const void *msgpack, uint32_t *len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns Number of characters printed excluding the NULL terminator
|
||||||
|
*/
|
||||||
|
uint32_t empack_print(empack_t *empack,
|
||||||
|
void (*print_func)(const char *buf, uint32_t buflen, void *arg),
|
||||||
|
void *arg,
|
||||||
|
const char *indent);
|
||||||
|
|
||||||
#endif /* _EMPACK_H_ */
|
#endif /* _EMPACK_H_ */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue