[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] libxl: libxl_json: Handle number above LONG_MAX.
# HG changeset patch # User Anthony PERARD <anthony.perard@xxxxxxxxxx> # Date 1320410305 0 # Node ID c5fe74068253a21325ab880370db4c93b7017998 # Parent 8d06378f148709fcc5d4861cbc50b40934c5b273 libxl: libxl_json: Handle number above LONG_MAX. The integers are now "long long" in the json_object. If a number (decimal or integer) is too big (or too low), it is stored as it in a string. So for that, we introduce a new type JSON_NUMBER. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> Committed-by: Ian Jackson <ian.jackson.citrix.com> --- diff -r 8d06378f1487 -r c5fe74068253 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Nov 04 12:38:25 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Nov 04 12:38:25 2011 +0000 @@ -544,6 +544,8 @@ JSON_FALSE, JSON_INTEGER, JSON_DOUBLE, + /* number is store in string, it's too big to be a long long or a double */ + JSON_NUMBER, JSON_STRING, JSON_MAP, JSON_ARRAY, @@ -553,7 +555,7 @@ typedef struct libxl__json_object { libxl__json_node_type type; union { - long i; + long long i; double d; char *string; /* List of libxl__json_object */ @@ -612,7 +614,7 @@ else return NULL; } -static inline long libxl__json_object_get_integer(const libxl__json_object *o) +static inline long long libxl__json_object_get_integer(const libxl__json_object *o) { if (libxl__json_object_is_integer(o)) return o->u.i; diff -r 8d06378f1487 -r c5fe74068253 tools/libxl/libxl_json.c --- a/tools/libxl/libxl_json.c Fri Nov 04 12:38:25 2011 +0000 +++ b/tools/libxl/libxl_json.c Fri Nov 04 12:38:25 2011 +0000 @@ -14,6 +14,7 @@ #include <assert.h> #include <string.h> +#include <math.h> #include <yajl/yajl_parse.h> #include <yajl/yajl_gen.h> @@ -44,6 +45,7 @@ # define DEBUG_GEN(ctx, type) yajl_gen_##type(ctx->g) # define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value) # define DEBUG_GEN_STRING(ctx, str, n) yajl_gen_string(ctx->g, str, n) +# define DEBUG_GEN_NUMBER(ctx, str, n) yajl_gen_number(ctx->g, str, n) # define DEBUG_GEN_REPORT(yajl_ctx) \ do { \ const unsigned char *buf = NULL; \ @@ -60,6 +62,7 @@ # define DEBUG_GEN(ctx, type) ((void)0) # define DEBUG_GEN_VALUE(ctx, type, value) ((void)0) # define DEBUG_GEN_STRING(ctx, value, lenght) ((void)0) +# define DEBUG_GEN_NUMBER(ctx, value, lenght) ((void)0) # define DEBUG_GEN_REPORT(ctx) ((void)0) #endif @@ -363,6 +366,7 @@ return; switch (obj->type) { case JSON_STRING: + case JSON_NUMBER: free(obj->u.string); break; case JSON_MAP: { @@ -504,36 +508,64 @@ return 1; } -static int json_callback_integer(void *opaque, long value) +static bool is_decimal(const char *s, unsigned len) +{ + const char *end = s + len; + for (; s < end; s++) { + if (*s == '.') + return true; + } + return false; +} + +static int json_callback_number(void *opaque, const char *s, unsigned int len) { libxl__yajl_ctx *ctx = opaque; - libxl__json_object *obj; + libxl__json_object *obj = NULL; + char *t = NULL; - DEBUG_GEN_VALUE(ctx, integer, value); + DEBUG_GEN_NUMBER(ctx, s, len); - if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL) + if (is_decimal(s, len)) { + double d = strtod(s, NULL); + + if ((d == HUGE_VAL || d == HUGE_VAL) && errno == ERANGE) { + goto error; + } + + if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL) + return 0; + obj->u.d = d; + } else { + long long i = strtoll(s, NULL, 10); + + if ((i == LLONG_MIN || i == LLONG_MAX) && errno == ERANGE) { + goto error; + } + + if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL) + return 0; + obj->u.i = i; + } + goto out; + +error: + /* If the conversion fail, we just store the original string. */ + if ((obj = json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL) return 0; - obj->u.i = value; - if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { - libxl__json_object_free(ctx->gc, obj); + t = malloc(len + 1); + if (t == NULL) { + LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR, + "Failed to allocate"); return 0; } + strncpy(t, s, len); + t[len] = 0; - return 1; -} + obj->u.string = t; -static int json_callback_double(void *opaque, double value) -{ - libxl__yajl_ctx *ctx = opaque; - libxl__json_object *obj; - - DEBUG_GEN_VALUE(ctx, double, value); - - if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL) - return 0; - obj->u.d = value; - +out: if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; @@ -706,9 +738,9 @@ static yajl_callbacks callbacks = { json_callback_null, json_callback_boolean, - json_callback_integer, - json_callback_double, NULL, + NULL, + json_callback_number, json_callback_string, json_callback_start_map, json_callback_map_key, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |