| 7747 |
ripley |
1 |
#include "JSONNode.h"
|
|
|
2 |
|
|
|
3 |
#ifdef JSON_ITERATORS
|
|
|
4 |
#ifdef JSON_REF_COUNT
|
|
|
5 |
#define JSON_ASSERT_UNIQUE(x) JSON_ASSERT(internal -> refcount == 1, json_string(JSON_TEXT(x)) + JSON_TEXT(" in non single reference"))
|
|
|
6 |
#else
|
|
|
7 |
#define JSON_ASSERT_UNIQUE(x) (void)0
|
|
|
8 |
#endif
|
|
|
9 |
|
|
|
10 |
#ifdef JSON_MUTEX_CALLBACKS
|
|
|
11 |
#define JSON_MUTEX_COPY2 ,internal -> mylock
|
|
|
12 |
#else
|
|
|
13 |
#define JSON_MUTEX_COPY2
|
|
|
14 |
#endif
|
|
|
15 |
|
|
|
16 |
JSONNode::json_iterator JSONNode::find(const json_string & name_t) json_nothrow {
|
|
|
17 |
JSON_CHECK_INTERNAL();
|
|
|
18 |
JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("find"));
|
|
|
19 |
makeUniqueInternal();
|
|
|
20 |
if (JSONNode ** res = internal -> at(name_t)){
|
|
|
21 |
return ptr_to_json_iterator(res);
|
|
|
22 |
}
|
|
|
23 |
return end();
|
|
|
24 |
}
|
|
|
25 |
|
|
|
26 |
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
|
|
|
27 |
JSONNode::json_iterator JSONNode::find_nocase(const json_string & name_t) json_nothrow {
|
|
|
28 |
JSON_CHECK_INTERNAL();
|
|
|
29 |
JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("find_nocase"));
|
|
|
30 |
makeUniqueInternal();
|
|
|
31 |
if (JSONNode ** res = internal -> at_nocase(name_t)){
|
|
|
32 |
return ptr_to_json_iterator(res);
|
|
|
33 |
}
|
|
|
34 |
return end();
|
|
|
35 |
}
|
|
|
36 |
#endif
|
|
|
37 |
|
|
|
38 |
JSONNode::json_iterator JSONNode::erase(json_iterator pos) json_nothrow {
|
|
|
39 |
JSON_CHECK_INTERNAL();
|
|
|
40 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("erase"));
|
|
|
41 |
JSON_ASSERT_UNIQUE("erase 1");
|
|
|
42 |
JSON_ASSERT_SAFE(pos < end(), JSON_TEXT("erase out of range"), return end(););
|
|
|
43 |
JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("erase out of range"), return begin(););
|
|
|
44 |
deleteJSONNode(*(json_iterator_ptr(pos)));
|
|
|
45 |
internal -> CHILDREN -> erase(json_iterator_ptr(pos));
|
|
|
46 |
return (empty()) ? end() : pos;
|
|
|
47 |
}
|
|
|
48 |
|
|
|
49 |
JSONNode::json_iterator JSONNode::erase(json_iterator _start, const json_iterator & _end) json_nothrow {
|
|
|
50 |
if (_start == _end) return _start;
|
|
|
51 |
JSON_CHECK_INTERNAL();
|
|
|
52 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("erase"));
|
|
|
53 |
JSON_ASSERT_UNIQUE("erase 3");
|
|
|
54 |
JSON_ASSERT_SAFE(_start <= end(), JSON_TEXT("erase out of lo range"), return end(););
|
|
|
55 |
JSON_ASSERT_SAFE(_end <= end(), JSON_TEXT("erase out of hi range"), return end(););
|
|
|
56 |
JSON_ASSERT_SAFE(_start >= begin(), JSON_TEXT("erase out of lo range"), return begin(););
|
|
|
57 |
JSON_ASSERT_SAFE(_end >= begin(), JSON_TEXT("erase out of hi range"), return begin(););
|
|
|
58 |
for (JSONNode ** pos = json_iterator_ptr(_start); pos < json_iterator_ptr(_end); ++pos){
|
|
|
59 |
deleteJSONNode(*pos);
|
|
|
60 |
}
|
|
|
61 |
|
|
|
62 |
internal -> CHILDREN -> erase(json_iterator_ptr(_start), (json_index_t)(json_iterator_ptr(_end) - json_iterator_ptr(_start)));
|
|
|
63 |
return (empty()) ? end() : _start;
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
#ifdef JSON_LIBRARY
|
|
|
67 |
JSONNode::json_iterator JSONNode::insert(json_iterator pos, JSONNode * x) json_nothrow {
|
|
|
68 |
#else
|
|
|
69 |
JSONNode::json_iterator JSONNode::insert(json_iterator pos, const JSONNode & x) json_nothrow {
|
|
|
70 |
#endif
|
|
|
71 |
JSON_CHECK_INTERNAL();
|
|
|
72 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insert"));
|
|
|
73 |
JSON_ASSERT_UNIQUE("insert 1");
|
|
|
74 |
if (json_iterator_ptr(pos) >= internal -> CHILDREN -> end()){
|
|
|
75 |
internal -> push_back(x);
|
|
|
76 |
return end() - 1;
|
|
|
77 |
}
|
|
|
78 |
JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of lo range"), return begin(););
|
|
|
79 |
#ifdef JSON_LIBRARY
|
|
|
80 |
internal -> CHILDREN -> insert(json_iterator_ptr(pos), x);
|
|
|
81 |
#else
|
|
|
82 |
internal -> CHILDREN -> insert(json_iterator_ptr(pos), newJSONNode(x));
|
|
|
83 |
#endif
|
|
|
84 |
return pos;
|
|
|
85 |
}
|
|
|
86 |
|
|
|
87 |
JSONNode::json_iterator JSONNode::insertFFF(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end) json_nothrow {
|
|
|
88 |
JSON_CHECK_INTERNAL();
|
|
|
89 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insertFFF"));
|
|
|
90 |
JSON_ASSERT_UNIQUE("insertFFF");
|
|
|
91 |
JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of high range"), return end(););
|
|
|
92 |
JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of low range"), return begin(););
|
|
|
93 |
const json_index_t num = (json_index_t)(_end - _start);
|
|
|
94 |
json_auto<JSONNode *> mem(num);
|
|
|
95 |
JSONNode ** runner = mem.ptr;
|
|
|
96 |
for (JSONNode ** po = _start; po < _end; ++po){
|
|
|
97 |
*runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2);
|
|
|
98 |
}
|
|
|
99 |
internal -> CHILDREN -> insert(json_iterator_ptr(pos), mem.ptr, num);
|
|
|
100 |
return pos;
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
#ifndef JSON_LIBRARY
|
|
|
104 |
JSONNode::const_iterator JSONNode::find(const json_string & name_t) const json_nothrow {
|
|
|
105 |
JSON_CHECK_INTERNAL();
|
|
|
106 |
JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("find"));
|
|
|
107 |
if (JSONNode ** res = internal -> at(name_t)){
|
|
|
108 |
return JSONNode::const_iterator(res);
|
|
|
109 |
}
|
|
|
110 |
return JSONNode::const_iterator(internal -> end());
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
|
|
|
114 |
JSONNode::const_iterator JSONNode::find_nocase(const json_string & name_t) const json_nothrow {
|
|
|
115 |
JSON_CHECK_INTERNAL();
|
|
|
116 |
JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("find_nocase"));
|
|
|
117 |
if (JSONNode ** res = internal -> at_nocase(name_t)){
|
|
|
118 |
return JSONNode::const_iterator(res);
|
|
|
119 |
}
|
|
|
120 |
return JSONNode::const_iterator(internal -> end());
|
|
|
121 |
}
|
|
|
122 |
#endif
|
|
|
123 |
|
|
|
124 |
JSONNode::reverse_iterator JSONNode::erase(reverse_iterator pos) json_nothrow {
|
|
|
125 |
JSON_CHECK_INTERNAL();
|
|
|
126 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("erase"));
|
|
|
127 |
JSON_ASSERT_UNIQUE("erase 2");
|
|
|
128 |
JSON_ASSERT_SAFE(pos < rend(), JSON_TEXT("erase out of range"), return rend(););
|
|
|
129 |
JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("erase out of range"), return rbegin(););
|
|
|
130 |
deleteJSONNode(*(pos.it));
|
|
|
131 |
internal -> CHILDREN -> erase(pos.it);
|
|
|
132 |
return (empty()) ? rend() : pos + 1;
|
|
|
133 |
}
|
|
|
134 |
|
|
|
135 |
JSONNode::reverse_iterator JSONNode::erase(reverse_iterator _start, const reverse_iterator & _end) json_nothrow {
|
|
|
136 |
if (_start == _end) return _start;
|
|
|
137 |
JSON_CHECK_INTERNAL();
|
|
|
138 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("erase"));
|
|
|
139 |
JSON_ASSERT_UNIQUE("erase 4");
|
|
|
140 |
JSON_ASSERT_SAFE(_start <= rend(), JSON_TEXT("erase out of lo range"), return rend(););
|
|
|
141 |
JSON_ASSERT_SAFE(_end <= rend(), JSON_TEXT("erase out of hi range"), return rend(););
|
|
|
142 |
JSON_ASSERT_SAFE(_start >= rbegin(), JSON_TEXT("erase out of lo range"), return rbegin(););
|
|
|
143 |
JSON_ASSERT_SAFE(_end >= rbegin(), JSON_TEXT("erase out of hi range"), return rbegin(););
|
|
|
144 |
for (JSONNode ** pos = _start.it; pos > _end.it; --pos){
|
|
|
145 |
deleteJSONNode(*pos);
|
|
|
146 |
}
|
|
|
147 |
const json_index_t num = (json_index_t)(_start.it - _end.it);
|
|
|
148 |
internal -> CHILDREN -> erase(_end.it + 1, num, _start.it);
|
|
|
149 |
return (empty()) ? rend() : _start + num;
|
|
|
150 |
}
|
|
|
151 |
|
|
|
152 |
JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const JSONNode & x) json_nothrow {
|
|
|
153 |
JSON_CHECK_INTERNAL();
|
|
|
154 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insert"));
|
|
|
155 |
JSON_ASSERT_UNIQUE("insert 1");
|
|
|
156 |
if (pos.it < internal -> CHILDREN -> begin()){
|
|
|
157 |
internal -> push_front(x);
|
|
|
158 |
return rend() - 1;
|
|
|
159 |
}
|
|
|
160 |
JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
|
|
|
161 |
internal -> CHILDREN -> insert(++pos.it, newJSONNode(x), true);
|
|
|
162 |
return pos;
|
|
|
163 |
}
|
|
|
164 |
|
|
|
165 |
JSONNode::reverse_iterator JSONNode::insertRFF(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end) json_nothrow {
|
|
|
166 |
JSON_CHECK_INTERNAL();
|
|
|
167 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insertRFF"));
|
|
|
168 |
JSON_ASSERT_UNIQUE("insert RFF");
|
|
|
169 |
JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
|
|
|
170 |
JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
|
|
|
171 |
const json_index_t num = (json_index_t)(_end - _start);
|
|
|
172 |
json_auto<JSONNode *> mem(num);
|
|
|
173 |
JSONNode ** runner = mem.ptr + num;
|
|
|
174 |
for (JSONNode ** po = _start; po < _end; ++po){ //fill it backwards
|
|
|
175 |
*(--runner) = newJSONNode(*(*po) JSON_MUTEX_COPY2);
|
|
|
176 |
}
|
|
|
177 |
internal -> CHILDREN -> insert(++pos.it, mem.ptr, num);
|
|
|
178 |
return pos - num + 1;
|
|
|
179 |
}
|
|
|
180 |
|
|
|
181 |
JSONNode::iterator JSONNode::insertFRR(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end) json_nothrow {
|
|
|
182 |
JSON_CHECK_INTERNAL();
|
|
|
183 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insertFRR"));
|
|
|
184 |
JSON_ASSERT_UNIQUE("insert FRR");
|
|
|
185 |
JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of range"), return end(););
|
|
|
186 |
JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of range"), return begin(););
|
|
|
187 |
const json_index_t num = (json_index_t)(_start - _end);
|
|
|
188 |
json_auto<JSONNode *> mem(num);
|
|
|
189 |
JSONNode ** runner = mem.ptr;
|
|
|
190 |
for (JSONNode ** po = _start; po > _end; --po){
|
|
|
191 |
*runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2);
|
|
|
192 |
}
|
|
|
193 |
internal -> CHILDREN -> insert(pos.it, mem.ptr, num);
|
|
|
194 |
return pos;
|
|
|
195 |
}
|
|
|
196 |
|
|
|
197 |
JSONNode::reverse_iterator JSONNode::insertRRR(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end) json_nothrow {
|
|
|
198 |
JSON_CHECK_INTERNAL();
|
|
|
199 |
JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("insertRRR"));
|
|
|
200 |
JSON_ASSERT_UNIQUE("insert RRR");
|
|
|
201 |
JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
|
|
|
202 |
JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
|
|
|
203 |
const json_index_t num = (json_index_t)(_start - _end);
|
|
|
204 |
json_auto<JSONNode *> mem(num);
|
|
|
205 |
JSONNode ** runner = mem.ptr;
|
|
|
206 |
for (JSONNode ** po = _start; po > _end; --po){
|
|
|
207 |
*runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2);
|
|
|
208 |
}
|
|
|
209 |
internal -> CHILDREN -> insert(++pos.it, mem.ptr, num);
|
|
|
210 |
return pos - num + 1;
|
|
|
211 |
}
|
|
|
212 |
#endif
|
|
|
213 |
|
|
|
214 |
#endif
|