Quick Links:

bal | bbl | bdl | bsl

Components

Package bdljsn
[Package Group bdl]

Provide a value-semantic JSON type and supporting utilities. More...

Components

 Component bdljsn_error
 

Provide a description of an error processing a document.

 Component bdljsn_json
 

Provide an in-memory representation of a JSON document.

 Component bdljsn_jsonliterals
 

Provide user-defined literals for bdljsn::Json objects.

 Component bdljsn_jsonnull
 

Provide a type that represents the JSON null value.

 Component bdljsn_jsonnumber
 

Provide a value-semantic type representing a JSON number.

 Component bdljsn_jsontype
 

Enumerate the set of JSON value types.

 Component bdljsn_jsonutil
 

Provide common non-primitive operations on Json objects.

 Component bdljsn_location
 

Provide a value-semantic type for location in a JSON document.

 Component bdljsn_numberutil
 

Provide utilities converting between JSON text and numeric types.

 Component bdljsn_readoptions
 

Provide options for reading a JSON document.

 Component bdljsn_stringutil
 

Provide a utility functions for JSON strings.

 Component bdljsn_tokenizer
 

Provide a tokenizer for extracting JSON data from a streambuf.

 Component bdljsn_writeoptions
 

Provide options for writing a JSON document.

 Component bdljsn_writestyle
 

Enumerate the formatting styles for a writing a JSON document.


Detailed Description

Outline
Purpose:
Provide a value-semantic JSON type and supporting utilities
MNEMONIC: Basic Development Library JSoN (bdljsn):
Description:
The bdljsn package provides the bdljsn::Json type, found in the bdljsn_json component, which is a value-semantic representation of JSON data. This package also provides facilities for reading and writing bdljsn::Json objects to JSON documents. bdljsn::Json has close structural similarities to the JSON grammar itself, which looks like the following, at a high level:
  JSON ::= Object
         | Array
         | String
         | Number
         | Boolean
         | null
Noting that the Object and Array alternatives can recursively contain JSON. Just like this grammar, the value of a bdljsn::Json object can be an object, array, string, number, boolean, or the null value. Objects and Arrays are represented by the bdljsn::JsonObject and bdljsn::JsonArray types, respectively, and are also provided by the bdljsn_json component. bdljsn::JsonObject is an associative container from strings to bdljsn::Json objects, and bdljsn::JsonArray is a sequence container with bdljsn::Json elements. Strings and booleans are represented with the standard bsl::string and bool types. The singular "null" value is represented by the bdljsn::JsonNull type, which has a single value like std::monostate. Numbers are represented by the bdljsn::JsonNumber type, which has facilities for storing any number that satisfies the JSON number grammar with arbitrary precision. It also provides operations for converting these arbitrary-precision numbers to common finite-precision number vocabulary types like int, double, and bdldfp::Decimal64, and detecting where overflow, underflow, and/or truncation would occur during conversion.
Though this package provides several types representing different kinds of JSON values, in general the bdljsn::Json interface is rich enough to be the primary vocabulary type for working with JSON. For example, if the value stored in a bdljsn::Json holds a JSON object, then you can use much of the associative container interface on the bdljsn::Json object directly, e.g.,
  void getName(bsl::string *name, const bdljsn::Json& json)
      // Load to the specified 'name' the "name" member of the specified
      // 'json'.  The behavior is undefined unless 'json' is a JSON object and
      // has a "name" member that is a string.
  {
      // First, verify that the 'json' is a JSON object, and not another
      // kind of value.
      assert(json.isObject());

      // Then, we can use the subscript operator with string keys, just like a
      // map.
      *name = json["name"].theString();
  }
Alternatively, if a bdljsn::Json holds a JSON array, then we can use it like a sequence container,
  bool findWaldo(const bdljsn::Json& json)
      // Return 'true' if 'json' is an array that contains the string "waldo",
      // and return 'false' otherwise.
  {
      if (!json.isArray()) {
          return false;                                               // RETURN
      }

      for (bsl::size_t i = 0; i != json.size(); ++i) {
          const bdljsn::Json& element = json[i];

          if (!element.isString()) {
              continue;                                             // CONTINUE
          }

          if (element.theString() == "waldo") {
              return true;                                            // RETURN
          }
      }

      return false;
  }
For an example of constructing bdljsn::Json objects, consider the use case where we have a simple representation of an organization chart, which we would like to convert to JSON for printing to standard output:
  struct Employee {
      // PUBLIC DATA
      int         d_id;
      bsl::string d_firstName;
      bsl::string d_lastName;
  };

  struct Team {
      // PUBLIC DATA
      Employee              d_manager;
      bsl::vector<Employee> d_members;
  };
We can define utility functions for converting these types to JSON:
  struct Utility {
      // CLASS METHODS
      static void toJson(bdljsn::Json *json, const Employee& employee)
          // Load to the specified 'json' the value of the specified 'employee'
          // converted to a JSON value.
      {
          bdljsn::Json& result = *json;

          result.makeObject();

          result["id"]        = employee.d_id;
          result["firstName"] = employee.d_firstName;
          result["lastName"]  = employee.d_lastName;
      }

      static void toJson(bdljsn::Json *json, const Team& team)
          // Load to the specified 'json' the value of the specified 'team'
          // converted to a JSON value.
      {
          bdljsn::Json& result = *json;
          result.makeObject();

          bdljsn::Json manager;
          toJson(&manager, team.d_manager);
          result["manager"] = bsl::move(manager);

          bdljsn::Json members;
          members.makeArray();
          for (bsl::size_t i = 0; i != team.d_members.size(); ++i) {
              bdljsn::Json member;
              toJson(&member, team.d_members[i]);
              members[i] = bsl::move(member);
          }
          result["members"] = bsl::move(members);
      }
  };
And then we can create a sample Team and print it to standard output using our toJson functions,
  void example()
  {
      Employee manager = { 1, "Michael", "Bloomberg" };
      Employee employee0 = { 2, "Peter", "Grauer" };
      Employee employee1 = { 3, "Tom", "Secunda" };

      Team team;
      team.d_manager = manager;
      team.d_members.push_back(employee0);
      team.d_members.push_back(employee1);

      bdljsn::Json teamAsJson;
      Utility::toJson(&teamAsJson, team);

      // The following set of options to 'write' specify that we would prefer
      // the output to be pretty-printed.
      bdljsn::WriteOptions options;
      options.setStyle(bdljsn::WriteStyle::e_PRETTY);

      int rc = bdljsn::JsonUtil::write(bsl::cout, teamAsJson, options);
      assert(0 == rc);
  }
Then, we can observe the following printed to standard output:
  {
      "manager": {
          "id": 1,
          "firstName": "Michael",
          "lastName": "Bloomberg"
      },
      "members": [
          {
              "id": 2,
              "firstName": "Peter",
              "lastName": "Grauer"
          },
          {
              "id": 3,
              "firstName": "Tom",
              "lastName": "Secunda"
          }
      ]
  }
Hierarchical Synopsis:
The bdljsn package currently has 14 components having 5 levels of physical dependency. The list below shows the hierarchical ordering of the components. The order of components within each level is not architecturally significant, just alphabetical.
  5. bdljsn_jsonliterals

  4. bdljsn_jsonutil

  3. bdljsn_json

  2. bdljsn_error
     bdljsn_jsonnumber
     bdljsn_writeoptions

  1. bdljsn_jsonnull
     bdljsn_jsontype
     bdljsn_location
     bdljsn_numberutil
     bdljsn_readoptions
     bdljsn_stringutil
     bdljsn_tokenizer
     bdljsn_writestyle
Component Synopsis:
bdljsn_error:
Provide a description of an error processing a document.
bdljsn_json:
Provide an in-memory representation of a JSON document.
bdljsn_jsonliterals:
Provide user-defined literals for bdljsn::Json objects.
bdljsn_jsonnull:
Provide a type that represents the JSON null value.
bdljsn_jsonnumber:
Provide a value-semantic type representing a JSON number.
bdljsn_jsontype:
Enumerate the set of JSON value types.
bdljsn_jsonutil:
Provide common non-primitive operations on Json objects.
bdljsn_location:
Provide a value-semantic type for location in a JSON document.
bdljsn_numberutil:
Provide utilities converting between JSON text and numeric types.
bdljsn_readoptions:
Provide options for reading a JSON document.
bdljsn_stringutil:
Provide a utility functions for JSON strings.
bdljsn_tokenizer:
Provide a tokenizer for extracting JSON data from a streambuf.
bdljsn_writeoptions:
Provide options for writing a JSON document.
bdljsn_writestyle:
Enumerate the formatting styles for a writing a JSON document.