**Note:** Encoding any value may be useful in some scenarios, but
it's generally discouraged as it violates strict compatiblity with
:rfc:`4627`. If you use this flag, don't expect interoperatibility
- with other JSON systems. Even Jansson itself doesn't have any means
- to decode JSON texts whose root value is not object or array.
+ with other JSON systems.
.. versionadded:: 2.1
specification requires that a JSON text is either a serialized array
or object, and this requirement is also enforced with the following
functions. In other words, the top level value in the JSON text being
-decoded must be either array or object.
+decoded must be either array or object. To decode any JSON value, use
+the ``JSON_DECODE_ANY`` flag (see below).
See :ref:`rfc-conformance` for a discussion on Jansson's conformance
to the JSON specification. It explains many design decisions that
.. versionadded:: 2.1
+``JSON_DECODE_ANY``
+ By default, the decoder expects an array or object as the input.
+ With this flag enabled, the decoder accepts any valid JSON value.
+
+ **Note:** Decoding any value may be useful in some scenarios, but
+ it's generally discouraged as it violates strict compatiblity with
+ :rfc:`4627`. If you use this flag, don't expect interoperatibility
+ with other JSON systems.
+
+ .. versionadded:: 2.3
+
The following functions perform the actual JSON decoding.
.. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error)
multiple times, if the input consists of consecutive JSON texts,
possibly separated by whitespace.
+ If both ``JSON_DISABLE_EOF_CHECK`` and ``JSON_DECODE_ANY`` flags
+ are used, the decoder may read one extra UTF-8 code unit (up to 4
+ bytes of input). For example, decoding ``4true`` correctly decodes
+ the integer 4, but leaves the file position pointing at ``r``
+ instead of ``t``. For this reason, if reading multiple consecutive
+ values that are not arrays and objects, they should be separated by
+ at least one whitespace character.
+
.. function:: json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
.. refcounting:: new
json_t *result;
lex_scan(lex, error);
- if(lex->token != '[' && lex->token != '{') {
- error_set(error, lex, "'[' or '{' expected");
- return NULL;
+ if(!(flags & JSON_DECODE_ANY)) {
+ if(lex->token != '[' && lex->token != '{') {
+ error_set(error, lex, "'[' or '{' expected");
+ return NULL;
+ }
}
result = parse_value(lex, flags, error);
json_decref(json);
}
+static void decode_any()
+{
+ json_t *json;
+ json_error_t error;
+
+ json = json_loads("\"foo\"", JSON_DECODE_ANY, &error);
+ if (!json || !json_is_string(json))
+ fail("json_load decoded any failed - string");
+ json_decref(json);
+
+ json = json_loads("42", JSON_DECODE_ANY, &error);
+ if (!json || !json_is_integer(json))
+ fail("json_load decoded any failed - integer");
+ json_decref(json);
+
+ json = json_loads("true", JSON_DECODE_ANY, &error);
+ if (!json || !json_is_true(json))
+ fail("json_load decoded any failed - boolean");
+ json_decref(json);
+
+ json = json_loads("null", JSON_DECODE_ANY, &error);
+ if (!json || !json_is_null(json))
+ fail("json_load decoded any failed - null");
+ json_decref(json);
+}
+
static void load_wrong_args()
{
json_t *json;
file_not_found();
reject_duplicates();
disable_eof_check();
+ decode_any();
load_wrong_args();
}