Skip to content

castedo/jios

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JIOS : JSON Input Output Streams

Similar to C++ streams, but the stream elements are structured JSON data rather than characters.

Contents

  • Features
  • [Parsing Examples](#Parsing Examples)
  • [Printing Examples](#Printing Examples)
  • Dependencies
  • [Other Libraries](#Other Libraries)

Features

Incremental Streamed Parsing

Not all parsing of JSON has to happen at once, but rather parsing can be streamed before all JSON is available. This is similar to many SAX parsers, but with jios client code still calls jios and "pulls" data rather than being called like a SAX parser would.

Document Object Model (DOM) friendliness

JSON objects and arrays are represented by distinct C++ types and can be "walked" and iterated in for loops like a DOM interface.

Non-blocking Parsing of Asynchronous Data Sources

jios can be called assuming all data is available or the expecting method can be called to check whether jios is still expecting more data. This can be used in asynchronous code to determine parsing should performed later when more data is available.

Async Example

Parse Directly Into Strongly-types Data Structures

Source back-end do not have to construct entire json objects in memory and instead data can read data incrementally into custom strongly types C++ objects.

A template library (express.hpp) is included which makes it easy to declare the JSON object members to bind to C++ class members so that such C++ classes can immediately be read and written as JSON.

Expression Example

Interoperable with standard C++ streams

Three ways jios interoperates with C++ streams:

  • included back-end source and sink and read and write with C++ streams.
  • C++ types and have insertion (<<) and extraction (>>) defined for C++ streams automatically work with jios. This mechanism can be overloaded when C++ types should be represented as structures JSON rather than JSON strings.
  • The jios front-end provides syntactic sugar and semantics that are like C++ streams.

Separate Independent Back-ends

Streams are backed by source and sink back-ends which do not have to operate on textual JSON.

Interoperability with Google Protocol Buffers

C++ classes generated by Google Protocol Buffers are automatically readable and writable to any jios sources and sinks.

Parsing Examples

  istringstream ss("1 \"two\" 3");
  int i, j;
  string s;
  json_in(ss) >> i >> s >> j;

Use any type with the istream >> (extraction) operator defined

  using namespace boost::posix_time;
  istringstream ss("[\"00:01:03\", \"00:00:12\"]");
  time_duration t1, t2;
  ijarray ija = json_in(ss).get().array();
  ija >> t1 >> t2;
  cout << boolalpha << bool(t1 == seconds(63)) << ' '
                    << bool(t2 == seconds(12)) << endl;

outputs

  true true

Parse JSON arrays into standard containers

  istringstream ss("[1, 2, 3]");
  list<int> many;
  json_in(ss) >> many;
  list<int> expect = {1, 2, 3};
  cout << boolalpha << bool(many == expect) << endl;
outputs

true


### Iterate on JSON streams and arrays

```cpp
  istringstream ss("1 2 3 4 5");
  int sum = 0;
  for (ijvalue & v : json_in(ss)) {
    int i;
    if (v.read(i)) {
      sum += i;
    }
  }
  cout << sum << endl;

outputs

  15

JSON arrays are parsed as a stream and accessible incrementally

  stringstream ss;
  int i = 0;
  ss << "[";
  ijarray ija = json_in(ss).get().array();
  ss << "1 ";
  ija >> i;
  cout << i << endl;
  ss << ", 2 ";
  ija >> i;
  cout << i << endl;
  ss << "]";
  if (ija.at_end()) { cout << "Done!" << endl; }

outputs

  1
  2
  Done!

Iterate by name value pair on JSON objects

  stringstream ss;
  ss << R"( { "a":1, "b":2, "c":3 } )";
  int sum = 0;
  for (ijpair & nv : json_in(ss).get().object()) {
    int i;
    if (nv.read(i)) {
      sum += i;
    }
  }
  cout << sum << endl;

outputs

  6

Parse JSON object as stream of name value pairs

  stringstream ss;
  ss << R"( { "Joe":35, "Jane":33 } )";
  string name1, name2;
  int age1, age2;
  ijobject ijo = json_in(ss).get().object();
  ijo >> tie(name1, age1) >> tie(name2, age2);
  cout << name1 << " is " << age1 - age2 << " years older than "
       << name2 << endl;

outputs

  Joe is 2 years older than Jane 

Printing Examples

  jios::json_out(std::cout, '\n') << 1 << 2 << "three";

outputs

  1
  2
  "three"

In the rest of the examples assume

  using namespace std;
  using namespace jios;
  ojstream jout = json_out(cout);

JSON Arrays

  ojarray oja = jout.put().array();
  for (int i = 0; i < 3; ++i) {
    oja << i;
  }
  oja << endj;

outputs

  [0, 1, 2]

JSON Objects

  string b = "BEE";
  jout.put().object() << make_pair("one", 1) << tie("two", b) << endj;

outputs

  {"one":1, "two":"BEE"}

Use any type with the ostream << (insertion) operator defined

  using namespace boost::posix_time;
  jout.put().array() << seconds(3) << seconds(2) << seconds(1) << endj;

outputs

  ["00:00:03", "00:00:02", "00:00:01"]

Even use such types as JSON object keys.

  using namespace boost::posix_time;
  jout.put().object() << make_pair(seconds(3), "launch")
                      << make_pair(seconds(7), "explode") << endj;

outputs

  {"00:00:03":"launch", "00:00:07":"explode"}

Dependencies

  • C++11
  • boost
  • JSON-C
  • Google Protocol Buffers (optional)

Other Libraries

There are many C/C++ JSON libraries. www.json.org has a long list of such C and C++ libraries.

A few worth mentioning are

Releases

No releases published

Packages

No packages published