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