json11阅读
概要:json11是一个基于c++11的json解析库,dropbox出品。
使用
直接举自带单元测试test.cpp中的例子:
const string simple_test =
R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";
string err;
const auto json = Json::parse(simple_test, err);
std::cout << "k1: " << json["k1"].string_value() << "\n";
std::cout << "k3: " << json["k3"].dump() << "\n";
for (auto &k : json["k3"].array_items()) {
std::cout << " - " << k.dump() << "\n";
}
Json::parse
可以解析string字符串生成Json对象,dump()
则将Json对象格式化为字符串形式。
Json类提供了多种构造函数,用来构造Json对象:
const Json obj = Json::object({
{ "k1", "v1" },
{ "k2", 42.0 },
{ "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
});
设计
主要由以下几个类构成
- class Json
- class JsonValue
- class Value
- class JsonInt JsonDouble ...
Json类为对外开放的接口,有多种构造方式。
class Json final {
public
// Types
enum Type {
NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
};
typedef std::vector<Json> array; //array、object直接使用STL容器实现
typedef std::map<std::string, Json> object;
Json() noexcept; // NUL
Json(std::nullptr_t) noexcept; // NUL
Json(double value); // NUMBER
Json(int value); // NUMBER
Json(bool value); // BOOL
Json(const std::string &value); // STRING
Json(std::string &&value); // STRING
Json(const char * value); // STRING
Json(const array &values); // ARRAY
Json(array &&values); // ARRAY
Json(const object &values); // OBJECT
Json(object &&values); // OBJECT
template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}
template <class M, typename std::enable_if<
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
int>::type = 0>
Json(const M & m) : Json(object(m.begin(), m.end())) {}
template <class V, typename std::enable_if<
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
int>::type = 0>
Json(const V & v) : Json(array(v.begin(), v.end())) {}
Json(void *) = delete;
...
private:
std::shared_ptr<JsonValue> m_ptr;
其中有几个构造函数比较复杂,详见:
这些数据的实体被存放在m_ptr所指向的对象之中。
class JsonValue {
protected:
friend class Json;
friend class JsonInt;
friend class JsonDouble;
virtual Json::Type type() const = 0;
virtual bool equals(const JsonValue * other) const = 0;
virtual bool less(const JsonValue * other) const = 0;
virtual void dump(std::string &out) const = 0;
virtual double number_value() const;
virtual int int_value() const;
virtual bool bool_value() const;
virtual const std::string &string_value() const;
virtual const Json::array &array_items() const;
virtual const Json &operator[](size_t i) const;
virtual const Json::object &object_items() const;
virtual const Json &operator[](const std::string &key) const;
virtual ~JsonValue() {}
};
JsonValue是一个抽象基类,定义了一些api,用来操作访问json对象。这些api并不向用户开放,用于内部使用。用户借由Json类中提供的函数来操作和访问。
接下来是其派生类Value:
template <Json::Type tag, typename T>
class Value : public JsonValue {
protected:
// Constructors
explicit Value(const T &value) : m_value(value) {}
explicit Value(T &&value) : m_value(move(value)) {}
// Get type tag
Json::Type type() const override {
return tag;
}
// Comparisons
bool equals(const JsonValue * other) const override {
return m_value == static_cast<const Value<tag, T> *>(other)->m_value;
}
bool less(const JsonValue * other) const override {
return m_value < static_cast<const Value<tag, T> *>(other)->m_value;
}
const T m_value;
void dump(string &out) const override { json11::dump(m_value, out); }
};
Value作为一个类模板,实例化出不同的类保存着json对象的数据实体。
而JsonInt,JsonDouble等等类可以直接通过继承对应的实例化类来保存数据。
以JsonInt为例:
class JsonInt final : public Value<Json::NUMBER, int> {
double number_value() const override { return m_value; }
int int_value() const override { return m_value; }
bool equals(const JsonValue * other) const override { return m_value == other->number_value(); }
bool less(const JsonValue * other) const override { return m_value < other->number_value(); }
public:
explicit JsonInt(int value) : Value(value) {}
};
继承的Value为int版本,因此可以直接通过父类构造函数来保存value。同时实现了专属于该类的一些操作,例如int_value()
用来获取value的值。
json11阅读的更多相关文章
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】AFNetworking源码阅读(三)
[原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- 【原】AFNetworking源码阅读(一)
[原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...
随机推荐
- 如何在Python中使用ZeroMQ和Docker构建微服务架构
@Container容器技术大会将于6月4日在上海光大会展中心国际大酒店举办,来自携程.PPTV.蚂蚁金服.京东.浙江移动.海尔电器.唯品会.eBay.道富银行.麻袋理财等公司的技术负责人将带来实践经 ...
- easyui-datebox 点击事件
<div class="form-group col-xs-5 col-md-5 col-lg-6" style = "margin-left: 0px;" ...
- System.Object
Object():System.Object类型的构造函数,自动调用. ~Object()/Finalize():System.Object类型的祈构函数,自动调用且不能够手动. Equals(obj ...
- SVN 撤回已提交的代码
1. TortoiseSVN -----> Show log 2.右键点击你想撤回的提交 -> Revert changes from this revision ----->Rev ...
- centos7 设置时区和时间
1.设置时区(同步时间前先设置) timedatectl set-timezone Asia/Shanghai 2.安装组件 yum -y install ntp systemctl enable n ...
- mySQL 判断表是否存
select `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` where `TABLE_SCHEMA`='数据库名' and `TABLE_NAME`= ...
- echars柱状图修改每条柱的颜色
在实际开发中,可能会需要到柱状图内某个柱需要特殊颜色表示,我这里的应用是排名,突出显示出当前的数据. 在Color参数中添加一个方法可以任意返回需要的颜色值 function (params) { i ...
- 前端-JavaScript1-3——JavaScript之字面量
字面量?????? 字面量:英语叫做literals,有些书上叫做直接量.看见什么,它就是什么. 我们先来学习数字的字面量,和字符串的字面量.剩余的字面量类型,我们日后遇见再介绍. 3.1 数字的字面 ...
- tomcat窗口一闪而过
当点击bin/startup.bat,出现黑窗口一闪而过时,肯定是因为tomcat启动报错了. 错误排查方法 首先检查java环境变量是否设置正确. 其次调试tomcat,需要修改startup.ba ...
- mysql-查询存在主表但是不存在副标的数据
A.B两表,找出ID字段中,存在A表,但是不存在B表的数据.A表总共13w数据,去重后大约3W条数据,B表有2W条数据,且B表的ID字段有索引. 方法一 使用 not in ,容易理解,效率低 ~执 ...