acl  3.5.3.0
json.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include <list>
4 #include <vector>
5 #include "dbuf_pool.hpp"
6 #include "pipe_stream.hpp"
7 
8 struct ACL_JSON_NODE;
9 struct ACL_JSON;
10 struct ACL_ITER;
11 
12 /**
13  * 对 ACL 库中 json 解析库的封装,方便 C++ 用户使用,如果不太注重性能因素,
14  * 可以直接使用该类,如果在服务端执行且非常注重性能,建议直接使用 ACL 库的
15  * json 解析器,因为该类也是调用了 ACL 库中的 json 解析过程,并且有二次拷贝
16  * 过程,可能会稍微影响一些性能,但对于一般的应用这点影响是微不足道的
17  */
18 
19 namespace acl {
20 
21 class string;
22 class json;
23 
24 /**
25  * json 节点,该类对象必须以 json.create_node() 方式创建
26  */
28 {
29 public:
30  /**
31  * 取得本 json 节点的标签名
32  * @return {const char*} 返回 json 节点标签名,如果返回空,则说明
33  * 调用者需要判断返回值
34  */
35  const char* tag_name(void) const;
36 
37  /**
38  * 返回该 json 节点的文本标签值,当该值为布尔型或数值型时调用者可
39  * 自行进行转换
40  * @return {const char*} 返回空说明没有文本标签值
41  */
42  const char* get_text(void) const;
43 
44  /**
45  * 当该 json 节点存在子节点时,返回本 json 节点标签对应的 json 子节点
46  * @return {const json_node*} 返回 NULL 说明不存在子节点
47  * 注:get_text 与 get_obj 不会同时返回非 NULL
48  */
49  json_node* get_obj(void) const;
50 
51  /**
52  * 当 json 节点为字符串类型时,该函数返回字符串内容
53  * @return {const char*} 返回 NULL 表示该节点非字符串类型
54  */
55  const char* get_string(void) const;
56 
57  /**
58  * 当 json 节点为长整型类型时,该函数返回长整型值的指针地址
59  * @return {const long long int*} 当返回 NULL 时表示该对象非长整型类型
60  */
61 #if defined(_WIN32) || defined(_WIN64)
62  const __int64* get_int64(void) const;
63 #else
64  const long long int* get_int64(void) const;
65 #endif
66 
67  /**
68  * 当 json 节点为浮点类型时,该函数返回长整型值的指针地址
69  * @return {const double*} 当返回 NULL 时表示该对象非浮点类型
70  */
71  const double *get_double(void) const;
72 
73  /**
74  * 当 json 节点为布尔类型时,该函数返回布尔值的指针地址
75  * @return {bool*} 当返回 NULL 时表示该对象非布尔类型
76  */
77  const bool* get_bool(void) const;
78 
79  /**
80  * 判断本节点数据是否为字符串类型
81  * @return {bool}
82  */
83  bool is_string(void) const;
84 
85  /**
86  * 判断本节点数据是否为数字类型
87  * @return {bool}
88  */
89  bool is_number(void) const;
90 
91  /**
92  * 判断本节点数据是否为浮点类型
93  * @return {bool}
94  */
95  bool is_double(void) const;
96 
97  /**
98  * 判断本节点数据是否为布尔类型
99  * @return {bool}
100  */
101  bool is_bool(void) const;
102 
103  /**
104  * 判断本节点数据是否为 null 类型
105  * @return {bool}
106  */
107  bool is_null(void) const;
108 
109  /**
110  * 判断本节点是否为对象类型
111  * @return {bool}
112  */
113  bool is_object(void) const;
114 
115  /**
116  * 判断本节点是否为数组类型
117  * @return {bool}
118  */
119  bool is_array(void) const;
120 
121  /**
122  * 获得该节点类型的描述
123  * @return {const char*}
124  */
125  const char* get_type(void) const;
126 
127  /**
128  * 当该 json 节点有标签时,本函数用来新的标签值覆盖旧的标签名
129  * @param name {const char*} 新的标签值,为非空字符串
130  * @return {bool} 返回 false 表示该节点没有标签或输入空串,没有进行替换
131  */
132  bool set_tag(const char* name);
133 
134  /**
135  * 当该 json 节点为叶节点时,本函数用来替换节点的文本值
136  * @param text {const char*} 新的叶节点文本值,为非空字符串
137  * @return {bool} 返回 false 表示该节点非叶节点或输入非法
138  */
139  bool set_text(const char* text);
140 
141  /**
142  * 将当前 json 节点转换成 json 字符串(包含本 json 节点及其子节点)
143  * @param out {string*} 非空时,则使用此缓冲区,否则使用内部缓冲区
144  * @return {const char*}
145  */
146  const string& to_string(string* out = NULL) const;
147 
148  /////////////////////////////////////////////////////////////////////
149 
150  /**
151  * 给本 json 节点添加 json_node 子节点对象
152  * @param child {json_node*} 子节点对象
153  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
154  * @return {json_node&} return_child 为 true 时返回子节点的引用,
155  * 否则返回本 json 节点对象的引用
156  */
157  json_node& add_child(json_node* child, bool return_child = false);
158 
159  /**
160  * 给本 json 节点添加 json_node 子节点对象
161  * @param child {json_node&} 子节点对象
162  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
163  * @return {json_node&} return_child 为 true 时返回子节点的引用,
164  * 否则返回本 json 节点对象的引用
165  */
166  json_node& add_child(json_node& child, bool return_child = false);
167 
168  /**
169  * 创建一个 json 节点对象,并将之添加为本 json 节点的子节点
170  * @param as_array {bool} 是否数组对象
171  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
172  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
173  * 否则返回本 json 节点对象的引用
174  */
175  json_node& add_child(bool as_array = false, bool return_child = false);
176  json_node& add_array(bool return_child = false);
177 
178  /**
179  * 创建一个 json 节点对象,并将之添加为本 json 节点的子节点
180  * @param tag {const char*} 标签名
181  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
182  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
183  * 否则返回本 json 节点对象的引用
184  */
185  json_node& add_child(const char* tag, bool return_child = false);
186 
187  /**
188  * 创建一个 json 节点对象,并将之添加为本 json 节点的子节点
189  * @param tag {const char*} 标签名
190  * @param node {json_node*} 标签值指针
191  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
192  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
193  * 否则返回本 json 节点对象的引用
194  */
195  json_node& add_child(const char* tag, json_node* node,
196  bool return_child = false);
197 
198  /**
199  * 创建一个 json 节点对象,并将之添加为本 json 节点的子节点
200  * @param tag {const char*} 标签名
201  * @param node {json_node&} 标签值引用
202  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
203  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
204  * 否则返回本 json 节点对象的引用
205  */
206  json_node& add_child(const char* tag, json_node& node,
207  bool return_child = false);
208 
209  /**
210  * 创建一个字符串类型的 json 节点对象,并将之添加为本 json 节点的子节点
211  * @param tag {const char*} 标签名
212  * @param value {const char*} 标签值
213  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
214  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
215  * 否则返回本 json 节点对象的引用
216  * 注:此处的 add_text 和 add_child 是同样的功能
217  */
218  json_node& add_text(const char* tag, const char* value,
219  bool return_child = false);
220 
221  /**
222  * 创建一个int64 类型的 json 节点对象,并将之添加为本 json 节点的子节点
223  * @param tag {const char*} 标签名
224  * @param value {int64} 标签值
225  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
226  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
227  * 否则返回本 json 节点对象的引用
228  */
229 #if defined(_WIN32) || defined(_WIN64)
230  json_node& add_number(const char* tag, __int64 value,
231  bool return_child = false);
232 #else
233  json_node& add_number(const char* tag, long long int value,
234  bool return_child = false);
235 #endif
236 
237  /**
238  * 创建一个 double 类型的 json 节点对象,并将之添加为本 json 节点的子节点
239  * @param tag {const char*} 标签名
240  * @param value {double} 标签值
241  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
242  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
243  * 否则返回本 json 节点对象的引用
244  */
245  json_node& add_double(const char* tag, double value,
246  bool return_child = false);
247 
248  /**
249  * 创建一个布尔类型的 json 节点对象,并将之添加为本 json 节点的子节点
250  * @param tag {const char*} 标签名
251  * @param value {bool} 标签值
252  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
253  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
254  * 否则返回本 json 节点对象的引用
255  */
256  json_node& add_bool(const char* tag, bool value,
257  bool return_child = false);
258 
259  /**
260  * 创建一个 null 类型的 json 节点对象,并将之添加为本 json 节点的子节点
261  * @param tag {const char*} 标签名
262  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
263  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
264  * 否则返回本 json 节点对象的引用
265  */
266  json_node& add_null(const char* tag, bool return_child = false);
267 
268  /**
269  * 创建一个 json 字符串对象,并将之添加为本 json 节点的子节点
270  * @param text {const char*} 文本字符串
271  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
272  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
273  * 否则返回本 json 节点对象的引用
274  */
275  json_node& add_array_text(const char* text,
276  bool return_child = false);
277 
278  /**
279  * 创建一个 json 数字对象,并将之添加为本 json 节点的子节点
280  * @param value {acl_int64} 数字值
281  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
282  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
283  * 否则返回本 json 节点对象的引用
284  */
285 #if defined(_WIN32) || defined(_WIN64)
286  json_node& add_array_number(__int64 value,
287  bool return_child = false);
288 #else
289  json_node& add_array_number(long long int value,
290  bool return_child = false);
291 #endif
292 
293  /**
294  * 创建一个 json double 对象,并将之添加为本 json 节点的子节点
295  * @param value {double} 值
296  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
297  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
298  * 否则返回本 json 节点对象的引用
299  */
300  json_node& add_array_double(double value, bool return_child = false);
301 
302  /**
303  * 创建一个 json 布尔对象,并将之添加为本 json 节点的子节点
304  * @param value {bool} 布尔值
305  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
306  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
307  * 否则返回本 json 节点对象的引用
308  */
309  json_node& add_array_bool(bool value, bool return_child = false);
310 
311  /**
312  * 创建一个 json null 对象,并将之添加为本 json 节点的子节点
313  * @param return_child {bool} 是否需要本函数返回新创建的子节点的引用
314  * @return {json_node&} return_child 为 true 时创建的新节点的引用,
315  * 否则返回本 json 节点对象的引用
316  */
317  json_node& add_array_null(bool return_child = false);
318 
319  /**
320  * @return {json_node&} 返回本节点的父节点引用,在采用级联方式创建 json
321  * 对象时,本函数常被用于返回父节点
322  */
323  json_node& get_parent(void) const;
324 
325  /////////////////////////////////////////////////////////////////////
326 
327  /**
328  * 获得本节点的第一个子节点,需要遍历子节点时必须首先调用此函数
329  * @return {json_node*} 返回空表示没有子节点,返回的非空对象不能
330  * 在外部 delete,因为内部会自动释放
331  */
332  json_node* first_child(void);
333 
334  /**
335  * 获得本节点的下一个子节点
336  * @return {json_node*} 返回空表示遍历过程结束,返回的非空对象不能
337  * 在外部 delete,因为内部会自动释放
338  */
339  json_node* next_child(void);
340 
341  /**
342  * 从当前 json 节点的子节点中提取对应标签的 json 子节点
343  * @param tag {const char*} json 子节点的标签名
344  * @return {json_node*} 返回 NULL 表示不存在
345  */
346  json_node* operator[] (const char* tag);
347 
348  /**
349  * 返回该 json 节点在整个 json 树中的深度
350  * @return {int}
351  */
352  int depth(void) const;
353 
354  /**
355  * 返回该 json 节点的下一级子节点的个数
356  * @return {int} 永远 >= 0
357  */
358  int children_count(void) const;
359 
360  /**
361  * 将本节点及其子节点从 json 树中删除,其内存将由 json 对象统一释放
362  * @return {int} 被释放的节点数量
363  */
364  int detach(void);
365 
366  /**
367  * 当在遍历该 json 节点时,内部会动态产生一些临时 json_node 对象,调用
368  * 此函数可以清空这些对象,一旦调用此函数进行了清除,则由 first_child,
369  * next_child 返回的 json_node 节点对象将不再可用,否则会产生内存非法
370  * 访问
371  */
372  void clear(void);
373 
374  /**
375  * 获得 json 对象的引用
376  * @return {json&}
377  */
378  json& get_json(void) const;
379 
380  /**
381  * 取出对应于 ACL 库中的 json 节点对象
382  * @return {ACL_JSON_NODE*} 返回节点对象,注:该节点用户不能单独释放
383  */
384  ACL_JSON_NODE* get_json_node(void) const;
385 
386 private:
387  friend class json;
388  friend class dbuf_guard;
389 
390  /**
391  * 构造函数,要求该对象必须只能由 json 对象创建
392  * @param node {ACL_JSON_NODE*} ACL 库中的 ACL_JSON_NODE 结构对象
393  */
394  json_node(ACL_JSON_NODE* node, json* json_ptr);
395 
396  /**
397  * 要求该对象必须是动态创建的
398  */
399  ~json_node(void);
400 
401  /**
402  * 设置 json 节点
403  * @param node {ACL_JSON_NODE*}
404  */
405  void set_json_node(ACL_JSON_NODE* node);
406 
407 private:
408  ACL_JSON_NODE* node_me_;
409  json* json_;
410  dbuf_guard* dbuf_;
411  json_node* parent_;
412  ACL_ITER* iter_;
413  string* buf_;
414  json_node* obj_;
415 
416  union {
417 #if defined(_WIN32) || defined(_WIN64)
418  __int64 n;
419 #else
420  long long int n;
421 #endif
422  bool b;
423  double d;
424  } node_val_;
425 };
426 
427 class ACL_CPP_API json : public pipe_stream, public dbuf_obj
428 {
429 public:
430  /**
431  * 构造函数,可用于解析 json 字符串或生成 json 对象
432  * @param data {const char*} json 格式的字符串,可以是完整的
433  * json 字符串,也可以是部分的 json 字符串,也可以是空指针,
434  * 无论如何,用户依然可以用部分或完整的 json 字符串调用 update
435  * 函数,在调用 update 过程中解析 json;其实,当构造函数的
436  * 的 data 参数非空时,它也会调用 update
437  * @param dbuf {dbuf_guard*} 非空时将做为内存池管理对象,否则内部
438  * 会自动创建一个内存池管理对象
439  */
440  json(const char* data = NULL, dbuf_guard* dbuf = NULL);
441 
442  /**
443  * 根据一个 json 对象中的一个 json 节点构造一个新的 json 对象
444  * @param node {const json_node&} 源 json 对象中的一个 json 节点
445  * @param dbuf {dbuf_guard*} 非空时将做为内存池管理对象,否则内部
446  * 会自动创建一个内存池管理对象
447  */
448  json(const json_node& node, dbuf_guard* dbuf = NULL);
449 
450  ~json(void);
451 
452  /**
453  * 设置是否在解析时自动处理半个汉字的情形
454  * @param on {bool}
455  * @return {json&}
456  */
457  json& part_word(bool on);
458 
459  /**
460  * 以流式方式循环调用本函数添加 json 数据,也可以一次性添加
461  * 完整的 json 数据,如果是重复使用该 json 解析器解析多个 json
462  * 对象,则应该在解析下一个 json 对象前调用 reset() 方法来清
463  * 除上一次的解析结果
464  * @param data {const char*} json 数据
465  @return {const char*} 当解析结束后,该返回值表示剩余数据的指针地址
466  */
467  const char* update(const char* data);
468 
469  /**
470  * 判断是否解析完毕
471  * @return {bool}
472  */
473  bool finish(void);
474 
475  /**
476  * 重置 json 解析器状态,该 json 对象可以用来对多个 json 数据
477  * 进行解析,在反复使用本 json 解析器前,需要调用本函数重置
478  * 内部 json 解析器状态,清除上一次的解析结果
479  */
480  void reset(void);
481 
482  /**
483  * 从 json 对象中取得某个标签名的第一个节点
484  * @param tag {const char*} 标签名(不区分大小写)
485  * @return {json_node*} 返回 json 节点对象,不存在则返回 NULL
486  * 注:返回的 json_node 节点可以修改,但不能删除节点,内部有自动删除机制,
487  * 当调用方法 clear/getElementsByTagName/getElementsByTags 后,节点
488  * 不能再被引用,因为节点的内存被自动释放
489  */
490  json_node* getFirstElementByTagName(const char* tag) const;
491 
492  /**
493  * 重载运算符,直接获得对应标签名的第一个节点
494  * @param tag {const char*} 标签名(不区分大小写)
495  * @return {json_node*} 返回 json 节点对象,不存在则返回 NULL
496  * 注:返回的 json_node 节点可以修改,但不能删除节点,内部有自动删除机制,
497  * 当调用方法 clear/getElementsByTagName/getElementsByTags 后,节点
498  * 不能再被引用,因为节点的内存被自动释放
499  */
500  json_node* operator[](const char* tag) const;
501 
502  /**
503  * 从 json 对象中取得某个标签名的所有节点集合
504  * @param tag {const char*} 标签名(不区分大小写)
505  * @return {const std::vector<json_node*>&} 返回结果集的对象引用,
506  * 如果查询结果为空,则该集合为空,即:empty() == true
507  * 注:返回的 json_node 节点可以修改,但不能删除节点,内部有自动删除机制,
508  * 当调用方法 clear/getElementsByTagName/getElementsByTags 后,节点
509  * 不能再被引用,因为节点的内存被自动释放
510  */
511  const std::vector<json_node*>&
512  getElementsByTagName(const char* tag) const;
513 
514  /**
515  * 从 json 对象中获得所有的与给定多级标签名相同的 json 节点的集合
516  * @param tags {const char*} 多级标签名,由 '/' 分隔各级标签名,
517  * 如针对 json 数据:
518  * { 'root': [
519  * 'first': { 'second': { 'third': 'test1' } },
520  * 'first': { 'second': { 'third': 'test2' } },
521  * 'first': { 'second': { 'third': 'test3' } }
522  * ]
523  * }
524  * 可以通过多级标签名:root/first/second/third 一次性查出所有符合
525  * 条件的节点
526  * @return {const std::vector<json_node*>&} 符合条件的 json 节点集合,
527  * 如果查询结果为空,则该集合为空,即:empty() == true
528  * 注:返回的 json_node 节点可以修改,但不能删除节点,内部有自动删除机制,
529  * 当调用方法 clear/getElementsByTagName/getElementsByTags 后,节点
530  * 不能再被引用,因为节点的内存被自动释放
531  */
532  const std::vector<json_node*>&
533  getElementsByTags(const char* tags) const;
534 
535  /**
536  * 从 json 对象中获得所有的与给定多级标签名相同的 json 节点的集合
537  * @param tags {const char*} 多级标签名,由 '/' 分隔各级标签名,
538  * 如针对 json 数据:
539  * { 'root': [
540  * 'first': { 'second': { 'third': 'test1' } },
541  * 'first': { 'second': { 'third': 'test2' } },
542  * 'first': { 'second': { 'third': 'test3' } }
543  * ]
544  * }
545  * 可以通过多级标签名:root/first/second/third 一次性查出所有符合
546  * 条件的节点
547  * @return {json_node*} 返回 NULL 表示不存在
548  */
549  json_node* getFirstElementByTags(const char* tags) const;
550 
551  /**
552  * 取得 acl 库中的 ACL_JSON 对象
553  * @return {ACL_JSON*} 该值不可能为空,注意用户可以修改该对象的值,
554  * 但不可以释放该对象
555  */
556  ACL_JSON* get_json(void) const;
557 
558  /////////////////////////////////////////////////////////////////////
559 
560  /**
561  * 创建一个 json_node 叶节点对象,该节点对象的格式为:
562  * "tag_name": "tag_value"
563  * @param tag {const char*} 标签名
564  * @param value {const char*} 标签值
565  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
566  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
567  * 不用时调用 reset 来释放这些 json_node 节点对象
568  */
569  json_node& create_node(const char* tag, const char* value);
570 
571  /**
572  * 创建一个 json_node 叶节点对象,该节点对象的格式为:
573  * "tag_name": tag_value
574  * @param tag {const char*} 标签名
575  * @param value {int64} 标签值
576  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
577  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
578  * 不用时调用 reset 来释放这些 json_node 节点对象
579  */
580 #if defined(_WIN32) || defined(_WIN64)
581  json_node& create_node(const char* tag, __int64 value);
582 #else
583  json_node& create_node(const char* tag, long long int value);
584 #endif
585 
586  /**
587  * 创建一个 json_node 叶节点对象,该节点对象的格式为:
588  * "tag_name": tag_value
589  * @param tag {const char*} 标签名
590  * @param value {double} 标签值
591  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
592  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
593  * 不用时调用 reset 来释放这些 json_node 节点对象
594  */
595  json_node& create_double(const char* tag, double value);
596 
597  /**
598  * 创建一个 json_node 叶节点对象,该节点对象的格式为:
599  * "tag_name": true|false
600  * @param tag {const char*} 标签名
601  * @param value {bool} 标签值
602  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
603  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
604  * 不用时调用 reset 来释放这些 json_node 节点对象
605  */
606  json_node& create_node(const char* tag, bool value);
607 
608  /**
609  * 创建一个 json_node null 叶节点对象,该节点对象的格式为:
610  * "tag_name": null
611  * @param tag {const char*} 标签名
612  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
613  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
614  * 不用时调用 reset 来释放这些 json_node 节点对象
615  */
616  json_node& create_null(const char* tag);
617 
618  /**
619  * 创建一个 json_node 叶节点字符串对象,该节点对象的格式为:"string"
620  * 按 json 规范,该节点只能加入至数组对象中
621  * @param text {const char*} 文本字符串
622  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
623  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
624  * 不用时调用 reset 来释放这些 json_node 节点对象
625  */
626  json_node& create_array_text(const char* text);
627 
628  /**
629  * 创建一个 json_node 叶节点数值对象
630  * 按 json 规范,该节点只能加入至数组对象中
631  * @param value {acl_int64} 数值
632  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
633  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
634  * 不用时调用 reset 来释放这些 json_node 节点对象
635  */
636 #if defined(_WIN32) || defined(_WIN64)
637  json_node& create_array_number(__int64 value);
638 #else
639  json_node& create_array_number(long long int value);
640 #endif
641 
642  /**
643  * 创建一个 json_node 叶节点数值对象
644  * 按 json 规范,该节点只能加入至数组对象中
645  * @param value {double} 值
646  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
647  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
648  * 不用时调用 reset 来释放这些 json_node 节点对象
649  */
650  json_node& create_array_double(double value);
651 
652  /**
653  * 创建一个 json_node 叶节点布尔对象
654  * 按 json 规范,该节点只能加入至数组对象中
655  * @param value {bool} 布尔值
656  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
657  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
658  * 不用时调用 reset 来释放这些 json_node 节点对象
659  */
660  json_node& create_array_bool(bool value);
661 
662  /**
663  * 创建一个 json_node 叶节点 null 对象
664  * 按 json 规范,该节点只能加入至数组对象中
665  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
666  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
667  * 不用时调用 reset 来释放这些 json_node 节点对象
668  */
669  json_node& create_array_null(void);
670 
671  /**
672  * 创建一个 json_node 节点容器对象,该对象没有标签,
673  * 该节点对象的格式为:"{}" 或数组对象 "[]"
674  * @param as_array {bool} 是否数组对象
675  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
676  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
677  * 不用时调用 reset 来释放这些 json_node 节点对象
678  */
679  json_node& create_node(bool as_array = false);
680  json_node& create_array(void);
681 
682  /**
683  * 创建一个 json_node 节点对象,该节点对象的格式为:tag_name: {}
684  * 或 tag_name: []
685  * @param tag {const char*} 标签名
686  * @param node {json_node*} json 节点对象作为标签值
687  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
688  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
689  * 不用时调用 reset 来释放这些 json_node 节点对象
690  */
691  json_node& create_node(const char* tag, json_node* node);
692 
693  /**
694  * 创建一个 json_node 节点对象,该节点对象的格式为:tag_name: {}
695  * 或 tag_name: []
696  * @param tag {const char*} 标签名
697  * @param node {json_node&} json 节点对象作为标签值
698  * @return {json_node&} 新产生的 json_node 对象不需要用户手工释放,
699  * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在
700  * 不用时调用 reset 来释放这些 json_node 节点对象
701  */
702  json_node& create_node(const char* tag, json_node& node);
703 
704  /////////////////////////////////////////////////////////////////////
705 
706  /**
707  * 将一个 json 对象中的一个 json 节点复制至任一 json 对象中的一个
708  * 新 json 节点中并返回该新的 json 节点
709  * @param node {json_node*} 源 json 对象的一个 json 节点
710  * @return {json_node&} 当前目标 json 对象中新创建的 json 节点
711  */
712  json_node& duplicate_node(const json_node* node);
713 
714  /**
715  * 将一个 json 对象中的一个 json 节点复制至任一 json 对象中的一个
716  * 新 json 节点中并返回该新的 json 节点
717  * @param node {json_node&} 源 json 对象的一个 json 节点
718  * @return {json_node&} 当前目标 json 对象中新创建的 json 节点
719  */
720  json_node& duplicate_node(const json_node& node);
721 
722  /**
723  * 获得根节点对象
724  * @return {json_node&}
725  */
726  json_node& get_root(void);
727 
728  /**
729  * 开始遍历该 json 对象并获得第一个节点
730  * @return {json_node*} 返回空表示该 json 对象为空节点
731  * 注:返回的节点对象用户不能手工释放,因为该对象被
732  * 内部库自动释放
733  */
734  json_node* first_node(void);
735 
736  /**
737  * 遍历该 json 对象的下一个 json 节点
738  * @return {json_node*} 返回空表示遍历完毕
739  * 注:返回的节点对象用户不能手工释放,因为该对象被
740  * 内部库自动释放
741  */
742  json_node* next_node(void);
743 
744  /**
745  * 将 json 对象树转成字符串
746  * @param out {string&} 存储转换结果的缓冲区
747  * @param add_space {bool} 创建 json 时是否自动在分隔符两边添加空格
748  */
749  void build_json(string& out, bool add_space = false) const;
750 
751  /**
752  * 将 json 对象树转换成 json 字符串
753  * @param out {string*} 非空时,则使用此缓冲区,否则使用内部缓冲区
754  * @param add_space {bool} 创建 json 时是否自动在分隔符两边添加空格
755  * @return {const string&}
756  */
757  const string& to_string(string* out = NULL, bool add_space = false) const;
758 
759  /**
760  * 获得内存池对象指针
761  * @return {dbuf_guard*}
762  */
763  dbuf_guard* get_dbuf(void) const {
764  return dbuf_;
765  }
766 
767  // pipe_stream 虚函数重载
768 
769  virtual int push_pop(const char* in, size_t len,
770  string* out, size_t max = 0);
771  virtual int pop_end(string* out, size_t max = 0);
772  virtual void clear(void);
773 
774 private:
775  // 内存池管理对象,适合管理大量小内存
776  dbuf_guard* dbuf_;
777  dbuf_guard* dbuf_internal_;
778 
779  // 对应于 acl 库中的 ACL_JSON 对象
780  ACL_JSON *json_;
781  // json 对象树中的根节点对象
782  json_node* root_;
783  // 临时的 json 节点查询结果集
784  std::vector<json_node*> nodes_query_;
785  // 缓冲区
786  string* buf_;
787  ACL_ITER* iter_;
788 };
789 
790 } // namespace acl
dbuf_guard * get_dbuf(void) const
Definition: json.hpp:763
HTTP_API void const char * name
Definition: lib_http.h:620
long long int n
Definition: json.hpp:420
#define ACL_CPP_API
double d
Definition: json.hpp:423