BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdljsn.h
Go to the documentation of this file.
1/// @file bdljsn.h
2///
3///
4/// @defgroup bdljsn Package bdljsn
5/// @brief Basic Development Library JSoN (bdljsn)
6/// @addtogroup bdl
7/// @{
8/// @addtogroup bdljsn
9/// @{
10/// * <a href="#bdljsn-purpose"> Purpose</a>
11/// * <a href="#bdljsn-mnemonic"> Mnemonic </a>
12/// * <a href="#bdljsn-description"> Description </a>
13/// * <a href="#bdljsn-hierarchical-synopsis"> Hierarchical Synopsis </a>
14/// * <a href="#bdljsn-component-synopsis"> Component Synopsis </a>
15///
16/// # Purpose {#bdljsn-purpose}
17/// Provide a value-semantic JSON type and supporting utilities
18///
19/// # Mnemonic {#bdljsn-mnemonic}
20/// Basic Development Library JSoN (bdljsn)
21///
22/// # Description {#bdljsn-description}
23/// The 'bdljsn' package provides the 'bdljsn::Json' type, found in
24/// the @ref bdljsn_json component, which is a value-semantic representation of JSON
25/// data. This package also provides facilities for reading and writing
26/// 'bdljsn::Json' objects to JSON documents. 'bdljsn::Json' has close structural
27/// similarities to the JSON grammar itself, which looks like the following, at a
28/// high level:
29/// @code
30/// JSON ::= Object
31/// | Array
32/// | String
33/// | Number
34/// | Boolean
35/// | null
36/// @endcode
37/// Noting that the 'Object' and 'Array' alternatives can recursively contain
38/// 'JSON'. Just like this grammar, the value of a 'bdljsn::Json' object can be
39/// an object, array, string, number, boolean, or the null value. Objects and
40/// Arrays are represented by the 'bdljsn::JsonObject' and 'bdljsn::JsonArray'
41/// types, respectively, and are also provided by the @ref bdljsn_json component.
42/// 'bdljsn::JsonObject' is an associative container from strings to
43/// 'bdljsn::Json' objects, and 'bdljsn::JsonArray' is a sequence container with
44/// 'bdljsn::Json' elements. Strings and booleans are represented with the
45/// standard 'bsl::string' and 'bool' types. The singular "null" value is
46/// represented by the 'bdljsn::JsonNull' type, which has a single value like
47/// 'std::monostate'. Numbers are represented by the 'bdljsn::JsonNumber' type,
48/// which has facilities for storing any number that satisfies the JSON number
49/// grammar with arbitrary precision. It also provides operations for converting
50/// these arbitrary-precision numbers to common finite-precision number vocabulary
51/// types like 'int', 'double', and 'bdldfp::Decimal64', and detecting where
52/// overflow, underflow, and/or truncation would occur during conversion.
53///
54/// Though this package provides several types representing different kinds of
55/// JSON values, in general the 'bdljsn::Json' interface is rich enough to be the
56/// primary vocabulary type for working with JSON. For example, if the value
57/// stored in a 'bdljsn::Json' holds a JSON object, then you can use much of the
58/// associative container interface on the 'bdljsn::Json' object directly, e.g.,
59/// @code
60/// void getName(bsl::string *name, const bdljsn::Json& json)
61/// // Load to the specified 'name' the "name" member of the specified
62/// // 'json'. The behavior is undefined unless 'json' is a JSON object and
63/// // has a "name" member that is a string.
64/// {
65/// // First, verify that the 'json' is a JSON object, and not another
66/// // kind of value.
67/// assert(json.isObject());
68///
69/// // Then, we can use the subscript operator with string keys, just like a
70/// // map.
71/// *name = json["name"].theString();
72/// }
73/// @endcode
74/// Alternatively, if a 'bdljsn::Json' holds a JSON array, then we can use it like
75/// a sequence container,
76/// @code
77/// bool findWaldo(const bdljsn::Json& json)
78/// // Return 'true' if 'json' is an array that contains the string "waldo",
79/// // and return 'false' otherwise.
80/// {
81/// if (!json.isArray()) {
82/// return false; // RETURN
83/// }
84///
85/// for (bsl::size_t i = 0; i != json.size(); ++i) {
86/// const bdljsn::Json& element = json[i];
87///
88/// if (!element.isString()) {
89/// continue; // CONTINUE
90/// }
91///
92/// if (element.theString() == "waldo") {
93/// return true; // RETURN
94/// }
95/// }
96///
97/// return false;
98/// }
99/// @endcode
100/// For an example of constructing 'bdljsn::Json' objects, consider the use case
101/// where we have a simple representation of an organization chart, which we would
102/// like to convert to JSON for printing to standard output:
103/// @code
104/// struct Employee {
105/// // PUBLIC DATA
106/// int d_id;
107/// bsl::string d_firstName;
108/// bsl::string d_lastName;
109/// };
110///
111/// struct Team {
112/// // PUBLIC DATA
113/// Employee d_manager;
114/// bsl::vector<Employee> d_members;
115/// };
116/// @endcode
117/// We can define utility functions for converting these types to JSON:
118/// @code
119/// struct Utility {
120/// // CLASS METHODS
121/// static void toJson(bdljsn::Json *json, const Employee& employee)
122/// // Load to the specified 'json' the value of the specified 'employee'
123/// // converted to a JSON value.
124/// {
125/// bdljsn::Json& result = *json;
126///
127/// result.makeObject();
128///
129/// result["id"] = employee.d_id;
130/// result["firstName"] = employee.d_firstName;
131/// result["lastName"] = employee.d_lastName;
132/// }
133///
134/// static void toJson(bdljsn::Json *json, const Team& team)
135/// // Load to the specified 'json' the value of the specified 'team'
136/// // converted to a JSON value.
137/// {
138/// bdljsn::Json& result = *json;
139/// result.makeObject();
140///
141/// bdljsn::Json manager;
142/// toJson(&manager, team.d_manager);
143/// result["manager"] = bsl::move(manager);
144///
145/// bdljsn::Json members;
146/// members.makeArray();
147/// for (bsl::size_t i = 0; i != team.d_members.size(); ++i) {
148/// bdljsn::Json member;
149/// toJson(&member, team.d_members[i]);
150/// members[i] = bsl::move(member);
151/// }
152/// result["members"] = bsl::move(members);
153/// }
154/// };
155/// @endcode
156/// And then we can create a sample 'Team' and print it to standard output using
157/// our 'toJson' functions,
158/// @code
159/// void example()
160/// {
161/// Employee manager = { 1, "Michael", "Bloomberg" };
162/// Employee employee0 = { 2, "Peter", "Grauer" };
163/// Employee employee1 = { 3, "Tom", "Secunda" };
164///
165/// Team team;
166/// team.d_manager = manager;
167/// team.d_members.push_back(employee0);
168/// team.d_members.push_back(employee1);
169///
170/// bdljsn::Json teamAsJson;
171/// Utility::toJson(&teamAsJson, team);
172///
173/// // The following set of options to 'write' specify that we would prefer
174/// // the output to be pretty-printed.
175/// bdljsn::WriteOptions options;
176/// options.setStyle(bdljsn::WriteStyle::e_PRETTY);
177///
178/// int rc = bdljsn::JsonUtil::write(bsl::cout, teamAsJson, options);
179/// assert(0 == rc);
180/// }
181/// @endcode
182/// Then, we can observe the following printed to standard output:
183/// @code
184/// {
185/// "manager": {
186/// "id": 1,
187/// "firstName": "Michael",
188/// "lastName": "Bloomberg"
189/// },
190/// "members": [
191/// {
192/// "id": 2,
193/// "firstName": "Peter",
194/// "lastName": "Grauer"
195/// },
196/// {
197/// "id": 3,
198/// "firstName": "Tom",
199/// "lastName": "Secunda"
200/// }
201/// ]
202/// }
203/// @endcode
204///
205/// ## Hierarchical Synopsis {#bdljsn-hierarchical-synopsis}
206///
207/// The 'bdljsn' package currently has 15 components having 5 levels of physical
208/// dependency. The list below shows the hierarchical ordering of the components.
209/// The order of components within each level is not architecturally significant,
210/// just alphabetical.
211/// @code
212/// 5. bdljsn_jsonliterals
213///
214/// 4. bdljsn_jsonutil
215///
216/// 3. bdljsn_json
217///
218/// 2. bdljsn_error
219/// bdljsn_jsonnumber
220/// bdljsn_tokenizer
221/// bdljsn_writeoptions
222///
223/// 1. bdljsn_jsonnull
224/// bdljsn_jsontestsuiteutil
225/// bdljsn_jsontype
226/// bdljsn_location
227/// bdljsn_numberutil
228/// bdljsn_readoptions
229/// bdljsn_stringutil
230/// bdljsn_writestyle
231/// @endcode
232///
233/// ## Component Synopsis {#bdljsn-component-synopsis}
234///
235/// @ref bdljsn_error :
236/// Provide a description of an error processing a document.
237///
238/// @ref bdljsn_json :
239/// Provide an in-memory representation of a JSON document.
240///
241/// @ref bdljsn_jsonliterals :
242/// Provide user-defined literals for `bdljsn::Json` objects.
243///
244/// @ref bdljsn_jsonnull :
245/// Provide a type that represents the JSON `null` value.
246///
247/// @ref bdljsn_jsonnumber :
248/// Provide a value-semantic type representing a JSON number.
249///
250/// @ref bdljsn_jsontestsuiteutil :
251/// Provide JSON Test Suite for BDE table-driven testing.
252///
253/// @ref bdljsn_jsontype :
254/// Enumerate the set of JSON value types.
255///
256/// @ref bdljsn_jsonutil :
257/// Provide common non-primitive operations on `Json` objects.
258///
259/// @ref bdljsn_location :
260/// Provide a value-semantic type for location in a JSON document.
261///
262/// @ref bdljsn_numberutil :
263/// Provide utilities converting between JSON text and numeric types.
264///
265/// @ref bdljsn_readoptions :
266/// Provide options for reading a JSON document.
267///
268/// @ref bdljsn_stringutil :
269/// Provide a utility functions for JSON strings.
270///
271/// @ref bdljsn_tokenizer :
272/// Provide a tokenizer for extracting JSON data from a `streambuf`.
273///
274/// @ref bdljsn_writeoptions :
275/// Provide options for writing a JSON document.
276///
277/// @ref bdljsn_writestyle :
278/// Enumerate the formatting styles for a writing a JSON document.
279///
280/// @}
281/** @} */