Merge pull request #123 from jjwchoy/decode-ignore-int
Implemented a decode option to only decode numbers to reals
This commit is contained in:
commit
8d439710cd
@ -950,6 +950,16 @@ macros can be ORed together to obtain *flags*.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
``JSON_DECODE_INT_AS_REAL``
|
||||
JSON defines only one number type. Jansson distinguishes between
|
||||
ints and reals. For more information see :ref:`real-vs-integer`.
|
||||
With this flag enabled the decoder interprets all numbers as real
|
||||
values. Integers that do not have an exact double representation
|
||||
will silently result in a loss of precision. Integers that cause
|
||||
a double overflow will cause an error.
|
||||
|
||||
.. versionadded:: 2.5
|
||||
|
||||
Each function also takes an optional :type:`json_error_t` parameter
|
||||
that is filled with error information if decoding fails. It's also
|
||||
updated on success; the number of bytes of input read is written to
|
||||
|
@ -38,6 +38,8 @@ strings.
|
||||
Numbers
|
||||
=======
|
||||
|
||||
.. _real-vs-integer:
|
||||
|
||||
Real vs. Integer
|
||||
----------------
|
||||
|
||||
@ -51,7 +53,8 @@ A JSON number is considered to be a real number if its lexical
|
||||
representation includes one of ``e``, ``E``, or ``.``; regardless if
|
||||
its actual numeric value is a true integer (e.g., all of ``1E6``,
|
||||
``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but
|
||||
will be treated as real values).
|
||||
will be treated as real values). With the ``JSON_DECODE_INT_AS_REAL``
|
||||
decoder flag set all numbers are interpreted as real.
|
||||
|
||||
All other JSON numbers are considered integers.
|
||||
|
||||
|
@ -236,9 +236,10 @@ json_t *json_deep_copy(json_t *value);
|
||||
|
||||
/* decoding */
|
||||
|
||||
#define JSON_REJECT_DUPLICATES 0x1
|
||||
#define JSON_DISABLE_EOF_CHECK 0x2
|
||||
#define JSON_DECODE_ANY 0x4
|
||||
#define JSON_REJECT_DUPLICATES 0x1
|
||||
#define JSON_DISABLE_EOF_CHECK 0x2
|
||||
#define JSON_DECODE_ANY 0x4
|
||||
#define JSON_DECODE_INT_AS_REAL 0x8
|
||||
|
||||
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
|
||||
|
||||
|
11
src/load.c
11
src/load.c
@ -775,6 +775,7 @@ error:
|
||||
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
||||
{
|
||||
json_t *json;
|
||||
double value;
|
||||
|
||||
switch(lex->token) {
|
||||
case TOKEN_STRING: {
|
||||
@ -783,7 +784,15 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
||||
}
|
||||
|
||||
case TOKEN_INTEGER: {
|
||||
json = json_integer(lex->value.integer);
|
||||
if (flags & JSON_DECODE_INT_AS_REAL) {
|
||||
if(jsonp_strtod(&lex->saved_text, &value)) {
|
||||
error_set(error, lex, "real number overflow");
|
||||
return NULL;
|
||||
}
|
||||
json = json_real(value);
|
||||
} else {
|
||||
json = json_integer(lex->value.integer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,28 @@ static void decode_any()
|
||||
json_decref(json);
|
||||
}
|
||||
|
||||
static void decode_int_as_real()
|
||||
{
|
||||
json_t *json;
|
||||
json_error_t error;
|
||||
|
||||
// This number cannot be represented exactly by a double
|
||||
const char *imprecise = "9007199254740993";
|
||||
json_int_t expected = 9007199254740992ll;
|
||||
|
||||
json = json_loads("42", JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY, &error);
|
||||
if (!json || !json_is_real(json) || json_real_value(json) != 42.0)
|
||||
fail("json_load decode int as real failed - int");
|
||||
json_decref(json);
|
||||
|
||||
// Tests that large numbers are handled correctly
|
||||
json = json_loads(imprecise, JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY,
|
||||
&error);
|
||||
if (!json || !json_is_real(json) || expected != json_real_value(json))
|
||||
fail("json_load decode int as real failed - expected imprecision");
|
||||
json_decref(json);
|
||||
}
|
||||
|
||||
static void load_wrong_args()
|
||||
{
|
||||
json_t *json;
|
||||
@ -132,6 +154,7 @@ static void run_tests()
|
||||
reject_duplicates();
|
||||
disable_eof_check();
|
||||
decode_any();
|
||||
decode_int_as_real();
|
||||
load_wrong_args();
|
||||
position();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user