Serializing and deserializing JSON with Boost Serializing and deserializing JSON with Boost json json

Serializing and deserializing JSON with Boost


Note that property_tree interprets the keys as paths, e.g. putting the pair "a.b"="z" will create an {"a":{"b":"z"}} JSON, not an {"a.b":"z"}. Otherwise, using property_tree is trivial. Here is a little example.

#include <sstream>#include <map>#include <boost/property_tree/ptree.hpp>#include <boost/property_tree/json_parser.hpp>using boost::property_tree::ptree;using boost::property_tree::read_json;using boost::property_tree::write_json;void example() {  // Write json.  ptree pt;  pt.put ("foo", "bar");  std::ostringstream buf;   write_json (buf, pt, false);  std::string json = buf.str(); // {"foo":"bar"}  // Read json.  ptree pt2;  std::istringstream is (json);  read_json (is, pt2);  std::string foo = pt2.get<std::string> ("foo");}std::string map2json (const std::map<std::string, std::string>& map) {  ptree pt;   for (auto& entry: map)       pt.put (entry.first, entry.second);  std::ostringstream buf;   write_json (buf, pt, false);   return buf.str();}


Boost versions 1.75 and later now have a robust native JSON library:

https://www.boost.org/doc/libs/develop/libs/json/doc/html/index.html

I don't suggest using Boost.PropertyTree's JSON algorithms anymore, as they are not fully compliant with the spec.


Some company asked me to implement JSON serialization library which is faster than boost lib. I did that - it is ~10x times faster then boost lib. I publish the code for anyone touse.

#pragma once#include <string>#include <vector>#include <regex>#include <fstream>enum class JsonNodeType { Array, Object, String };class JsonNode{    JsonNodeType m_nodeType;        std::vector<JsonNode*>* m_values{0};    std::vector<std::string>* m_keys{0};    std::string m_value{};    inline static int m_indent;    inline static bool m_formatOutput;    const int m_indentInc{4};public:    JsonNode(JsonNodeType type)     {        m_nodeType = type;                switch (m_nodeType) {            case JsonNodeType::Object: m_keys = new std::vector<std::string>();                                       [[fallthrough]];            case JsonNodeType::Array: m_values = new std::vector<JsonNode*>();        }    };    JsonNode(std::string value)     {        m_nodeType = JsonNodeType::String;        m_value = value;    }    ~JsonNode()     {        if (m_values)                   for (JsonNode* node : *m_values)                delete node;                        delete m_values;         delete m_keys;     }    void Add(JsonNode* node)     {                       assert(m_nodeType == JsonNodeType::Array);                m_values->push_back(node);    }    void Add(const char* key, JsonNode* node)     {               assert(m_nodeType == JsonNodeType::Object);        m_values->push_back(node);        m_keys->push_back(key);    }    void Add(const char* key, std::string value)     {               assert(m_nodeType == JsonNodeType::Object);        m_keys->push_back(key);        m_values->push_back(new JsonNode(value));    }    void Add(std::string value)     {        assert(m_nodeType == JsonNodeType::Array);        m_values->push_back(new JsonNode(value));    }    void Add(int value)     {        assert(m_nodeType == JsonNodeType::Array);        m_values->push_back(new JsonNode(std::to_string(value)));    }    void Add(const char* key, bool value)     {        assert(m_nodeType == JsonNodeType::Object);        m_keys->push_back(key);        m_values->push_back(new JsonNode(value ? "true" : "false"));    }    void OutputToStream(std::ostream& ofs, bool formatOutput = true)     {        m_indent = 0;               m_formatOutput = formatOutput;        OutputNodeToStream(ofs);        ofs << std::endl;    }    std::string EscapeString(std::string& str)     {           std::regex html2json("\\\\|\\/|\\\"");        std::regex newline("\n");        std::string tmp = std::regex_replace(str, html2json, "\\$&");           return std::regex_replace(tmp, newline, "\\n");    }private:     void OutputNodeToStream(std::ostream& ofs)     {        switch (m_nodeType) {            case JsonNodeType::String:                ofs << "\"" << m_value << "\"";                break;            case JsonNodeType::Object:                OutputObjectToStream(ofs);                break;            case JsonNodeType::Array:                OutputArrayToStream(ofs);                break;        }    }    void ChangeIndent(std::ostream& ofs, int indentDelta)     {        if (!m_formatOutput)            return;        m_indent += indentDelta;                ofs << std::endl;    }    void OutputIndents(std::ostream& ofs)     {        if (!m_formatOutput)            return;        for (int i = 0; i < m_indent; i++)            ofs << " ";    }    void OutputObjectToStream(std::ostream& ofs)     {        assert(m_nodeType == JsonNodeType::Object);        assert(m_keys->size() == m_values->size());        if (m_keys->empty())         {            ofs << "\"\"";            return;        }        ofs << "{";             ChangeIndent(ofs, m_indentInc);                for (int i = 0; i < m_keys->size(); i++)         {                        if (i > 0)                ofs << ",";            if (i > 0 && m_formatOutput)                ofs << std::endl;                        OutputIndents(ofs);            ofs << "\"" << m_keys->at(i) << "\": ";            m_values->at(i)->OutputNodeToStream(ofs);        }                   ChangeIndent(ofs, -m_indentInc);        OutputIndents(ofs);        ofs << "}";         }    void OutputArrayToStream(std::ostream& ofs)     {            assert(m_nodeType == JsonNodeType::Array);        if (m_values->empty())         {            ofs << "\"\"";            return;        }        ofs << "[";        ChangeIndent(ofs, m_indentInc);        for (int i = 0; i < m_values->size(); i++)         {            if (i > 0)                ofs << ",";            if(i > 0 && m_formatOutput)                ofs << std::endl;            OutputIndents(ofs);                     m_values->at(i)->OutputNodeToStream(ofs);        }                ChangeIndent(ofs, -m_indentInc);        OutputIndents(ofs);        ofs << "]";         }};

Usage examples

Create json tree:

JsonNode* Circuit::GetMyJson(){    JsonNode* node = new JsonNode(JsonNodeType::Object);    JsonNode* gates = new JsonNode(JsonNodeType::Array);    for (auto& [k, v] : m_gates)        gates->Add(v.GetMyJson());    node->Add("gates", gates);    return node;}

Output tree:

std::unique_ptr<JsonNode> node (simulation->GetMyJson());std::ofstream output("output.json", std::ios::out);node->OutputToStream(output);