|
DAW JSON Link
|
Parsing arrays is common and it is a fundamental data structure in JSON. It can be both the root object or a member.
The above JSON document contains an array of integers as the root object.
The C++ to parse this could look like
To see a working example of the following, refer to cookbook_array1_test.cpp The previous is a simple example, had the element type of the array been more complicated, such as a class, a data mapping would be required.
Here we hae a JSON array containing a class with members of type string, unsigned, float, and boolean.
The C++ data structures and the mapping could look like the following To see a working example using this code, refer to cookbook_array2_test.cpp
The above would construct MyClass4 with arguments of types std::string, unsigned, float, bool
Use the json_array member type in the member list to describe a member that is an array type.
To see a working example using this code, refer to cookbook_array3_test.cpp
The above JSON document, has an object root, with int, array of int, and an array of string members
The C++ data structures could look like the following
The json_data_contract specialization as follows
Use json_sized_array when an array's container needs a size supplied by another member of the same JSON object. This is useful for containers such as std::unique_ptr<T[]> that do not store their size.
The size mapping is passed to json_sized_array as its third template argument. Its constructor receives the parsed element range followed by that size. To see a working example, refer to test_json_sized_array.cpp.
The size member must be a named, non-nullable mapping in the same contract. Because input can request an arbitrarily large allocation or provide a size that disagrees with the array, custom constructors should enforce suitable resource limits and validate the number of parsed elements before returning. For serialization, expose pointer-like storage as a sized range such as daw::span; a pointer alone does not provide an end iterator.
Arrays often provide the recursive edge in an n-ary tree:
To see a working example, including serialization and round-trip parsing, refer to cookbook_array4_test.cpp.
A direct json_array<"children", TreeNode> mapping would require the TreeNode contract while that contract is still being defined. The json_recursive_class_no_name element mapping exposes the JSON object type without eagerly instantiating that contract. When parsing reaches a child, the outer contract is complete and can be used normally.
The empty children array supplies the recursion's base case, so no nullable or pointer wrapper is required. Parsing and serialization use the ordinary std::vector<TreeNode> value. As with any nested JSON representation, the structure must be acyclic.
For dealing with pointer like arrays(T *, has element_type type alias) see int_ptr_test
to_json_array writes its argument as a JSON array. C arrays are accepted along with containers. A char array is treated as a std::string_view of length N - 1, so each character is written as a one character string. Pointers have no length and are a compile error; pass a container or a daw::span instead.
Given
| Expression | Output |
|---|---|
to_json_array( "Hi\"" ) | ["H","i","\""] |
to_json_array( buffer ) | ["H","i","\""] |
to_json_array( "Hi\""sv ) | ["H","i","\""] |
to_json_array( ints ) | [1,2,3] |
to_json_array( std::vector<std::string_view>{ "A\"da" } ) | ["A\"da"] |
to_json_array( ptrs ) | [65,null] |
to_json_array( ptr ) with char const *ptr | compile error: pointers have no length |
As with to_json, character pointers inside a container are deduced as a nullable char. To write them as strings, give the element mapping explicitly: