BDE 4.14.0 Production release
|
Provide utilities converting between bdld::Datum
and JSON data.
bdld::Datum
and JSON dataThis component provides a struct, baljsn::DatumUtil
, that is a namespace for a suite of functions that convert a bdld::Datum
into a JSON string, and back.
While most scalar types supported by Datum
can be encoded into a JSON string, only the subset of types represented natively in JSON – number (represented in C++ as a double
), string
, bool
, null
, array, and map types – will be populated in a Datum
decoded from a JSON string. If one were to encode a Datum
containing a type not natively supported by JSON, if that JSON string were decoded back into a Datum
object, the resulting Datum
would not be equal to the original value. For example, a Datum
containing an integer would be encoded into a JSON number, and then decoded back into a Datum
using double
to represent that number. Note that DatumUtil
uses a more permissive parser for numerical values than the strict JSON standard specifies. In particular, it is possible to parse NaN
, Inf
, or Infinity
into the corresponding singular double
values even though the JSON standard does not permit this, so applications should be ready to handle these kinds of values. Also note that the encode
routines do not encode these singular double
values in these parseable formats. Singular double
values will be rendered as strings (e.g., "+inf" or "nan") if the strictTypes
encoding configuration is false
, and will result generate an encoding error if strictTypes
is true
.
Clients wishing to ensure that encoding and then decoding results in a Datum
equal to the original value should use only Datum
types natively supported in JSON (see Supported Types , and ensure that duplicate keys are not present in the source Datum
(duplicate keys in a Datum
map are typically an error, but the interface does allow them to be created). Enabling the strictTypes
option verifies that the types in encoded JSON fields can be decoded back into Datum
fields of equal value. So, for example, enabling strictTypes
will result in encode
producing a positive return status if one of the encoded types is an int
, because decoding the resulting JSON will produce a double
. The strictTypes
option does not, however, verify that a Datum map contains unique keys. For double
fields, strictTypes
will result in encode
returning a positive value if a singular double
value is encountered, such as a NaN or Infinity.
The order of key/value pairs in objects in textual JSON passed to decode
is preserved in the decoded Datum
. If multiple entries with the same key
are present in an object, decode
will return the first such value.
The order of key/value pairs (DatumMapEntry
) in Datum
objects passed to encode
will be preserved in the resulting JSON
, and all keys/value pairs will be present (including duplicate keys). Duplicate keys will be rendered in an encoded JSON, even if strictTypes
checking is enabled. Note that a Datum map containing duplicate keys is typically an error (the result of a incorrectly constructed Datum), but the public interface for Datum does not disallow creating such a Datum
object.
The table below describes the set of types that a Datum
may be, whether it can be encode
d to JSON, and, if so, which JSON type will be decode
d if the value is read back in.
The encode
routines will return a negative (error) status if the input datum
contains any field that is not JSON-able
in this table.
If the DatumEncoderOptions
parameter is passed to an encode
routine and its strictTypes
field is true
, then encode
will return a positive value if any value is encoded where the dataType
and decode type
columns in this table are different (and therefore the strictTypes ok?
column is no
).
Datum
type value returned by the type()
encode
d by this component.encode
this value, if supported.Datum
type this encode
d value would be decode
d into.encode
will return 0 on success even if options->strictTypes()
is true
.This section illustrates intended use of this component.
The following example illustrates encoding a Datum
as a JSON string and then decoding that JSON string back into a Datum
object.
First, we create our Datum
object, using the bdld::DatumMaker
utility:
Then, we convert the books
Datum
to formatted JSON:
Next, we compare the result to the JSON we expect:
Finally, we can decode the booksJSON
and make sure we got the same value back:
The following example illustrates decoding a string into a Datum
object.
First, we create the JSON source, in both plain and formatted forms:
Then, we convert the single-line string
to a Datum
:
Next, we convert the formatted string
to another Datum
and make sure that the results match:
Finally, we make sure that the structure of the resulting datum is as we expect.
Notice that the type
of "age" is double
, since "age" was encoded as a number, and double
is the supported representation of a JSON number (see Supported Types .