A JSON parser in C++

Related tags

JSON jsonxx
Overview

JSON++

Build Status

Introduction

JSON++ is a light-weight JSON parser, writer and reader written in C++. JSON++ can also convert JSON documents into lossless XML documents.

Contributors

If you've made substantial contribution, please add your link here.

Why another JSON parser?

Perhaps because web service clients are usually written in dynamic languages these days, none of the existing C++ JSON parsers fitted my needs very well, so I wrote one that I used in another project. My goals for JSON++ were:

  • Efficient in both memory and speed.
  • No third party dependencies. JSON++ only depends on the standard C++ library.
  • Cross platform.
  • Robust.
  • Small and convenient API. Most of the time, you only need to call one function and two function templates.
  • Easy to integrate. JSON++ only has one source file and one header file. Just compile the source file and link with your program.
  • Able to construct documents dynamically.
  • JSON writer: write documents in JSON format.

Other contributors have sinced added more functionalities:

Compiler version

You need a modern C++ compiler. For older compilers, please try legacy branch.

Configuration

Strict/permissive parsing

JSONxx can parse JSON documents both in strict or permissive mode.

When jsonxx::Settings::Parser is set to Strict, JSONxx parser will accept:

  • Fully conformant JSON documents only.

When jsonxx::Settings::Parser is set to Permissive, JSONxx parser will accept:

  • Fully conformant JSON documents
  • Ending commas in arrays and objects: { "array": [0,1,2,], }
  • Single quoted strings: ['hello', "world"]
  • C++ style comments: { "width": 320, "height": 240 } //Picture details

Default value is Permissive.

When jsonxx::Settings::UnquotedKeys is set to Enabled, JSONxx parser will accept:

  • Unquoted keys: {name: "world"}

Default value is Disabled.

Assertions

JSONxx uses internally JSONXX_ASSERT(...) macro that works both in debug and release mode. Set jsonxx::Settings::Assertions value to Disabled to disable assertions.

Default value is Enabled.

Usage

The following snippets are from one of the unit tests. They are quite self-descriptive.

using namespace std;
using namespace jsonxx;

string teststr(
        "{"
        "  \"foo\" : 1,"
        "  \"bar\" : false,"
        "  \"person\" : {\"name\" : \"GWB\", \"age\" : 60,},"
        "  \"data\": [\"abcd\", 42],"
        "}"
);

// Parse string or stream
Object o;
assert(o.parse(teststr));

// Validation. Checking for JSON types and values as well
assert(1 == o.get<Number>("foo"));
assert(o.has<Boolean>("bar"));
assert(o.has<Object>("person"));
assert(o.get<Object>("person").has<Number>("age"));
assert(!o.get<Object>("person").has<Boolean>("old"));
assert(o.get<Object>("person").get<Boolean>("old", false));
assert(o.has<Array>("data"));
assert(o.get<Array>("data").get<Number>(1) == 42);
assert(o.get<Array>("data").get<String>(0) == "abcd");
assert(o.get<Array>("data").get<String>(2, "hello") == "hello");
assert(!o.has<Number>("data"));
cout << o.json() << endl;                     // JSON output
cout << o.xml(JSONx) << endl;                 // JSON to XML conversion (JSONx subtype)
cout << o.xml(JXML) << endl;                  // JSON to XML conversion (JXML subtype)
cout << o.xml(JXMLex) << endl;                // JSON to XML conversion (JXMLex subtype)
// Generate JSON document dynamically
using namespace std;
using namespace jsonxx;
Array a;
a << 123;
a << "hello world";
a << 3.1415;
a << 99.95f;
a << 'h';
a << Object("key", "value");
Object o;
o << "key1" << "value";
o << "key2" << 123;
o << "key3" << a;
cout << o.json() << endl;

To do

  • Custom JSON comments (C style /**/) when permissive parsing is enabled.
Comments
  • Parsing fails when empty lines are encountered

    Parsing fails when empty lines are encountered

    When parsing an empty line the parser stops parsing. An empty line is defined as a line that has no white-space.

    Simple test case:

    {
            string teststr("{\"name\": 10,\n\"file\":11}");
            istringstream input(teststr);
            Object o;
            TEST(o.parse(input));
            TEST(o.has<Number>("file")); // fails
    }
    
    bugs 
    opened by Rapptz 20
  • How to get array on top of valid JSON

    How to get array on top of valid JSON

    This is valid json data. But how can I get "var1" or "var2"?

      std::string json_str(
          "[ "
          "     \"var1\", "
          "     { \"id\" : \"1234\" }, "
          "     \"var2\", "
          "     \"var3\" "
          "] "
      );
    
    opened by phlegx 5
  • A valid json which not pass

    A valid json which not pass

    [JSONXX] expression 'read.size()' failed at jsonxx_test.cc:619 -> jsonxx_test: jsonxx.cc:29: void jsonxx::assertion(const char *, int, const char *, bool): Assertion `0' failed. My json is as following:

    { "string" : "lorem ipsum", "utf string" : "\u006corem\u0020ipsum", "utf-8 string": "あいうえお", "surrogate string": "lorem\uD834\uDD1Eipsum\uD834\uDF67lorem", "positive one" : 1, "negative one" : -1, "pi" : 3.14, "hard to parse number" : -3.14e-4, "big int": 2147483647, "big uint": 4294967295, "boolean true" : true, "boolean false" : false, "null" : null, "string array" : ["lorem", "ipsum"], "x^2 array" : [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100], "/" : null, "object" : { "nested string" : "str", "nested true" : true, "nested false" : false, "nested null" : null, "nested number" : 123, "nested array" : ["lorem", "ipsum"], "nested object" : {"lorem": "ipsum"} }, "/" : null, "/**/" : "comment", "//" : "comment", "url" : "https://www.example.com/search?q=12345", "escaped chars" : "" \ /", "empty object" : {}, "empty array" : [] }

    opened by frokaikan 4
  • Added ability to override merging when pushing arrays into arrays

    Added ability to override merging when pushing arrays into arrays

    Currently, an Array pushed into another Array via operator<< will merge into the target Array. Sometimes (probably most of the time) we want the Array to become a child instead. The update is fully backwards-compatible, as it only adds a single optional param that defaults to the original behaviour.

    To append a child Array A, instead of using operator<<, we call import(A, false).

    opened by AlexeiDrake 3
  • Not passing tests

    Not passing tests

    Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin13.0.2

    [JSONXX] expression 'v.parse(input)' failed at jsonxx_test.cc:171 -> Assertion failed: (0), function assertion, file jsonxx.cc, line 29.
    
    opened by Meekohi 3
  • Add default values

    Add default values

    This patch adds the ability to get default values for Object and Array without having to use has beforehand. It uses an identity meta-function so you still have to provide the template parameter for a consistent API.

    I added test cases (they all pass) and updated the README for example usage.

    Here is an example usage for brevity:

    #include <jsonxx.h>
    
    const std::string file("{ \"type\": \"basic\", \"list\": [\"string\", 10]  }");
    
    int main() {
        using namespace jsonxx;
        Object o;
        assert(o.parse(file));
        assert(!o.has<String>("file"));
        assert(o.get<String>("file", "test.txt") == "test.txt");
        assert(!o.get<Array>("list").has<Number>(2));
        assert(o.get<Array>("list").get<Number>(2, 10) == 10);
    }
    

    Also, I suggest switching to Markdown from Textile because it allows for syntax highlighting (which aids readability in my opinion). I don't actually know if Textile can syntax highlight.

    Hope this patch is useful. :)

    opened by Rapptz 3
  • Fix a compiler error

    Fix a compiler error

    So I realised where that attr parameter was used but they were actually default constructed strings so they really did have no use. I removed them to prevent a compilation error (oops :( ). I have triple checked that this compiles now so it should be good.

    One thing I noticed is that there is a lot of duplication of code for integral types using a macro. Would fixing that be desirable? Because if so then I wouldn't mind fixing that using the current JSONXX_COMPILER_HAS_CXX11 macro to detect C++11 and some slight (portable) template metaprogramming.

    opened by Rapptz 3
  • Array/list parsing issue

    Array/list parsing issue

    Hi, I'm currently attempting to use this library to parse the json output from the twitter API. So far this has been the easiest and cleanest json parser for C++ I've been able to find. After a while I found a huge problem though. When a 'tweet' contains geo information it partly failed to parse it. The place info in the raw json is listed below:

    {"place":{"full_name":"Limburg, The Netherlands","attributes":{},"name":"Limburg","place_type":"admin","bounding_box":{"type":"Polygon","coordinates":[[[5.5661376,50.750449],[6.2268848,50.750449],[6.2268848,51.7784841],[5.5661376,51.7784841]]]},"url":"http://api.twitter.com/1/geo/id/4ef0c00cbdff9ac8.json","country_code":"NL","id":"4ef0c00cbdff9ac8","country":"The Netherlands"}/* Normal tweet information */}

    I believe it mainly fails at the coordinates part. Now here is the even weirder part of it, listed below is a simple cout of the parsed object.

    {"bounding_box": {"coordinates": [[[5.56614, 50.7504], [6.22688, 50.7504], [6.22688, 51.7785], [5.56614, 51.7785]]], "type": "Polygon"}, "country": "The Netherlands", "country_code": "NL", "favorited": false, "id": "4ef0c00cbdff9ac8", "name": "Limburg", "place": {"full_name": "Limburg, The Netherlands"}, "place_type": "admin", "url": "http://api.twitter.com/1/geo/id/4ef0c00cbdff9ac8.json"/* Normal tweet information */}

    As you can see it doesn't have a place, it pretty much just put it's own info in the first level. Apart from this it's also just not parsing certain things in these situations. I'd highly appreciate it if this got fixed so I can happily use this json parser after all. Thanks in advance.

    Ps. as you can see I took some stuff out of the raw json to save a lot of space, if you need a full example on what it failed at just let me know.

    opened by schoentoon 3
  • Unexpected behavior using const char * variable

    Unexpected behavior using const char * variable

    First observed using the xtensa (Espressif) compiler. Same result using GCC on Ubuntu 64.

    $ gcc --version
    gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406
    Copyright (C) 2016 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    #include <stdio.h>
    #include <jsonxx.hpp>
    
    using namespace jsonxx;
    
    int main (int argc, char**argv) {
    
        const char * test = "abcmango";
    
        Object obj;
    
        obj << "test_1" << Value(test); 
        obj << "test_2" << test;
        obj << "test_3" << String(test);
    
        obj << "test_4" << Value("defbanana");
        obj << "test_5" << "defbanana";
        obj << "test_6" << String("defbanana");
    
        printf("%s\n", obj.json().c_str());
    }
    

    Observed output:

    {
    	"test_1": null,
    	"test_2": null,
    	"test_3": "abcmango",
    	"test_4": "defbanana",
    	"test_5": "defbanana",
    	"test_6": "defbanana" 
    } 
    
    

    Expected output:

    {
    	"test_1": "abcmango",
    	"test_2": "abcmango",
    	"test_3": "abcmango",
    	"test_4": "defbanana",
    	"test_5": "defbanana",
    	"test_6": "defbanana" 
    } 
    
    opened by MrSurly 2
  • cmake support

    cmake support

    I tried adding this myself, but encountered errors:

    [  1%] Linking CXX executable jsonxx
    /data/data/com.termux/files/usr/bin/../lib/crtbegin_dynamic.o: In function `_start':
    crtbegin.c:(.text+0x84): undefined reference to `main'
    clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)        make[2]: *** [lib/jsonxx/CMakeFiles/jsonxx.dir/build.make:95: lib/jsonxx/jsonxx] Error 1
    make[1]: *** [CMakeFiles/Makefile2:86: lib/jsonxx/CMakeFiles/jsonxx.dir/all] Error 2
    make: *** [Makefile:130: all] Error 2
    
    opened by lukeeey 2
  • Library improperly parses numbers

    Library improperly parses numbers

    For some reason false gets parsed by double long istream << as fa, but fails. Then when it gets passed on to check if its a boolean, the peek and get now return l instead of f. To fix this, I implemented an actual parser for numbers. I'm sure this isn't the best way to parse numbers, but I needed a fix asap:

    bool parse_number(std::istream& input, Number& value) {
        input >> std::ws;
        char digits[10] = {'0','1','2','3','4','5','6','7','8','9'};
    	size_t bI = 0;
    	int left = 0;
    	int right = 0;
    	bool hasDecimal = false;
    	
    	char ch;
    	while(input && !input.eof()){
    		ch = input.peek();
    		bool matchedDigit = false;
    		for(size_t i = 0; i < 10; i++){
    			if(ch == digits[i]){
    				if(hasDecimal){
    					right = (right * 10) + i;
    				}
    				else {
    					left = (left * 10) + i;
    				}
    				matchedDigit = true;
    				input.get();
    				bI++;
    				break;
    			}
    		}
    		if(matchedDigit)continue;
    		if(bI > 0 && ch == '.' && hasDecimal == false){
    			hasDecimal = true;
    			input.get();
    			bI++;
    		}
    		else {
    			break;
    		}
    	}
    	
    	if(bI > 0){
    		value = left + right * pow(10.0,log10(right) + 1);
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    opened by kkirby 2
  • Header version number is not up-to-date

    Header version number is not up-to-date

    Hi, I'm the maintainer of the jsonxx package for build2 (see https://cppget.org/jsonxx?q=jsonxx and https://github.com/build2-packaging/jsonxx). (I had to package it because it was used in a project at work which buildsystem we changed to build2 recently).

    I prepared the v1.0.1 package but we realized the header doesn't expose the right version number there: https://github.com/hjiang/jsonxx/blob/master/jsonxx.h#L22

    opened by Klaim 1
  • Any plans for initializer lists?

    Any plans for initializer lists?

    This would make writing JSON so much easy. Or even something like object.add( "key", "value") so we dont have to use object << "key" << "value" all the time

    suggestions 
    opened by lukeeey 0
  • Ordered object keys

    Ordered object keys

    Hey there,

    I'm using jsonxx for a project of mine, and I had a need for ordered object keys. I noticed here that you were intending on doing this:

    https://www.reddit.com/r/cpp/comments/1g40mu/jsonxx_is_a_lightweight_json_parser_writer_and/

    Since this hasn't been done yet, I took a stab at it real quick. Let me know what you think.

    -Greg

    opened by vicariousgreg 0
  • Fix parsing from std::cin (tellg/seekg are not working for it).

    Fix parsing from std::cin (tellg/seekg are not working for it).

    Hi there,

    I fixed parsing from std::cin. The problem was in tellg/seekg that break std::cin (and it looks they are not required at all, so I removed them).

    You can reproduce the issue with the following sample:

    #include "jsonxx.h"
    #include <iostream>
    
    using namespace std;
    using namespace jsonxx;
    
    int main()
    {
        Object o;
        o.parse(cin);
        cout << o.get<Array>("ar").get<Number>(0) << endl;
        return 0;
    }
    

    Send this json to stdin:

    { "ar" : [1] }
    
    opened by SergiusTheBest 3
  • std::string_view for parsing?

    std::string_view for parsing?

    I think it might be worth using std::string_view as a view into one large std::string that contains the whole document when parsing. This way there will only be 1 memory allocation.

    Only trouble is that string_view is still experimental so would probably have to wait for it to appear in the next standard.

    suggestions 
    opened by paulsapps 0
Releases(v1.0.1)
  • v1.0.1(Feb 21, 2021)

    • allow importing const char * as value
    • fix: when the input stream is configured to throw on error, an exception would be throw when parsing non-number values.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 20, 2021)

    This release is created due to user request. v1.x will include future bug fixes. I plan to make changes that utilize new C++ features when I have time, which will be in v2.x.

    Source code(tar.gz)
    Source code(zip)
Owner
Hong Jiang
Hong Jiang
Ultralightweight JSON parser in ANSI C

cJSON Ultralightweight JSON parser in ANSI C. Table of contents License Usage Welcome to cJSON Building Copying the source CMake Makefile Vcpkg Includ

Dave Gamble 8k Sep 29, 2022
JSON parser and generator for C/C++ with scanf/printf like interface. Targeting embedded systems.

JSON parser and emitter for C/C++ Features ISO C and ISO C++ compliant portable code Very small footprint No dependencies json_scanf() scans a string

Cesanta Software 622 Sep 24, 2022
JSON & BSON parser/writer

jbson is a library for building & iterating BSON data, and JSON documents in C++14. \tableofcontents Features # {#features} Header only. Boost license

Chris Manning 40 Sep 14, 2022
Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket

JSMN jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be easily integrated into resource-limited or embedded projects. You

Serge Zaitsev 3.1k Oct 3, 2022
A JSON parser in C++

JSON++ Introduction JSON++ is a light-weight JSON parser, writer and reader written in C++. JSON++ can also convert JSON documents into lossless XML d

Hong Jiang 488 Sep 13, 2022
🗄️ single header json parser for C and C++

??️ json.h A simple single header solution to parsing JSON in C and C++. JSON is parsed into a read-only, single allocation buffer. The current suppor

Neil Henning 513 Sep 24, 2022
Very low footprint JSON parser written in portable ANSI C

Very low footprint JSON parser written in portable ANSI C. BSD licensed with no dependencies (i.e. just drop the C file into your project) Never recur

James McLaughlin 1.2k Sep 30, 2022
Very simple C++ JSON Parser

Very simple JSON parser for c++ data.json: { "examples": [ { "tag_name": "a", "attr": [ { "key":

Amir Saboury 65 Sep 28, 2022
a JSON parser and printer library in C. easy to integrate with any model.

libjson - simple and efficient json parser and printer in C Introduction libjson is a simple library without any dependancies to parse and pretty prin

Vincent Hanquez 262 Sep 29, 2022
a header-file-only, JSON parser serializer in C++

PicoJSON - a C++ JSON parser / serializer Copyright © 2009-2010 Cybozu Labs, Inc. Copyright © 2011-2015 Kazuho Oku Licensed under 2-clause BSD license

Kazuho Oku 1k Sep 27, 2022
A fast JSON parser/generator for C++ with both SAX/DOM style API

A fast JSON parser/generator for C++ with both SAX/DOM style API Tencent is pleased to support the open source community by making RapidJSON available

Tencent 12.4k Sep 28, 2022
Lightweight, extremely high-performance JSON parser for C++11

sajson sajson is an extremely high-performance, in-place, DOM-style JSON parser written in C++. Originally, sajson meant Single Allocation JSON, but i

Chad Austin 541 Sep 16, 2022
🔋 In-place lightweight JSON parser

?? JSON parser for C This is very simple and very powerful JSON parser. It creates DOM-like data structure and allows to iterate and process JSON obje

Recep Aslantas 22 Sep 14, 2022
RapidJSON is a JSON parser and generator for C++.

A fast JSON parser/generator for C++ with both SAX/DOM style API

Tencent 12.4k Oct 2, 2022
single-header json parser for c99 and c++

ghh_json.h a single-header ISO-C99 (and C++ compatible) json loader. why? obviously this isn't the first json library written for C, so why would I wr

garrison hinson-hasty 15 May 26, 2022
Buggy JSON parser

Fuzzgoat: A minimal libFuzzer integration This repository contains a basic C project that includes an (intentionally insecure) JSON parser. It is an e

Fuzzbuzz 1 Apr 11, 2022
A generator of JSON parser & serializer C++ code from structure header files

JSON-CPP-gen This is a program that parses C++ structures from a header file and automatically generates C++ code capable of serializing said structur

Viktor Chlumský 10 Aug 20, 2022
Very low footprint JSON parser written in portable ANSI C

Very low footprint JSON parser written in portable C89 (sometimes referred to as ANSI C). BSD licensed with no dependencies (i.e. just drop the C file

null 1.2k Sep 30, 2022
A light-weight json parser.

pson pson is a lightweight parser and it support six type, null , bool, number, string, array, object, and it can parse the encoding of UTF-8. It's fa

pinK 17 Sep 9, 2022