-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjson.C
114 lines (93 loc) · 2.7 KB
/
json.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "json.H"
static mem_buf_t parse_mem;
const pd::pi_t::root_t *pibf_parse(pd::in_segment_t &in_seg)
{
pd::in_t::ptr_t in = in_seg;
try {
return pd::pi_t::parse_text(in, parse_mem);
}
catch (...) {
return nullptr;
}
}
const pd::pi_t &pi_name_buf(const char *name, size_t name_size, char *buf, size_t buf_size)
{
pd::str_t name_str(name, name_size);
pd::pi_t::pro_t name_pro(name_str);
pd::pi_t::root_t *root = pd::pi_t::build(name_pro, parse_mem);
return root->value;
}
pd::pi_t const *pi_object_lookup(pd::pi_t const *obj, char const *find)
{
if (!find || !(*find))
return obj;
if (obj) {
if (obj->type() == pd::pi_t::_array) {
pd::pi_t::array_t const &array = obj->__array();
if (*find == '[') {
char const *close = strchr(find, ']');
errno = 0;
if (close > find) {
char *ptr = nullptr;
long index = strtol(find + 1, &ptr, 10);
if (errno == 0 && ptr == close) {
if (array._count() > index) {
pd::pi_t const *val = &(array[index]);
return pi_object_lookup(val, close + 1);
}
}
}
}
}
else if (obj->type() == pd::pi_t::_map) {
pd::pi_t::map_t const &map = obj->__map();
char const *name = find;
char const *dot = strchr(find, '.');
char const *subs = strchr(find, '[');
char const *part = ((dot && subs > dot) || !subs) ? dot : subs;
size_t name_size = (part >= find) ? (size_t)(part - find) : strlen(find);
if (dot || part != find) {
pd::pi_t const *val = obj;
if (name_size) {
size_t buf_size = pi_get_buf_size(name_size);
char buf[buf_size];
val = map.lookup(pi_name_buf(name, name_size, buf, buf_size));
}
return pi_object_lookup(val, (part ? (part == dot ? (part + 1) : part) : nullptr));
}
}
}
return nullptr;
}
char const *pi_get_string(pd::pi_t const *obj, size_t *len)
{
if (!obj || obj->type() != pd::pi_t::_string) return NULL;
pd::pi_t::string_t const &string = obj->__string();
if (!string._count()) return NULL;
if (len) *len = string.str().size();
return string.str().ptr();
}
static uint64_t pi_check_int(pd::pi_t const *obj, uint64_t defval)
{
if (!obj) return defval;
if (obj->type() == pd::pi_t::_int29)
return obj->__int29();
if (obj->type() == pd::pi_t::_uint64)
return obj->__uint64();
if (obj->type() == pd::pi_t::_string) {
pd::pi_t::string_t const &string = obj->__string();
if (string._count()) {
pd::str_t str = string.str();
char *ptr;
uint64_t val = strtoul(str.ptr(), &ptr, 10);
if (ptr == str.ptr() + str.size())
return val;
}
}
return defval;
}
uint64_t pi_get_int(pd::pi_t const *root, char const *name, uint64_t defval)
{
pd::pi_t const *obj = pi_object_lookup(root, name);
return pi_check_int(obj, defval);
}