|
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 encoded to JSON, and, if so, which JSON type will be decoded 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()encoded by this component.encode this value, if supported.Datum type this encoded value would be decoded 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 .