diff --git a/modules/libcom/src/yajl/yajl_gen.c b/modules/libcom/src/yajl/yajl_gen.c index 80b32b3a6..3cffc9430 100644 --- a/modules/libcom/src/yajl/yajl_gen.c +++ b/modules/libcom/src/yajl/yajl_gen.c @@ -58,6 +58,7 @@ yajl_gen_config(yajl_gen g, int option, ...) switch(opt) { case yajl_gen_beautify: case yajl_gen_validate_utf8: + case yajl_gen_json5: if (va_arg(ap, int)) g->flags |= opt; else g->flags &= ~opt; break; @@ -213,10 +214,24 @@ yajl_gen_status yajl_gen_double(yajl_gen g, double number) { char i[32]; + int special = 1; ENSURE_VALID_STATE; ENSURE_NOT_KEY; - if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; + if (isnan(number)) { + strcpy(i, "NaN"); + } + else if (isinf(number)) { + sprintf(i, "%cInfinity", number < 0 ? '-' : '+'); + } + else { + special = 0; + sprintf(i, "%.20g", number); + if (strspn(i, "0123456789-") == strlen(i)) { + strcat(i, ".0"); + } + } + if (special && !(g->flags & yajl_gen_json5)) + return yajl_gen_invalid_number; INSERT_SEP; INSERT_WHITESPACE; - sprintf(i, "%.20g", number); g->print(g->ctx, i, (unsigned int)strlen(i)); APPENDED_ATOM; FINAL_NEWLINE; diff --git a/modules/libcom/src/yajl/yajl_gen.h b/modules/libcom/src/yajl/yajl_gen.h index 9afa46267..c142eeedf 100644 --- a/modules/libcom/src/yajl/yajl_gen.h +++ b/modules/libcom/src/yajl/yajl_gen.h @@ -98,7 +98,14 @@ extern "C" { * iterest of saving bytes. Setting this flag will cause YAJL to * always escape '/' in generated JSON strings. */ - yajl_gen_escape_solidus = 0x10 + yajl_gen_escape_solidus = 0x10, + /** + * Special numbers such as NaN and Infinity cannot be represented in + * the original JSON, but are permitted in JSON5. Setting this flag + * allows yajl_gen_double() to output the JSON5 representation of these + * special numbers instead of returning with an error. + */ + yajl_gen_json5 = 0x20, } yajl_gen_option; /** Allow the modification of generator options subsequent to handle @@ -122,9 +129,12 @@ extern "C" { /** Generate an integer number. */ YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number); - /** Generate a floating point number. \p number may not be infinity or - * NaN, as these have no representation in JSON. In these cases the - * generator will return \ref yajl_gen_invalid_number */ + /** generate a floating point number + * \param number the value to output, which may only be \c Infinity or \c NaN + * if the \ref yajl_gen_json5 flag is set, as these values + * have no legal representation in JSON. In these cases the + * generator will return \ref yajl_gen_invalid_number + */ YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number); /** Generate a number from the string given in \p num. */ YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand,