This commit is contained in:
CismonX 2018-03-10 10:28:54 +08:00
commit f7a7e6ce39
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
3 changed files with 258 additions and 0 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 CismonX
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

65
README.md Normal file
View File

@ -0,0 +1,65 @@
# boost-helper-json
A simple wrapper around `Boost.PropertyTree` for quick & dirty JSON access.
## 1. Introduction
If you're working with JSON on C++ and looking for a good library, I'd recommend [RapidJSON](http://rapidjson.org/) or [JSON for Modern C++](https://nlohmann.github.io/json/). They are fast and scalable, and provide loads of useful functionalities.
However, if you're just looking for a quick and dirty workaround, and happen to be using the Boost C++ libraries in your project, this may be an option for you.
Just include the header, and start hacking with JSON.
## 2. Example
```c++
#include "json.hpp"
#include <iostream>
#include <string>
int main()
{
using namespace boost_helper;
// Initialize JSON with a string.
json response(R"({"err":0,"data":{"msg":"ok","names":["John","Sarah"]}})");
// Changing a node value with a string.
response["data"]["msg"] = "confirmed";
// Check whether this node has a child with the specified key.
if (response.has("err"))
{
// Changing a node value with another JSON node.
response["err"] = json(R"({"code":0,"status":"ok"})");
}
// Access child node value of a JSON.
std::cout << "Now message becomes \"" << response["data"]["msg"].val() << '"' << std::endl;
// Iterate through a JSON node.
for (const auto& name : response["data"]["names"])
{
std::cout << name.second.val() << " said hello!" << std::endl;
}
// Iterate througth a JSON node and change its children's values.
for (auto name : response["data"]["names"])
{
name.second = "Nobody";
}
// Compare a JSON node with another node.
if (response["data"]["names"] == json(R"(["Nobody","Nobody"])"))
{
// Add a child string to a JSON node without key.
response["data"]["names"].add("Somebody");
}
// Add a child node to a JSON node without key.
response["data"]["names"].add(json(R"(["Paul","Joshua"])"));
// Print a JSON node.
std::cout << response.to_string() << std::endl;
}
```

172
json.hpp Normal file
View File

@ -0,0 +1,172 @@
#pragma once
#include <boost/property_tree/json_parser.hpp>
namespace boost_helper
{
/**
* A simple wrapper around Boost.PropertyTree for quick & dirty JSON access.
*
* @author CismonX
*/
class json
{
using ptree = boost::property_tree::ptree;
/// The Boost.PropertyTree instance with stores this JSON structure.
ptree* data_;
/// Whether this is the node root of JSON object.
bool is_root_ = false;
public:
/// Trying to modify the value of root node of JSON.
class root_modification_exception : public std::exception {};
/// Range-based for support.
class iterator : public ptree::iterator
{
public:
explicit iterator(const ptree::iterator& other) : ptree::iterator(other) {}
std::pair<std::string, json> operator*() const
{
return make_pair(dereference().first, json(&dereference().second));
}
};
/**
* Iterator begin.
*/
iterator begin() const
{
return iterator(data_->begin());
}
/**
* Iterator end.
*/
iterator end() const
{
return iterator(data_->end());
}
/**
* Create a new JSON object with the given string.
*/
explicit json(const std::string& json_str) : is_root_(true)
{
data_ = new ptree;
std::istringstream stream(json_str);
read_json(stream, *data_);
}
/**
* Create a JSON object with a ptree node.
*/
explicit json(boost::property_tree::ptree* other) : data_(other) {}
/**
* Assign the value of this node with another node.
* @throws root_modification_exception : thrown when trying to modify a non-root node.
*/
json& operator=(const json& other)
{
if (is_root_)
throw root_modification_exception();
*data_ = *other.data_;
return *this;
}
/**
* Assign the value of this node with a string.
* @throws root_modification_exception : thrown when trying to modify a non-root node.
*/
json& operator=(const std::string& value)
{
if (is_root_)
throw root_modification_exception();
data_->put_value(value);
return *this;
}
/**
* Whether this node is equal to another node.
*/
bool operator==(const json& other) const
{
return *data_ == *other.data_;
}
/**
* Whether this node is not equal to another node.
*/
bool operator!=(const json& other) const
{
return *data_ != *other.data_;
}
/**
* Get child node.
*/
json operator[](const std::string& key) const
{
if (data_->find(key) == data_->not_found())
data_->add_child(key, boost::property_tree::ptree());
return json(&data_->get_child(key));
}
/**
* Add a string element to this node without key.
*/
void add(const std::string& value)
{
ptree element;
element.put_value(value);
data_->push_back(make_pair("", element));
}
/**
* Add a child node to this node without key.
*/
void add(const json& value)
{
data_->push_back(make_pair("", *value.data_));
}
/**
* Get string value of this node.
*/
std::string val() const
{
return data_->get_value<std::string>();
}
/**
* Check whether this node has a child with the specified key.
*/
bool has(const std::string& key) const
{
return data_->find(key) != data_->not_found();
}
/**
* Print this JSON node to a string.
*/
std::string to_string(bool pretty = false) const
{
std::ostringstream stream;
write_json(stream, *data_, pretty);
return stream.str();
}
/**
* Destructor.
*/
~json()
{
if (is_root_)
delete data_;
}
};
}