Jamoma API  0.6.0.a19
JSONNode.cpp
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  }
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"
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 
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
43  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 
62  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 
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
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