mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
libxl_json: introduce parser functions for builtin types
This changeset introduces following functions:
* libxl_defbool_parse_json
* libxl__bool_parse_json
* libxl_uuid_parse_json
* libxl_mac_parse_json
* libxl_bitmap_parse_json
* libxl_cpuid_policy_list_parse_json
* libxl_string_list_parse_json
* libxl_key_value_list_parse_json
* libxl_hwcap_parse_json
* libxl__int_parse_json
* libxl__uint{8,16,32,64}_parse_json
* libxl__string_parse_json
They will be used in later patch to convert the libxl__json_object
tree of a builtin type to libxl_FOO struct.
Also remove declaration of libxl_domid_gen_json as libxl_domid uses
yajl_gen_integer to generate JSON object.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Anthony Perard <anthony.perard@citrix.com>
This commit is contained in:
1 parent
185123b72e
commit
752f181fef
4 files changed
+386
-17
No files matched your search
+73
-16
@@ -338,29 +338,29 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
|
||||
(const char**)(cpuid[i].policy), cpuid_res);
|
||||
}
|
||||
|
||||
static const char *input_names[2] = { "leaf", "subleaf" };
|
||||
static const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
|
||||
/*
|
||||
* Aiming for:
|
||||
* [
|
||||
* { 'leaf': 'val-eax',
|
||||
* 'subleaf': 'val-ecx',
|
||||
* 'eax': 'filter',
|
||||
* 'ebx': 'filter',
|
||||
* 'ecx': 'filter',
|
||||
* 'edx': 'filter' },
|
||||
* { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
|
||||
* ... etc ...
|
||||
* ]
|
||||
*/
|
||||
|
||||
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
|
||||
libxl_cpuid_policy_list *pcpuid)
|
||||
{
|
||||
libxl_cpuid_policy_list cpuid = *pcpuid;
|
||||
yajl_gen_status s;
|
||||
const char *input_names[2] = { "leaf", "subleaf" };
|
||||
const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Aiming for:
|
||||
* [
|
||||
* { 'leaf': 'val-eax',
|
||||
* 'subleaf': 'val-ecx',
|
||||
* 'eax': 'filter',
|
||||
* 'ebx': 'filter',
|
||||
* 'ecx': 'filter',
|
||||
* 'edx': 'filter' },
|
||||
* { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
|
||||
* ... etc ...
|
||||
* ]
|
||||
*/
|
||||
|
||||
s = yajl_gen_array_open(hand);
|
||||
if (s != yajl_gen_status_ok) goto out;
|
||||
|
||||
@@ -398,6 +398,63 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
|
||||
const libxl__json_object *o,
|
||||
libxl_cpuid_policy_list *p)
|
||||
{
|
||||
int i, size;
|
||||
libxl_cpuid_policy_list l;
|
||||
flexarray_t *array;
|
||||
|
||||
if (!libxl__json_object_is_array(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
array = libxl__json_object_get_array(o);
|
||||
if (!array->count)
|
||||
return 0;
|
||||
|
||||
size = array->count;
|
||||
/* need one extra slot as sentinel */
|
||||
l = *p = libxl__calloc(NOGC, size + 1, sizeof(libxl_cpuid_policy));
|
||||
|
||||
l[size].input[0] = XEN_CPUID_INPUT_UNUSED;
|
||||
l[size].input[1] = XEN_CPUID_INPUT_UNUSED;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
const libxl__json_object *t;
|
||||
int j;
|
||||
|
||||
if (flexarray_get(array, i, (void**)&t) != 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (!libxl__json_object_is_map(t))
|
||||
return ERROR_FAIL;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(l[0].input); j++) {
|
||||
const libxl__json_object *r;
|
||||
|
||||
r = libxl__json_map_get(input_names[j], t, JSON_INTEGER);
|
||||
if (!r)
|
||||
l[i].input[j] = XEN_CPUID_INPUT_UNUSED;
|
||||
else
|
||||
l[i].input[j] = libxl__json_object_get_integer(r);
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(l[0].policy); j++) {
|
||||
const libxl__json_object *r;
|
||||
|
||||
r = libxl__json_map_get(policy_names[j], t, JSON_STRING);
|
||||
if (!r)
|
||||
l[i].policy[j] = NULL;
|
||||
else
|
||||
l[i].policy[j] =
|
||||
libxl__strdup(NOGC, libxl__json_object_get_string(r));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -100,6 +100,42 @@ yajl_gen_status libxl_defbool_gen_json(yajl_gen hand,
|
||||
return libxl__yajl_gen_asciiz(hand, libxl_defbool_to_string(*db));
|
||||
}
|
||||
|
||||
int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_defbool *p)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
if (!libxl__json_object_is_string(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
s = libxl__json_object_get_string(o);
|
||||
|
||||
if (!strncmp(s, LIBXL__DEFBOOL_STR_DEFAULT,
|
||||
strlen(LIBXL__DEFBOOL_STR_DEFAULT)))
|
||||
p->val = LIBXL__DEFBOOL_DEFAULT;
|
||||
else if (!strncmp(s, LIBXL__DEFBOOL_STR_TRUE,
|
||||
strlen(LIBXL__DEFBOOL_STR_TRUE)))
|
||||
p->val = LIBXL__DEFBOOL_TRUE;
|
||||
else if (!strncmp(s, LIBXL__DEFBOOL_STR_FALSE,
|
||||
strlen(LIBXL__DEFBOOL_STR_FALSE)))
|
||||
p->val = LIBXL__DEFBOOL_FALSE;
|
||||
else
|
||||
return ERROR_FAIL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
bool *p)
|
||||
{
|
||||
if (!libxl__json_object_is_bool(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
*p = libxl__json_object_get_bool(o);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
|
||||
libxl_uuid *uuid)
|
||||
{
|
||||
@@ -108,6 +144,15 @@ yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
|
||||
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_UUID_FMTLEN);
|
||||
}
|
||||
|
||||
int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_uuid *p)
|
||||
{
|
||||
if (!libxl__json_object_is_string(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
return libxl_uuid_from_string(p, o->u.string);
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand,
|
||||
libxl_bitmap *bitmap)
|
||||
{
|
||||
@@ -128,6 +173,40 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_bitmap *p)
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
const libxl__json_object *t;
|
||||
flexarray_t *array;
|
||||
|
||||
if (!libxl__json_object_is_array(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
array = libxl__json_object_get_array(o);
|
||||
if (!array->count) {
|
||||
libxl_bitmap_init(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = libxl__json_array_get(o, array->count - 1);
|
||||
if (!libxl__json_object_is_integer(t))
|
||||
return ERROR_FAIL;
|
||||
size = libxl__json_object_get_integer(t) + 1;
|
||||
|
||||
libxl_bitmap_alloc(CTX, p, size);
|
||||
|
||||
for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
|
||||
if (!libxl__json_object_is_integer(t))
|
||||
return ERROR_FAIL;
|
||||
|
||||
libxl_bitmap_set(p, libxl__json_object_get_integer(t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
|
||||
libxl_key_value_list *pkvl)
|
||||
{
|
||||
@@ -155,6 +234,41 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
int libxl_key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_key_value_list *p)
|
||||
{
|
||||
libxl__json_map_node *node = NULL;
|
||||
flexarray_t *maps = NULL;
|
||||
int i, size;
|
||||
libxl_key_value_list kvl;
|
||||
|
||||
if (!libxl__json_object_is_map(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
maps = libxl__json_object_get_map(o);
|
||||
size = maps->count * 2;
|
||||
kvl = *p = libxl__calloc(NOGC, size, sizeof(char *));
|
||||
|
||||
for (i = 0; i < maps->count; i++) {
|
||||
int idx = i * 2;
|
||||
if (flexarray_get(maps, i, (void**)&node) != 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (!libxl__json_object_is_string(node->obj) &&
|
||||
!libxl__json_object_is_null(node->obj))
|
||||
return ERROR_FAIL;
|
||||
|
||||
kvl[idx] = libxl__strdup(NOGC, node->map_key);
|
||||
if (libxl__json_object_is_string(node->obj))
|
||||
kvl[idx+1] =
|
||||
libxl__strdup(NOGC, libxl__json_object_get_string(node->obj));
|
||||
else
|
||||
kvl[idx+1] = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *pl)
|
||||
{
|
||||
libxl_string_list l = *pl;
|
||||
@@ -176,6 +290,38 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_string_list *p)
|
||||
{
|
||||
const libxl__json_object *t;
|
||||
libxl_string_list l;
|
||||
flexarray_t *array = NULL;
|
||||
int i, size;
|
||||
|
||||
if (!libxl__json_object_is_array(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
array = libxl__json_object_get_array(o);
|
||||
size = array->count;
|
||||
|
||||
if (size == 0) {
|
||||
*p = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* need one extra slot as sentinel */
|
||||
l = *p = libxl__calloc(NOGC, size + 1, sizeof(char *));
|
||||
|
||||
for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
|
||||
if (!libxl__json_object_is_string(t))
|
||||
return ERROR_FAIL;
|
||||
|
||||
l[i] = libxl__strdup(NOGC, libxl__json_object_get_string(t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
|
||||
{
|
||||
char buf[LIBXL_MAC_FMTLEN+1];
|
||||
@@ -183,6 +329,15 @@ yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
|
||||
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_MAC_FMTLEN);
|
||||
}
|
||||
|
||||
int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_mac *p)
|
||||
{
|
||||
if (!libxl__json_object_is_string(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
return libxl__parse_mac(libxl__json_object_get_string(o), *p);
|
||||
}
|
||||
|
||||
yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand,
|
||||
libxl_hwcap *p)
|
||||
{
|
||||
@@ -201,6 +356,27 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_hwcap *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!libxl__json_object_is_array(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
for (i = 0; i<4; i++) {
|
||||
const libxl__json_object *t;
|
||||
|
||||
t = libxl__json_array_get(o, i);
|
||||
if (!t || !libxl__json_object_is_integer(t))
|
||||
return ERROR_FAIL;
|
||||
|
||||
(*p)[i] = libxl__json_object_get_integer(t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
yajl_gen_status libxl__string_gen_json(yajl_gen hand,
|
||||
const char *p)
|
||||
{
|
||||
@@ -210,6 +386,20 @@ yajl_gen_status libxl__string_gen_json(yajl_gen hand,
|
||||
return yajl_gen_null(hand);
|
||||
}
|
||||
|
||||
int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
char **p)
|
||||
{
|
||||
if (!libxl__json_object_is_string(o) && !libxl__json_object_is_null(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (libxl__json_object_is_null(o))
|
||||
*p = NULL;
|
||||
else
|
||||
*p = libxl__strdup(NOGC, libxl__json_object_get_string(o));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* libxl__json_object helper functions
|
||||
*/
|
||||
@@ -832,6 +1022,87 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p)
|
||||
{
|
||||
long long i;
|
||||
|
||||
if (!libxl__json_object_is_integer(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
i = libxl__json_object_get_integer(o);
|
||||
|
||||
if (i > INT_MAX || i < INT_MIN)
|
||||
return ERROR_FAIL;
|
||||
|
||||
*((int *)p) = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Macro to generate:
|
||||
* libxl__uint8_parse_json
|
||||
* libxl__uint16_parse_json
|
||||
* libxl__uint32_parse_json
|
||||
*/
|
||||
#define PARSE_UINT(width) \
|
||||
int libxl__uint ## width ## _parse_json(libxl__gc *gc, \
|
||||
const libxl__json_object *o,\
|
||||
void *p) \
|
||||
{ \
|
||||
long long i; \
|
||||
\
|
||||
if (!libxl__json_object_is_integer(o)) \
|
||||
return ERROR_FAIL; \
|
||||
\
|
||||
i = libxl__json_object_get_integer(o); \
|
||||
\
|
||||
if (i < 0 || i > UINT ## width ## _MAX) \
|
||||
return ERROR_FAIL; \
|
||||
\
|
||||
*((uint ## width ## _t *)p) = i; \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
PARSE_UINT(8);
|
||||
PARSE_UINT(16);
|
||||
PARSE_UINT(32);
|
||||
|
||||
int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p)
|
||||
{
|
||||
if (!libxl__json_object_is_integer(o) &&
|
||||
!libxl__json_object_is_number(o))
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (libxl__json_object_is_integer(o)) {
|
||||
long long i = libxl__json_object_get_integer(o);
|
||||
|
||||
if (i < 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
*((uint64_t *)p) = i;
|
||||
} else {
|
||||
const char *s;
|
||||
unsigned long long i;
|
||||
int saved_errno = errno;
|
||||
|
||||
s = libxl__json_object_get_number(o);
|
||||
|
||||
errno = 0;
|
||||
i = strtoull(s, NULL, 10);
|
||||
|
||||
if (i == ULLONG_MAX && errno == ERANGE)
|
||||
return ERROR_FAIL;
|
||||
|
||||
errno = saved_errno;
|
||||
*((uint64_t *)p) = i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -22,18 +22,52 @@
|
||||
# include <yajl/yajl_version.h>
|
||||
#endif
|
||||
|
||||
typedef struct libxl__gc libxl__gc;
|
||||
typedef struct libxl__json_object libxl__json_object;
|
||||
|
||||
yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val);
|
||||
yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
|
||||
yajl_gen_status libxl_domid_gen_json(yajl_gen hand, libxl_domid *p);
|
||||
int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_defbool *p);
|
||||
int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
bool *p);
|
||||
yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p);
|
||||
int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_uuid *p);
|
||||
yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *p);
|
||||
int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_mac *p);
|
||||
yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand, libxl_bitmap *p);
|
||||
int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_bitmap *p);
|
||||
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
|
||||
libxl_cpuid_policy_list *p);
|
||||
int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
|
||||
const libxl__json_object *o,
|
||||
libxl_cpuid_policy_list *p);
|
||||
yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *p);
|
||||
int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_string_list *p);
|
||||
yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
|
||||
libxl_key_value_list *p);
|
||||
int libxl_key_value_list_parse_json(libxl__gc *gc,
|
||||
const libxl__json_object *o,
|
||||
libxl_key_value_list *p);
|
||||
yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, libxl_hwcap *p);
|
||||
int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
libxl_hwcap *p);
|
||||
int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p);
|
||||
int libxl__uint8_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p);
|
||||
int libxl__uint16_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p);
|
||||
int libxl__uint32_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p);
|
||||
int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
void *p);
|
||||
int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
|
||||
char **p);
|
||||
|
||||
#include <_libxl_types_json.h>
|
||||
|
||||
|
||||
@@ -44,6 +44,13 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
|
||||
const libxl__json_object *o,
|
||||
libxl_cpuid_policy_list *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||