1 #include "JSONNode.h"
2
3 #define IMPLEMENT_CTOR(type)\
4 JSONNode::JSONNode(const json_string & name_t, type value_t) json_nothrow : internal(internalJSONNode::newInternal()){\
5 internal -> Set(value_t);\
6 internal -> setname(name_t);\
7 LIBJSON_CTOR;\
8 }
IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)9 IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)
10
11 #ifndef JSON_LIBRARY
12 JSONNode::JSONNode(const json_string & name_t, const json_char * value_t) json_nothrow : internal(internalJSONNode::newInternal()){
13 internal -> Set(json_string(value_t));
14 internal -> setname(name_t);
15 LIBJSON_CTOR;
16 }
17 #endif
18
19 #if (defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY))
20 #include "JSONWorker.h"
stringType(const json_string & str)21 JSONNode JSONNode::stringType(const json_string & str){
22 JSONNode res;
23 res.set_name(json_global(EMPTY_JSON_STRING));
24 #ifdef JSON_LESS_MEMORY
25 res = JSONWorker::FixString(str, res.internal, false);
26 #else
27 res = JSONWorker::FixString(str, res.internal -> _string_encoded);
28 #endif
29 return res;
30 }
31
set_name_(const json_string & newname)32 void JSONNode::set_name_(const json_string & newname) json_nothrow {
33 #ifdef JSON_LESS_MEMORY
34 json_string _newname = JSONWorker::FixString(newname, internal, true);
35 #else
36 json_string _newname = JSONWorker::FixString(newname, internal -> _name_encoded);
37 #endif
38 set_name(_newname);
39 }
40 #endif
41
42 #ifdef JSON_CASTABLE
as_node(void) const43 JSONNode JSONNode::as_node(void) const json_nothrow {
44 JSON_CHECK_INTERNAL();
45 if (type() == JSON_NODE){
46 return *this;
47 } else if (type() == JSON_ARRAY){
48 JSONNode res(duplicate());
49 res.internal -> _type = JSON_NODE;
50 return res;
51 }
52 #ifdef JSON_MUTEX_CALLBACKS
53 if (internal -> mylock != 0){
54 JSONNode res(JSON_NODE);
55 res.set_mutex(internal -> mylock);
56 return res;
57 }
58 #endif
59 return JSONNode(JSON_NODE);
60 }
61
as_array(void) const62 JSONNode JSONNode::as_array(void) const json_nothrow {
63 JSON_CHECK_INTERNAL();
64 if (type() == JSON_ARRAY){
65 return *this;
66 } else if (type() == JSON_NODE){
67 JSONNode res(duplicate());
68 res.internal -> _type = JSON_ARRAY;
69 json_foreach(res.internal -> CHILDREN, runner){
70 (*runner) -> clear_name();
71 }
72 return res;
73 }
74 #ifdef JSON_MUTEX_CALLBACKS
75 if (internal -> mylock != 0){
76 JSONNode res(JSON_ARRAY);
77 res.set_mutex(internal -> mylock);
78 return res;
79 }
80 #endif
81 return JSONNode(JSON_ARRAY);
82 }
83
cast(char newtype)84 void JSONNode::cast(char newtype) json_nothrow {
85 JSON_CHECK_INTERNAL();
86 if (newtype == type()) return;
87
88 switch(newtype){
89 case JSON_NULL:
90 nullify();
91 return;
92 case JSON_STRING:
93 *this = as_string();
94 return;
95 case JSON_NUMBER:
96 *this = as_float();
97 return;
98 case JSON_BOOL:
99 *this = as_bool();
100 return;
101 case JSON_ARRAY:
102 *this = as_array();
103 return;
104 case JSON_NODE:
105 *this = as_node();
106 return;
107 }
108 JSON_FAIL(JSON_TEXT("cast to unknown type"));
109 }
110 #endif
111
112 //different just to supress the warning
113 #ifdef JSON_REF_COUNT
merge(JSONNode & other)114 void JSONNode::merge(JSONNode & other) json_nothrow {
115 #else
116 void JSONNode::merge(JSONNode &) json_nothrow {
117 #endif
118 JSON_CHECK_INTERNAL();
119 #ifdef JSON_REF_COUNT
120 if (internal == other.internal) return;
121 JSON_ASSERT(*this == other, JSON_TEXT("merging two nodes that aren't equal"));
122 if (internal -> refcount < other.internal -> refcount){
123 *this = other;
124 } else {
125 other = *this;
126 }
127 #endif
128 }
129
130 #ifdef JSON_REF_COUNT
131 void JSONNode::merge(JSONNode * other) json_nothrow {
132 JSON_CHECK_INTERNAL();
133 if (internal == other -> internal) return;
134 *other = *this;
135 }
136
137 //different just to supress the warning
138 void JSONNode::merge(unsigned int num, ...) json_nothrow {
139 #else
140 void JSONNode::merge(unsigned int, ...) json_nothrow {
141 #endif
142 JSON_CHECK_INTERNAL();
143 #ifdef JSON_REF_COUNT
144 va_list args;
145 va_start(args, num);
146 for(unsigned int i = 0; i < num; ++i){
147 merge(va_arg(args, JSONNode*));
148 }
149 va_end(args);
150 #endif
151 }
152
153 JSONNode JSONNode::duplicate(void) const json_nothrow {
154 JSON_CHECK_INTERNAL();
155 JSONNode mycopy(*this);
156 #ifdef JSON_REF_COUNT
157 JSON_ASSERT(internal == mycopy.internal, JSON_TEXT("copy ctor failed to ref count correctly"));
158 mycopy.makeUniqueInternal();
159 #endif
160 JSON_ASSERT(internal != mycopy.internal, JSON_TEXT("makeUniqueInternal failed"));
161 return mycopy;
162 }
163
164 JSONNode & JSONNode::at(json_index_t pos) json_throws(std::out_of_range) {
165 JSON_CHECK_INTERNAL();
166 if (json_unlikely(pos >= internal -> size())){
167 JSON_FAIL(JSON_TEXT("at() out of bounds"));
168 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
169 }
170 return (*this)[pos];
171 }
172
173 const JSONNode & JSONNode::at(json_index_t pos) const json_throws(std::out_of_range) {
174 JSON_CHECK_INTERNAL();
175 if (json_unlikely(pos >= internal -> size())){
176 JSON_FAIL(JSON_TEXT("at() const out of bounds"));
177 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
178 }
179 return (*this)[pos];
180 }
181
182 JSONNode & JSONNode::operator[](json_index_t pos) json_nothrow {
183 JSON_CHECK_INTERNAL();
184 JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] out of bounds"));
185 makeUniqueInternal();
186 return *(internal -> at(pos));
187 }
188
189 const JSONNode & JSONNode::operator[](json_index_t pos) const json_nothrow {
190 JSON_CHECK_INTERNAL();
191 JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] const out of bounds"));
192 return *(internal -> at(pos));
193 }
194
195 JSONNode & JSONNode::at(const json_string & name_t) json_throws(std::out_of_range) {
196 JSON_CHECK_INTERNAL();
197 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
198 makeUniqueInternal();
199 if (JSONNode ** res = internal -> at(name_t)){
200 return *(*res);
201 }
202 JSON_FAIL(json_string(JSON_TEXT("at could not find child by name: ")) + name_t);
203 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
204 }
205
206 const JSONNode & JSONNode::at(const json_string & name_t) const json_throws(std::out_of_range) {
207 JSON_CHECK_INTERNAL();
208 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
209 if (JSONNode ** res = internal -> at(name_t)){
210 return *(*res);
211 }
212 JSON_FAIL(json_string(JSON_TEXT("at const could not find child by name: ")) + name_t);
213 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
214 }
215
216 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
217 JSONNode & JSONNode::at_nocase(const json_string & name_t) json_throws(std::out_of_range) {
218 JSON_CHECK_INTERNAL();
219 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
220 makeUniqueInternal();
221 if (JSONNode ** res = internal -> at_nocase(name_t)){
222 return *(*res);
223 }
224 JSON_FAIL(json_string(JSON_TEXT("at_nocase could not find child by name: ")) + name_t);
225 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
226 }
227
228 const JSONNode & JSONNode::at_nocase(const json_string & name_t) const json_throws(std::out_of_range) {
229 JSON_CHECK_INTERNAL();
230 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
231 if (JSONNode ** res = internal -> at_nocase(name_t)){
232 return *(*res);
233 }
234 JSON_FAIL(json_string(JSON_TEXT("at_nocase const could not find child by name: ")) + name_t);
235 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
236 }
237 #endif
238
239 #ifndef JSON_LIBRARY
240 struct auto_delete {
241 public:
242 auto_delete(JSONNode * node) json_nothrow : mynode(node){};
243 ~auto_delete(void) json_nothrow { JSONNode::deleteJSONNode(mynode); };
244 JSONNode * mynode;
245 private:
246 auto_delete(const auto_delete &);
247 auto_delete & operator = (const auto_delete &);
248 };
249 #endif
250
251 JSONNode JSON_PTR_LIB JSONNode::pop_back(json_index_t pos) json_throws(std::out_of_range) {
252 JSON_CHECK_INTERNAL();
253 if (json_unlikely(pos >= internal -> size())){
254 JSON_FAIL(JSON_TEXT("pop_back out of bounds"));
255 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
256 }
257 makeUniqueInternal();
258 #ifdef JSON_LIBRARY
259 return internal -> pop_back(pos);
260 #else
261 auto_delete temp(internal -> pop_back(pos));
262 return *temp.mynode;
263 #endif
264 }
265
266 JSONNode JSON_PTR_LIB JSONNode::pop_back(const json_string & name_t) json_throws(std::out_of_range) {
267 JSON_CHECK_INTERNAL();
268 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back"));
269 #ifdef JSON_LIBRARY
270 return internal -> pop_back(name_t);
271 #else
272 if (JSONNode * res = internal -> pop_back(name_t)){
273 auto_delete temp(res);
274 return *(temp.mynode);
275 }
276 JSON_FAIL(json_string(JSON_TEXT("pop_back const could not find child by name: ")) + name_t);
277 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
278 #endif
279 }
280
281 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
282 JSONNode JSON_PTR_LIB JSONNode::pop_back_nocase(const json_string & name_t) json_throws(std::out_of_range) {
283 JSON_CHECK_INTERNAL();
284 JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back_no_case"));
285 #ifdef JSON_LIBRARY
286 return internal -> pop_back_nocase(name_t);
287 #else
288 if (JSONNode * res = internal -> pop_back_nocase(name_t)){
289 auto_delete temp(res);
290 return *(temp.mynode);
291 }
292 JSON_FAIL(json_string(JSON_TEXT("pop_back_nocase could not find child by name: ")) + name_t);
293 json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
294 #endif
295 }
296 #endif
297
298 #ifdef JSON_MEMORY_POOL
299 #include "JSONMemoryPool.h"
300 memory_pool<NODEPOOL> json_node_mempool;
301 #endif
302
303 void JSONNode::deleteJSONNode(JSONNode * ptr) json_nothrow {
304 #ifdef JSON_MEMORY_POOL
305 ptr -> ~JSONNode();
306 json_node_mempool.deallocate((void*)ptr);
307 #elif defined(JSON_MEMORY_CALLBACKS)
308 ptr -> ~JSONNode();
309 libjson_free<JSONNode>(ptr);
310 #else
311 delete ptr;
312 #endif
313 }
314
315 inline JSONNode * _newJSONNode(const JSONNode & orig) {
316 #ifdef JSON_MEMORY_POOL
317 return new((JSONNode*)json_node_mempool.allocate()) JSONNode(orig);
318 #elif defined(JSON_MEMORY_CALLBACKS)
319 return new(json_malloc<JSONNode>(1)) JSONNode(orig);
320 #else
321 return new JSONNode(orig);
322 #endif
323 }
324
325 JSONNode * JSONNode::newJSONNode(const JSONNode & orig JSON_MUTEX_COPY_DECL) {
326 #ifdef JSON_MUTEX_CALLBACKS
327 if (parentMutex != 0){
328 JSONNode * temp = _newJSONNode(orig);
329 temp -> set_mutex(parentMutex);
330 return temp;
331 }
332 #endif
333 return _newJSONNode(orig);
334 }
335
336 JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t) {
337 #ifdef JSON_MEMORY_POOL
338 return new((JSONNode*)json_node_mempool.allocate()) JSONNode(internal_t);
339 #elif defined(JSON_MEMORY_CALLBACKS)
340 return new(json_malloc<JSONNode>(1)) JSONNode(internal_t);
341 #else
342 return new JSONNode(internal_t);
343 #endif
344 }
345
346 JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig) {
347 #ifdef JSON_MEMORY_POOL
348 return new((JSONNode*)json_node_mempool.allocate()) JSONNode(true, const_cast<JSONNode &>(orig));
349 #elif defined(JSON_MEMORY_CALLBACKS)
350 return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JSONNode &>(orig));
351 #else
352 return new JSONNode(true, const_cast<JSONNode &>(orig));
353 #endif
354 }
355
356
357