Add yajl_gen_json5 option and generator support for special numbers

When this flag is set, the yajl_gen_double() routine can output
the values NaN, -Infinity and +Infinity.
This commit is contained in:
Andrew Johnson
2020-07-10 00:15:15 -05:00
parent 97b8df6912
commit baaf50c6d2
2 changed files with 31 additions and 6 deletions

View File

@@ -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;

View File

@@ -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,