Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component baljsn_encoder
[Package baljsn]

Provide a JSON encoder for bdlat-compatible types. More...

Namespaces

namespace  baljsn

Detailed Description

Outline
Purpose:
Provide a JSON encoder for bdlat-compatible types.
Classes:
baljsn::Encoder JSON decoder for bdlat-compliant types
See also:
Component baljsn_decoder, Component baljsn_printutil
Description:
This component provides a class, baljsn::Encoder, for encoding value-semantic objects in the JSON format. In particular, the class contains a parameterized encode function that encodes an object into a specified stream. There are two overloaded versions of this function:
  • one that writes to a bsl::streambuf
  • one that writes to an bsl::ostream
This component can be used with types that support the bdlat framework (see the bdlat package for details), which is a compile-time interface for manipulating struct-like and union-like objects. In particular, types generated by the bas_codegen.pl tool, and other dynamic types, can be encoded using this class. The encode function can be invoked on any object that satisfies the requirements of a sequence, choice, or array object as defined in the bdlat_sequencefunctions, bdlat_choicefunctions, and bdlat_arrayfunctions components.
Although the JSON format is easy to read and write and is very useful for debugging, it is relatively expensive to encode and decode and relatively bulky to transmit. It is more efficient to use a binary encoding (such as BER) if the encoding format is under your control (see balber_berencoder).
Refer to the details of the JSON encoding format supported by this encoder in the package documentation file (doc/baljsn.txt).
Usage:
This section illustrates intended use of this component.
Example 1: Encoding a bas_codegen.pl-Generated Object into JSON:
Consider that we want to exchange an employee's information between two processes. To allow this information exchange we will define the XML schema representation for that class, use bas_codegen.pl to create the Employee class for storing that information, populate an Employee object, and encode that object using the baljsn encoder.
First, we will define the XML schema inside a file called employee.xsd:
  <?xml version='1.0' encoding='UTF-8'?>
  <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
             xmlns:test='http://bloomberg.com/schemas/test'
             targetNamespace='http://bloomberg.com/schemas/test'
             elementFormDefault='unqualified'>

      <xs:complexType name='Address'>
          <xs:sequence>
              <xs:element name='street' type='xs:string'/>
              <xs:element name='city'   type='xs:string'/>
              <xs:element name='state'  type='xs:string'/>
          </xs:sequence>
      </xs:complexType>

      <xs:complexType name='Employee'>
          <xs:sequence>
              <xs:element name='name'        type='xs:string'/>
              <xs:element name='homeAddress' type='test:Address'/>
              <xs:element name='age'         type='xs:int'/>
          </xs:sequence>
      </xs:complexType>

      <xs:element name='Employee' type='test:Employee'/>

  </xs:schema>
Then, we will use the bas_codegen.pl tool, to generate the C++ classes for this schema. The following command will generate the header and implementation files for the all the classes in the test_messages components in the current directory:
  $ bas_codegen.pl -m msg -p test xsdfile.xsd
Next, we will populate a test::Employee object:
  test::Employee employee;
  employee.name()                 = "Bob";
  employee.homeAddress().street() = "Lexington Ave";
  employee.homeAddress().city()   = "New York City";
  employee.homeAddress().state()  = "New York";
  employee.age()                  = 21;
Then, we will create a baljsn::Encoder object:
  baljsn::Encoder encoder;
Now, we will output this object in the JSON format by invoking the encode method of the encoder. We will also create a baljsn::EncoderOptions object that allows us to specify that the encoding should be done in a pretty format, and what the initial indent level and spaces per level should be. We will then pass that object to the encode method:
  bsl::ostringstream os;

  baljsn::EncoderOptions options;
  options.setEncodingStyle(baljsn::EncoderOptions::e_PRETTY);
  options.setInitialIndentLevel(1);
  options.setSpacesPerLevel(4);

  const int rc = encoder.encode(os, employee, options);
  assert(!rc);
  assert(os);
Finally, we will verify that the output is as expected:
  const char EXP_OUTPUT[] = "    {\n"
                            "        \"name\" : \"Bob\",\n"
                            "        \"homeAddress\" : {\n"
                            "            \"street\" : \"Lexington Ave\",\n"
                            "            \"city\" : \"New York City\",\n"
                            "            \"state\" : \"New York\"\n"
                            "        },\n"
                            "        \"age\" : 21\n"
                            "    }\n";

  assert(EXP_OUTPUT == os.str());