Provide a simple formatter for encoding data in the JSON format.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide a simple formatter for encoding data in the JSON format.
-
- Classes:
-
- See also:
- Component baljsn_encoder, Component baljsn_formatter, Component baljsn_printutil
-
- Description:
- This component provides a class,
baljsn::SimpleFormatter
, for rendering JSON conforming text for objects, arrays, and various scalar types.
- This component provides an interface that is easier to use, and renders more readable "pretty" JSON, than
baljsn::Formatter
. Clients are encouraged to use baljsn::SimpleFormatter
instead of baljsn::Formatter
(see Comparison to baljsn::Formatter
).
- The
SimpleFormatter
class
also provides the ability to specify formatting options at construction. The options that can be provided include the encoding style (compact or pretty), the initial indentation level and spaces per level if encoding in the pretty format.
-
- Comparison to baljsn::Formatter:
-
- API Comparison:
- Here is the side-by-side sequence of calls to create the following JSON using both components, assuming an existing stream
os
: {
"Object" : {
"Field 1" : 1,
"Field 2" : null
},
"Array" : [
1,
"string",
[],
[
[
{
}
]
]
],
"True" : true
}
Some extra indentation has been added in these examples to show the various open
/close
call nesting levels. Formatter | SimpleFormatter
-----------------------------------+----------------------------------------
baljsn::Formatter f(os); | baljsn::SimpleFormatter sf(os);
|
f.openObject(); | sf.openObject();
|
f.openMember("Object"); | sf.openObject("Object");
f.openObject(); | sf.addValue("Field 1", 1);
f.openMember("Field 1"); | sf.addNullValue("Field 2");
f.putValue(1); | sf.closeObject();
f.closeMember(); |
f.openMember("Field 2"); | sf.openArray("Array");
f.putNullValue(); | sf.addValue(1);
f.closeObject(); | sf.closeArray(e_EMPTY_ARRAY_FORMAT);
f.closeMember(); | sf.openArray();
| sf.openArray();
f.openMember("Array"); | sf.openObject();
f.openArray(); | sf.closeObject();
f.putValue(1); | sf.closeArray();
f.addArrayElementSeparator(); | sf.closeArray();
f.putValue("string"); | sf.closeArray();
f.addArrayElementSeparator(); |
f.openArray(true); | sf.addValue("True", true);
f.closeArray(true); | sf.closeObject();
f.addArrayElementSeparator(); |
f.openArray(); |
f.openArray(); |
f.openObject(); |
f.closeObject(); |
f.closeArray(); |
f.closeArray(); |
|
f.closeArray(); |
f.closeMember(); |
|
f.openMember("True"); |
f.putValue(true); |
|
f.closeObject(); |
-----------------------------------+----------------------------------------
- JSON Format ----------- The JSON encoding format (see http://json.org or ECMA-404 standard for more information) specifies a self-describing and simple syntax that is built on two structures:
-
Objects: JSON objects are represented as collections of name value pairs. The
SimpleFormatter
class
allows encoding objects by providing the openObject
and closeObject
methods to open and close an object and overloads for openObject
, openArray
, addValue
and addNullValue
which take a name
to specify the named fields in the object, or the use of the addMemberName
manipulator followed by the overloads of openObject
, openArray
, addValue
, and addNullValue
which do not take a name.
-
Arrays: JSON arrays are specified as an ordered list of values. The
SimpleFormatter
class
provides the openArray
and closeArray
method to open and close an array, as well as overloads for openObject
, openArray
, addValue
and addNullValue
which do not take a name
for array elements.
- The
SimpleFormatter
class
provides the ability to specify formatting options at construction. The options that can be provided include the encoding style (compact or pretty), the initial indentation level and spaces per level if encoding in the pretty format.
-
- Usage:
- This section illustrates intended use of this component.
-
- Example 1: Encoding a Stock Portfolio in JSON:
- Let us suppose we have to encode a JSON document containing information about a small portfolio of stocks. The eventual data we want to encode is represented by the following JSON string (which is the expected output of the encoding process):
- First, we specify the result that we are expecting to get:
{
const bsl::string EXPECTED = R"JSON({
"Stocks" : [
{
"Name" : "International Business Machines Corp",
"Ticker" : "IBM US Equity",
"Last Price" : 149.3,
"Dividend Yield" : 3.95
},
{
"Name" : "Apple Inc",
"Ticker" : "AAPL US Equity",
"Last Price" : 205.8,
"Dividend Yield" : 1.4
}
]
})JSON";
Then, to encode this JSON document we create a baljsn::SimpleFormatter
object. Since we want the document to be written in a pretty, easy to understand format we will specify true
for the usePrettyStyle
option and provide an appropriate initial indent level and spaces per level values: Next, we encode the start of the top level object, and open the first member "Stocks" (which holds an array of stock information): formatter.openObject();
formatter.openArray("Stocks");
Next, we render each element within the array of "Stocks" as an object that contains information for an individual stock: We now encode the other elements in the stock object. formatter.addValue("Name", "International Business Machines Corp");
formatter.addValue("Ticker", "IBM US Equity");
formatter.addValue("Last Price", 149.3);
formatter.addValue("Dividend Yield", 3.95);
Then, close the first stock object. Next, we add another stock object. formatter.openObject();
formatter.addValue("Name", "Apple Inc");
formatter.addValue("Ticker", "AAPL US Equity");
formatter.addValue("Last Price", 205.8);
formatter.addValue("Dividend Yield", 1.4);
formatter.closeObject();
Similarly, we can continue to format the rest of the document. For the purpose of this usage example we will complete this document. formatter.closeArray();
formatter.closeObject();
Once the formatting is complete the written data can be viewed from the stream passed to the formatter at construction. if (verbose)
bsl::cout << os.str() << bsl::endl;
Finally, verify the received result: assert(EXPECTED == os.str());
}
-
- Example 2: Encoding an array:
- Let us say we want to encode an array of various values.
- First, we create our
formatter
as we did above: Then we open our array. Next, we populate the array with a series of unnamed values. Named values are only used in objects, not arrays. formatter.addValue("First value");
formatter.addValue(2);
formatter.addValue(3);
Then, we demonstrate that arrays can be nested, opening another level of array, populating it, and closing it: formatter.openArray();
formatter.addValue("First value of inner array");
formatter.addValue(3.14159);
formatter.closeArray();
Arrays can also contain (unnamed) objects: Next, we add (named) values to our object: formatter.addValue("Greeting", "Hello from the first inner object");
formatter.addValue("PI approximation", 3.14);
Then we close the nested object: Finally, we close the outer array: formatter.closeArray();
}