JSON for Modern C++
 
 
 
 
Go to file
Niels 725202356b + fix memory issues 2014-12-29 12:51:20 +01:00
src + fix memory issues 2014-12-29 12:51:20 +01:00
test + another check 2014-12-28 22:59:11 +01:00
.gitignore + fix memory issues 2014-12-29 12:51:20 +01:00
.travis.yml + more test cases 2014-12-28 22:38:57 +01:00
Doxyfile 2.0 preview 2014-12-28 09:11:01 +01:00
Makefile.am + more test cases 2014-12-28 15:57:43 +01:00
README.md issue badge 2014-12-28 23:21:46 +01:00
configure.ac 2.0 preview 2014-12-28 09:11:01 +01:00

README.md

Yet another JSON class for C++

Build Status Coverage Status Github Issues

Design goals

There are myriads of JSON libraries out there, and each may even have its reason to exist. Our class had these design goals:

  • Trivial integration. Our whole code consists of just two files: A header file JSON.h and a source file JSON.cc. That's it. No library, no subproject, no dependencies. The class is written in vanilla C++11. All in all, the class should require no adjustment of your compiler flags or project settings.

  • Intuitive syntax. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of C++ to achieve the same feeling in your code. Check out the examples below and you know, what I mean.

Other aspects were not so important to us:

  • Memory efficiency. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). We use the following C++ data types: std::string for strings, int or double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans. We know that there are more efficient ways to store the values, but we are happy enough right now. And by the way: Valgrind says our code is free of leaks.

  • Speed. We currently implement the parser as naive recursive descent parser with hand coded string handling. It is fast enough, but a LALR-parser with a decent regular expression processor should be even faster (but would consist of more files which makes the integration harder).

  • Rigorous standard compliance. We followed the specification as close as possible, but did not invest too much in a 100% compliance with respect to Unicode support. As a result, there might be edge cases of false positives and false negatives, but as long as we have a hand-written parser, we won't invest too much to be fully compliant.

Integration

All you need to do is add

#include "JSON.h"

to the files you want to use JSON objects. Furthermore, you need to compile the file JSON.cc and link it to your binaries.

Examples

Here are some examples to give you an idea how to use the class:

// create an empty structure
JSON j;

// add a number that is stored as double
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add a null object
j["nothing"] = nullptr;

// add an object inside the object
j["further"]["entry"] = 42;

// add an array that is stored as std::vector
j["list"] = { 1, 0, 2 };

// add another object
j["object"] = { {"currency", "USD"}, {"value", "42.99"} };

Input / Output

// create object from stream
JSON j;
j << "{ \"pi\": 3.141, \"happy\": true }";

// write string representation to stream
std::cout << j;

These operators work for any subclasses of std::istream or std::ostream.

// create object from string literal
JSON j = "{ \"pi\": 3.141, \"happy\": true }"_json;

STL-like access

// create an array
JSON j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);

// iterate the array
for (JSON::iterator it = j.begin(); it != j.end(); ++it) {
  std::cout << *it << '\n';
}

// range-based for
for (auto element : j) {
  std::cout << element << '\n';
}

// getter/setter
const std::string tmp = j[0];
j[1] = 42;

// other stuff
j.size();     // 3
j.empty();    // false
j.type();     // JSON::valeu_type::array

// create an object
JSON o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

// find an entry
if (o.find("foo") != o.end()) {
  // there is an entry with key "foo"
}

// iterate the object
for (JSON::iterator it = o.begin(); it != o.end(); ++it) {
  std::cout << it.key() << ':' << it.value() << '\n';
}

Implicit conversions

The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted

/// strings
std::string s1 = "Hello, world!";
JSON js = s;
std::string s2 = j;

// Booleans
bool b1 = true;
JSON jb = b1;
bool b2 = jb;

// numbers
int i = 42;
JSON jn = i;
double f = jn;