Jamoma API  0.6.0.a19
internalJSONNode.cpp
1 #include "internalJSONNode.h"
2 #include "NumberToString.h" //So that I can convert numbers into strings
3 #include "JSONNode.h" //To fill in the foreward declaration
4 #include "JSONWorker.h" //For fetching and parsing and such
5 #include "JSONGlobals.h"
6 
7 internalJSONNode::internalJSONNode(const internalJSONNode & orig) json_nothrow :
8  _type(orig._type), _name(orig._name), _name_encoded(orig._name_encoded),
9  _string(orig._string), _string_encoded(orig._string_encoded), _value(orig._value)
10  initializeMutex(0)
11  initializeRefCount(1)
12  initializeFetch(orig.fetched)
13  initializeComment(orig._comment)
14  initializeChildren(0){
15 
16 
17  LIBJSON_COPY_CTOR;
18  if (isContainer()){
19  CHILDREN = jsonChildren::newChildren();
20  if (json_likely(!orig.CHILDREN -> empty())){
21  CHILDREN -> reserve(orig.CHILDREN -> size());
22  json_foreach(orig.CHILDREN, myrunner){
23  CHILDREN -> push_back(JSONNode::newJSONNode((*myrunner) -> duplicate()));
24  }
25  }
26  }
27  #ifdef JSON_MUTEX_CALLBACKS /*-> JSON_MUTEX_CALLBACKS */
28  _set_mutex(orig.mylock, false);
29  #endif /*<- */
30 }
31 
32 #ifdef JSON_PREPARSE /*-> JSON_PREPARSE */
33  #define SetFetchedFalseOrDo(code) code
34 #else /*<- else */
35  #define SetFetchedFalseOrDo(code) SetFetched(false)
36 #endif /*<- */
37 
38 //this one is specialized because the root can only be array or node
39 #ifdef JSON_READ_PRIORITY /*-> JSON_READ_PRIORITY */
40 internalJSONNode::internalJSONNode(const json_string & unparsed) json_nothrow : _type(), _name(),_name_encoded(false), _string(unparsed), _string_encoded(), _value()
41  initializeMutex(0)
42  initializeRefCount(1)
43  initializeFetch(false)
44  initializeComment(json_global(EMPTY_JSON_STRING))
45  initializeChildren(0){
46 
47  LIBJSON_CTOR;
48  switch (unparsed[0]){
49  case JSON_TEXT('{'): //node
50  _type = JSON_NODE;
51  CHILDREN = jsonChildren::newChildren();
52  #ifdef JSON_PREPARSE
53  FetchNode();
54  #endif
55  break;
56  case JSON_TEXT('['): //array
57  _type = JSON_ARRAY;
58  CHILDREN = jsonChildren::newChildren();
59  #ifdef JSON_PREPARSE
60  FetchArray();
61  #endif
62  break;
63  default:
64  JSON_FAIL_SAFE(JSON_TEXT("root not starting with either { or ["), Nullify(););
65  break;
66  }
67 }
68 
69 #ifndef JSON_STRICT
70  #define LETTERCASE(x, y)\
71  case JSON_TEXT(x):\
72  case JSON_TEXT(y)
73 #else
74  #define LETTERCASE(x, y)\
75  case JSON_TEXT(x)
76 #endif
77 
78 internalJSONNode::internalJSONNode(const json_string & name_t, const json_string & value_t) json_nothrow : _type(), _name_encoded(), _name(JSONWorker::FixString(name_t, NAME_ENCODED)), _string(), _string_encoded(), _value()
79  initializeMutex(0)
80  initializeRefCount(1)
81  initializeFetch(false)
82  initializeComment(json_global(EMPTY_JSON_STRING))
83  initializeChildren(0){
84 
85  LIBJSON_CTOR;
86 
87  #ifdef JSON_STRICT
88  JSON_ASSERT_SAFE(!value_t.empty(), JSON_TEXT("empty node"), Nullify(); return;);
89  #else
90  if (json_unlikely(value_t.empty())){
91  _type = JSON_NULL;
92  SetFetched(true);
93  return;
94  }
95  #endif
96 
97  _string = value_t;
98 
99  const json_char firstchar = value_t[0];
100  #if defined JSON_DEBUG || defined JSON_SAFE
101  const json_char lastchar = value_t[value_t.length() - 1];
102  #endif
103 
104  switch (firstchar){
105  case JSON_TEXT('\"'): //a json_string literal, still escaped and with leading and trailing quotes
106  JSON_ASSERT_SAFE(lastchar == JSON_TEXT('\"'), JSON_TEXT("Unterminated quote"), Nullify(); return;);
107  _type = JSON_STRING;
108  SetFetchedFalseOrDo(FetchString());
109  break;
110  case JSON_TEXT('{'): //a child node, or set of children
111  JSON_ASSERT_SAFE(lastchar == JSON_TEXT('}'), JSON_TEXT("Missing }"), Nullify(); return;);
112  _type = JSON_NODE;
113  CHILDREN = jsonChildren::newChildren();
114  SetFetchedFalseOrDo(FetchNode());
115  break;
116  case JSON_TEXT('['): //an array
117  JSON_ASSERT_SAFE(lastchar == JSON_TEXT(']'), JSON_TEXT("Missing ]"), Nullify(); return;);
118  _type = JSON_ARRAY;
119  CHILDREN = jsonChildren::newChildren();
120  SetFetchedFalseOrDo(FetchArray());
121  break;
122  LETTERCASE('t', 'T'):
123  JSON_ASSERT_SAFE(value_t == json_global(CONST_TRUE), json_string(json_global(ERROR_UNKNOWN_LITERAL) + value_t).c_str(), Nullify(); return;);
124  _value._bool = true;
125  _type = JSON_BOOL;
126  SetFetched(true);
127  break;
128  LETTERCASE('f', 'F'):
129  JSON_ASSERT_SAFE(value_t == json_global(CONST_FALSE), json_string(json_global(ERROR_UNKNOWN_LITERAL) + value_t).c_str(), Nullify(); return;);
130  _value._bool = false;
131  _type = JSON_BOOL;
132  SetFetched(true);
133  break;
134  LETTERCASE('n', 'N'):
135  JSON_ASSERT_SAFE(value_t == json_global(CONST_NULL), json_string(json_global(ERROR_UNKNOWN_LITERAL) + value_t).c_str(), Nullify(); return;);
136  _type = JSON_NULL;
137  SetFetched(true);
138  break;
139  default:
140  JSON_ASSERT_SAFE(NumberToString::isNumeric(value_t), json_string(json_global(ERROR_UNKNOWN_LITERAL) + value_t).c_str(), Nullify(); return;);
141  _type = JSON_NUMBER;
142  SetFetchedFalseOrDo(FetchNumber());
143  break;
144  }
145 }
146 
147 #endif /*<- */
148 
149 
150 internalJSONNode::~internalJSONNode(void) json_nothrow {
151  LIBJSON_DTOR;
152  #ifdef JSON_MUTEX_CALLBACKS
153  _unset_mutex();
154  #endif /*<- */
155  DELETE_CHILDREN();
156 }
157 
158 #ifdef JSON_READ_PRIORITY
159  void internalJSONNode::FetchString(void) const json_nothrow {
160  JSON_ASSERT_SAFE(!_string.empty(), JSON_TEXT("JSON json_string type is empty?"), Nullify(); return;);
161  JSON_ASSERT_SAFE(_string[0] == JSON_TEXT('\"'), JSON_TEXT("JSON json_string type doesn't start with a quotation?"), Nullify(); return;);
162  JSON_ASSERT_SAFE(_string[_string.length() - 1] == JSON_TEXT('\"'), JSON_TEXT("JSON json_string type doesn't end with a quotation?"), Nullify(); return;);
163  _string = JSONWorker::FixString(json_string(_string.begin() + 1, _string.end() - 1), STRING_ENCODED);
164  #ifdef JSON_LESS_MEMORY
165  JSON_ASSERT(_string.capacity() == _string.length(), JSON_TEXT("_string object too large 2"));
166  #endif
167  }
168 
169  void internalJSONNode::FetchNode(void) const json_nothrow {
170  JSON_ASSERT_SAFE(!_string.empty(), JSON_TEXT("JSON node type is empty?"), Nullify(); return;);
171  JSON_ASSERT_SAFE(_string[0] == JSON_TEXT('{'), JSON_TEXT("JSON node type doesn't start with a bracket?"), Nullify(); return;);
172  JSON_ASSERT_SAFE(_string[_string.length() - 1] == JSON_TEXT('}'), JSON_TEXT("JSON node type doesn't end with a bracket?"), Nullify(); return;);
173  JSONWorker::DoNode(this, _string);
174  clearString(_string);
175  }
176 
177  void internalJSONNode::FetchArray(void) const json_nothrow {
178  JSON_ASSERT_SAFE(!_string.empty(), JSON_TEXT("JSON node type is empty?"), Nullify(); return;);
179  JSON_ASSERT_SAFE(_string[0] == JSON_TEXT('['), JSON_TEXT("JSON node type doesn't start with a square bracket?"), Nullify(); return;);
180  JSON_ASSERT_SAFE(_string[_string.length() - 1] == JSON_TEXT(']'), JSON_TEXT("JSON node type doesn't end with a square bracket?"), Nullify(); return;);
181  JSONWorker::DoArray(this, _string);
182  clearString(_string);
183  }
184 
185 #endif
186 
187 //This one is used by as_int and as_float, so even non-readers need it
188 void internalJSONNode::FetchNumber(void) const json_nothrow {
189  #ifdef JSON_STRICT
190  _value._number = NumberToString::_atof(_string.c_str());
191  #else
192  #ifdef JSON_UNICODE
193  const size_t len = _string.length();
194  #if defined(_MSC_VER) && defined(JSON_SAFE)
195  const size_t bytes = (len * (sizeof(json_char) / sizeof(char))) + 1;
196  json_auto<char> temp(bytes);
197  size_t res;
198  errno_t err = wcstombs_s(&res, temp.ptr, bytes, _string.c_str(), len);
199  if (err != 0){
200  _value._number = (json_number)0.0;
201  return;
202  }
203  #elif defined(JSON_SAFE)
204  const size_t bytes = (len * (sizeof(json_char) / sizeof(char))) + 1;
205  json_auto<char> temp(bytes);
206  size_t res = std::wcstombs(temp.ptr, _string.c_str(), len);
207  if (res == (size_t)-1){
208  _value._number = (json_number)0.0;
209  return;
210  }
211  #else
212  json_auto<char> temp(len + 1);
213  size_t res = std::wcstombs(temp.ptr, _string.c_str(), len);
214  #endif
215  temp.ptr[res] = '\0';
216  _value._number = (json_number)std::atof(temp.ptr);
217  #else
218  _value._number = (json_number)std::atof(_string.c_str());
219  #endif
220  #endif
221  #if((!defined(JSON_CASTABLE) && defined(JSON_LESS_MEMORY)) && !defined(JSON_WRITE_PRIORITY))
222  clearString(_string);
223  #endif
224 }
225 
226 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
227  void internalJSONNode::Fetch(void) const json_nothrow {
228  if (fetched) return;
229  switch (type()){
230  case JSON_STRING:
231  FetchString();
232  break;
233  case JSON_NODE:
234  FetchNode();
235  break;
236  case JSON_ARRAY:
237  FetchArray();
238  break;
239  case JSON_NUMBER:
240  FetchNumber();
241  break;
242  #if defined JSON_DEBUG || defined JSON_SAFE
243  default:
244  JSON_FAIL(JSON_TEXT("Fetching an unknown type"));
245  Nullify();
246  #endif
247  }
248  fetched = true;
249  }
250 #endif
251 
252 void internalJSONNode::Set(const json_string & val) json_nothrow {
253  makeNotContainer();
254  _type = JSON_STRING;
255  _string = val;
256  shrinkString(_string);
257  _string_encoded = true;
258  SetFetched(true);
259 }
260 
261 #ifdef JSON_LIBRARY
262  void internalJSONNode::Set(json_int_t val) json_nothrow {
263  makeNotContainer();
264  _type = JSON_NUMBER;
265  _value._number = (json_number)val;
266  #if(defined(JSON_CASTABLE) || !defined(JSON_LESS_MEMORY) || defined(JSON_WRITE_PRIORITY))
267  _string = NumberToString::_itoa<json_int_t>(val);
268  #else
269  clearString(_string);
270  #endif
271  SetFetched(true);
272  }
273 
274  void internalJSONNode::Set(json_number val) json_nothrow {
275  makeNotContainer();
276  _type = JSON_NUMBER;
277  _value._number = val;
278  #if(defined(JSON_CASTABLE) || !defined(JSON_LESS_MEMORY) || defined(JSON_WRITE_PRIORITY))
279  _string = NumberToString::_ftoa(val);
280  #else
281  clearString(_string);
282  #endif
283  SetFetched(true);
284  }
285 #else
286  #if(defined(JSON_CASTABLE) || !defined(JSON_LESS_MEMORY) || defined(JSON_WRITE_PRIORITY))
287  #define SET(converter, type)\
288  void internalJSONNode::Set(type val) json_nothrow {\
289  makeNotContainer();\
290  _type = JSON_NUMBER;\
291  _value._number = (json_number)val;\
292  _string = NumberToString::converter<type>(val);\
293  SetFetched(true);\
294  }
295  #define SET_FLOAT(type) \
296  void internalJSONNode::Set(type val) json_nothrow {\
297  makeNotContainer();\
298  _type = JSON_NUMBER;\
299  _value._number = (json_number)val;\
300  _string = NumberToString::_ftoa(_value._number);\
301  SetFetched(true);\
302  }
303  #else /*<- else */
304  #define SET(converter, type)\
305  void internalJSONNode::Set(type val) json_nothrow {\
306  makeNotContainer();\
307  _type = JSON_NUMBER;\
308  _value._number = (json_number)val;\
309  clearString(_string);\
310  SetFetched(true);\
311  }
312  #define SET_FLOAT(type) \
313  void internalJSONNode::Set(type val) json_nothrow {\
314  makeNotContainer();\
315  _type = JSON_NUMBER;\
316  _value._number = (json_number)val;\
317  clearString(_string);\
318  SetFetched(true);\
319  }
320  #endif
321  #define SET_INTEGER(type) SET(_itoa, type) SET(_uitoa, unsigned type)
322 
323  SET_INTEGER(char)
324  SET_INTEGER(short)
325  SET_INTEGER(int)
326  SET_INTEGER(long)
327  #ifndef JSON_ISO_STRICT
328  SET_INTEGER(long long)
329  SET_FLOAT(long double)
330  #endif
331 
332  SET_FLOAT(float)
333  SET_FLOAT(double)
334 #endif
335 
336 void internalJSONNode::Set(bool val) json_nothrow {
337  makeNotContainer();
338  _type = JSON_BOOL;
339  _value._bool = val;
340  #if(defined(JSON_CASTABLE) || !defined(JSON_LESS_MEMORY) || defined(JSON_WRITE_PRIORITY))
341  _string = val ? json_global(CONST_TRUE) : json_global(CONST_FALSE);
342  #endif
343  SetFetched(true);
344 }
345 
346 bool internalJSONNode::IsEqualTo(const internalJSONNode * val) const json_nothrow {
347  if (this == val) return true; //same internal object, so they must be equal (not only for ref counting)
348  if (type() != val -> type()) return false; //aren't even same type
349  if (_name != val -> _name) return false; //names aren't the same
350  if (type() == JSON_NULL) return true; //both null, can't be different
351  #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
352  Fetch();
353  val -> Fetch();
354  #endif
355  switch (type()){
356  case JSON_STRING:
357  return val -> _string == _string;
358  case JSON_NUMBER:
359  return _floatsAreEqual(val -> _value._number, _value._number);
360  case JSON_BOOL:
361  return val -> _value._bool == _value._bool;
362  };
363 
364  JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("Checking for equality, not sure what type"));
365  if (CHILDREN -> size() != val -> CHILDREN -> size()) return false; //if they arne't he same size then they certainly aren't equal
366 
367  //make sure each children is the same
368  JSONNode ** valrunner = val -> CHILDREN -> begin();
369  json_foreach(CHILDREN, myrunner){
370  JSON_ASSERT(*myrunner != NULL, json_global(ERROR_NULL_IN_CHILDREN));
371  JSON_ASSERT(*valrunner != NULL, json_global(ERROR_NULL_IN_CHILDREN));
372  JSON_ASSERT(valrunner != val -> CHILDREN -> end(), JSON_TEXT("at the end of other one's children, but they're the same size?"));
373  if (**myrunner != **valrunner) return false;
374  ++valrunner;
375  }
376  return true;
377 }
378 
379 void internalJSONNode::Nullify(void) const json_nothrow {
380  _type = JSON_NULL;
381  #if(defined(JSON_CASTABLE) || !defined(JSON_LESS_MEMORY) || defined(JSON_WRITE_PRIORITY)) /*-> JSON_CASTABLE || !JSON_LESS_MEMORY || JSON_WRITE_PRIORITY */
382  _string = json_global(CONST_NULL);
383  #else /*<- else */
384  clearString(_string);
385  #endif /*<- */
386  SetFetched(true);
387 }
388 
389 #ifdef JSON_MUTEX_CALLBACKS /*-> JSON_MUTEX_CALLBACKS */
390  #define JSON_MUTEX_COPY ,mylock
391 #else /*<- else */
392  #define JSON_MUTEX_COPY
393 #endif /*<- */
394 
395 #ifdef JSON_LIBRARY /*-> JSON_LIBRARY */
396 void internalJSONNode::push_back(JSONNode * node) json_nothrow {
397 #else /*<- else */
398 void internalJSONNode::push_back(const JSONNode & node) json_nothrow {
399 #endif /*<- */
400  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("push_back"), return;);
401  #ifdef JSON_LIBRARY /*-> JSON_LIBRARY */
402  #ifdef JSON_MUTEX_CALLBACKS /*-> JSON_MUTEX_CALLBACKS */
403  if (mylock != 0) node -> set_mutex(mylock);
404  #endif /*<- */
405  CHILDREN -> push_back(node);
406  #else /*<- else */
407  CHILDREN -> push_back(JSONNode::newJSONNode(node JSON_MUTEX_COPY));
408  #endif /*<- */
409 }
410 
411 void internalJSONNode::push_front(const JSONNode & node) json_nothrow {
412  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("push_front"), return;);
413  CHILDREN -> push_front(JSONNode::newJSONNode(node JSON_MUTEX_COPY));
414 }
415 
416 JSONNode * internalJSONNode::pop_back(json_index_t pos) json_nothrow {
417  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("pop_back"), return 0;);
418  JSONNode * result = (*CHILDREN)[pos];
419  JSONNode ** temp = CHILDREN -> begin() + pos;
420  CHILDREN -> erase(temp);
421  return result;
422 }
423 
424 JSONNode * internalJSONNode::pop_back(const json_string & name_t) json_nothrow {
425  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("pop_back(str)"), return 0;);
426  if (JSONNode ** res = at(name_t)){
427  JSONNode * result = *res;
428  CHILDREN -> erase(res);
429  return result;
430  }
431  return 0;
432 }
433 
434 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS /*-> JSON_CASE_INSENSITIVE_FUNCTIONS */
435  JSONNode * internalJSONNode::pop_back_nocase(const json_string & name_t) json_nothrow {
436  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("pop_back_nocase"), return 0;);
437  if (JSONNode ** res = at_nocase(name_t)){
438  JSONNode * result = *res;
439  CHILDREN -> erase(res);
440  return result;
441  }
442  return 0;
443  }
444 #endif /*<- */
445 
446 JSONNode ** internalJSONNode::at(const json_string & name_t) json_nothrow {
447  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("at"), return 0;);
448  Fetch();
449  json_foreach(CHILDREN, myrunner){
450  JSON_ASSERT(*myrunner != NULL, json_global(ERROR_NULL_IN_CHILDREN));
451  if (json_unlikely((*myrunner) -> name() == name_t)) return myrunner;
452  }
453  return 0;
454 }
455 
456 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS /*-> JSON_CASE_INSENSITIVE_FUNCTIONS */
457  bool internalJSONNode::AreEqualNoCase(const json_char * ch_one, const json_char * ch_two) json_nothrow {
458  while (*ch_one){ //only need to check one, if the other one terminates early, the check will cause it to fail
459  const json_char c_one = *ch_one;
460  const json_char c_two = *ch_two;
461  if (c_one != c_two){
462  if ((c_two > 64) && (c_two < 91)){ //A - Z
463  if (c_one != (json_char)(c_two + 32)) return false;
464  } else if ((c_two > 96) && (c_two < 123)){ //a - z
465  if (c_one != (json_char)(c_two - 32)) return false;
466  } else { //not a letter, so return false
467  return false;
468  }
469  }
470  ++ch_one;
471  ++ch_two;
472 
473  }
474  return *ch_two == '\0'; //this one has to be null terminated too, or else json_string two is longer, hence, not equal
475  }
476 
477  JSONNode ** internalJSONNode::at_nocase(const json_string & name_t) json_nothrow {
478  JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT("at_nocase"), return 0;);
479  Fetch();
480  json_foreach(CHILDREN, myrunner){
481  JSON_ASSERT(*myrunner, json_global(ERROR_NULL_IN_CHILDREN));
482  if (json_unlikely(AreEqualNoCase((*myrunner) -> name().c_str(), name_t.c_str()))) return myrunner;
483  }
484  return 0;
485  }
486 #endif /*<- */
487 
488 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) /*-> JSON_PREPARSE && JSON_READ_PRIORITY */
489  void internalJSONNode::preparse(void) json_nothrow {
490  Fetch();
491  if (isContainer()){
492  json_foreach(CHILDREN, myrunner){
493  (*myrunner) -> preparse();
494  }
495  }
496  }
497 #endif /*<- */
498 
499 internalJSONNode::operator bool() const json_nothrow {
500  Fetch();
501  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
502  switch(type()){
503  case JSON_NUMBER:
504  return !_floatsAreEqual(_value._number, (json_number)0.0);
505  case JSON_NULL:
506  return false;
507  }
508  #endif /*<- */
509  JSON_ASSERT(type() == JSON_BOOL, json_global(ERROR_UNDEFINED) + JSON_TEXT("(bool)"));
510  return _value._bool;
511 }
512 
513 #ifdef JSON_LIBRARY /*-> JSON_LIBRARY */
514  internalJSONNode::operator json_number() const json_nothrow {
515  Fetch();
516  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
517  switch(type()){
518  case JSON_NULL:
519  return (json_number)0.0;
520  case JSON_BOOL:
521  return (json_number)(_value._bool ? 1.0 : 0.0);
522  case JSON_STRING:
523  FetchNumber();
524  }
525  #endif /*<- */
526  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("as_float"));
527  return (json_number)_value._number;
528  }
529 
530  internalJSONNode::operator json_int_t() const json_nothrow {
531  Fetch();
532  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
533  switch(type()){
534  case JSON_NULL:
535  return 0;
536  case JSON_BOOL:
537  return _value._bool ? 1 : 0;
538  case JSON_STRING:
539  FetchNumber();
540  }
541  #endif /*<- */
542  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("as_int"));
543  JSON_ASSERT(_value._number == (json_number)((json_int_t)_value._number), json_string(JSON_TEXT("as_int will truncate ")) + _string);
544  return (json_int_t)_value._number;
545  }
546 #else /*<- else */
547  #ifndef JSON_ISO_STRICT /*-> !JSON_ISO_STRICT */
548  internalJSONNode::operator long double() const json_nothrow {
549  Fetch();
550  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
551  switch(type()){
552  case JSON_NULL:
553  return (long double)0.0;
554  case JSON_BOOL:
555  return (long double)(_value._bool ? 1.0 : 0.0);
556  case JSON_STRING:
557  FetchNumber();
558  }
559  #endif /*<- */
560  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(long double)"));
561  return (long double)_value._number;
562  }
563  #else /*<- else */
564  internalJSONNode::operator double() const json_nothrow {
565  Fetch();
566  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
567  switch(type()){
568  case JSON_NULL:
569  return (double)0.0;
570  case JSON_BOOL:
571  return (double)(_value._bool ? 1.0 : 0.0);
572  case JSON_STRING:
573  FetchNumber();
574  }
575  #endif /*<- */
576  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(double)"));
577  return (double)_value._number;
578  }
579  #endif /*<- */
580 
581  //do whichever one is longer, because it's easy to cast down
582  #ifdef JSON_ISO_STRICT /*-> JSON_ISO_STRICT */
583  internalJSONNode::operator long() const json_nothrow
584  #else /*<- else */
585  internalJSONNode::operator long long() const json_nothrow
586  #endif /*<- */
587  {
588  Fetch();
589  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
590  switch(type()){
591  case JSON_NULL:
592  return 0;
593  case JSON_BOOL:
594  return _value._bool ? 1 : 0;
595  case JSON_STRING:
596  FetchNumber();
597  }
598  #endif /*<- */
599  #ifdef JSON_ISO_STRICT /*-> JSON_ISO_STRICT */
600  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(long)"));
601  JSON_ASSERT(_value._number > LONG_MIN, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT("long"));
602  JSON_ASSERT(_value._number < LONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("long"));
603  JSON_ASSERT(_value._number == (json_number)((long)_value._number), json_string(JSON_TEXT("(long) will truncate ")) + _string);
604  return (long)_value._number;
605  #else /*<- else */
606  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(long long)"));
607  #ifdef LONG_LONG_MAX
608  JSON_ASSERT(_value._number < LONG_LONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("long long"));
609  #elif defined(LLONG_MAX)
610  JSON_ASSERT(_value._number < LLONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("long long"));
611  #endif
612  #ifdef LONG_LONG_MIN
613  JSON_ASSERT(_value._number > LONG_LONG_MIN, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT("long long"));
614  #elif defined(LLONG_MAX)
615  JSON_ASSERT(_value._number > LLONG_MIN, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT("long long"));
616  #endif
617 
618  JSON_ASSERT(_value._number == (json_number)((long long)_value._number), json_string(JSON_TEXT("(long long) will truncate ")) + _string);
619  return (long long)_value._number;
620  #endif /*<- */
621  }
622 
623  #ifdef JSON_ISO_STRICT /*-> JSON_ISO_STRICT */
624  internalJSONNode::operator unsigned long() const json_nothrow
625  #else /*<- else */
626  internalJSONNode::operator unsigned long long() const json_nothrow
627  #endif /*<- */
628  {
629  Fetch();
630  #ifdef JSON_CASTABLE /*-> JSON_CASTABLE */
631  switch(type()){
632  case JSON_NULL:
633  return 0;
634  case JSON_BOOL:
635  return _value._bool ? 1 : 0;
636  case JSON_STRING:
637  FetchNumber();
638  }
639  #endif /*<- */
640  #ifdef JSON_ISO_STRICT /*-> JSON_ISO_STRICT */
641  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(unsigned long)"));
642  JSON_ASSERT(_value._number > 0, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT("unsigned long"));
643  JSON_ASSERT(_value._number < ULONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("unsigned long"));
644  JSON_ASSERT(_value._number == (json_number)((unsigned long)_value._number), json_string(JSON_TEXT("(unsigend long) will truncate ")) + _string);
645  return (unsigned long)_value._number;
646  #else /*<- else */
647  JSON_ASSERT(type() == JSON_NUMBER, json_global(ERROR_UNDEFINED) + JSON_TEXT("(unsigned long long)"));
648  JSON_ASSERT(_value._number > 0, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT("unsigned long long"));
649  #ifdef ULONG_LONG_MAX
650  JSON_ASSERT(_value._number < ULONG_LONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("unsigned long long"));
651  #elif defined(ULLONG_MAX)
652  JSON_ASSERT(_value._number < ULLONG_MAX, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT("unsigned long long"));
653  #endif
654  JSON_ASSERT(_value._number == (json_number)((unsigned long long)_value._number), json_string(JSON_TEXT("(unsigned long long) will truncate ")) + _string);
655  return (unsigned long long)_value._number;
656  #endif /*<- */
657  }
658 #endif /*<- */
659 
660  /*
661  These functions are to allow allocation to be completely controlled by the callbacks
662  */
663 
664 #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
665  #include "JSONMemoryPool.h"
666  static memory_pool<INTERNALNODEPOOL> json_internal_mempool;
667 #endif /*<- */
668 
669 void internalJSONNode::deleteInternal(internalJSONNode * ptr) json_nothrow {
670  #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
671  ptr -> ~internalJSONNode();
672  json_internal_mempool.deallocate((void*)ptr);
673  #elif defined(JSON_MEMORY_CALLBACKS) /*<- else JSON_MEMORY_CALLBACKS */
674  ptr -> ~internalJSONNode();
675  libjson_free<internalJSONNode>(ptr);
676  #else /*<- else */
677  delete ptr;
678  #endif /*<- */
679 }
680 
681 internalJSONNode * internalJSONNode::newInternal(char mytype) {
682  #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
683  return new((internalJSONNode*)json_internal_mempool.allocate()) internalJSONNode(mytype);
684  #elif defined(JSON_MEMORY_CALLBACKS) /*<- else JSON_MEMORY_CALLBACKS */
685  return new(json_malloc<internalJSONNode>(1)) internalJSONNode(mytype);
686  #else /*<- else */
687  return new internalJSONNode(mytype);
688  #endif /*<- */
689 }
690 
691 #ifdef JSON_READ_PRIORITY /*-> JSON_READ_PRIORITY */
692 internalJSONNode * internalJSONNode::newInternal(const json_string & unparsed) {
693  #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
694  return new((internalJSONNode*)json_internal_mempool.allocate()) internalJSONNode(unparsed);
695  #elif defined(JSON_MEMORY_CALLBACKS) /*<- else JSON_MEMORY_CALLBACKS */
696  return new(json_malloc<internalJSONNode>(1)) internalJSONNode(unparsed);
697  #else /*<- else */
698  return new internalJSONNode(unparsed);
699  #endif /*<- */
700 }
701 
702 internalJSONNode * internalJSONNode::newInternal(const json_string & name_t, const json_string & value_t) {
703  #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
704  return new((internalJSONNode*)json_internal_mempool.allocate()) internalJSONNode(name_t, value_t);
705  #elif defined(JSON_MEMORY_CALLBACKS) /*<- else JSON_MEMORY_CALLBACKS */
706  return new(json_malloc<internalJSONNode>(1)) internalJSONNode(name_t, value_t);
707  #else /*<- else */
708  return new internalJSONNode(name_t, value_t);
709  #endif /*<- */
710 }
711 
712 #endif /*<- */
713 
714 internalJSONNode * internalJSONNode::newInternal(const internalJSONNode & orig) {
715  #ifdef JSON_MEMORY_POOL /*-> JSON_MEMORY_POOL */
716  return new((internalJSONNode*)json_internal_mempool.allocate()) internalJSONNode(orig);
717  #elif defined(JSON_MEMORY_CALLBACKS) /*<- else JSON_MEMORY_CALLBACKS */
718  return new(json_malloc<internalJSONNode>(1)) internalJSONNode(orig);
719  #else /*<- else */
720  return new internalJSONNode(orig);
721  #endif /*<- */
722 }
723 
724 #ifdef JSON_DEBUG /*-> JSON_MEMORY_POOL */
725  #ifndef JSON_LIBRARY /*-> JSON_MEMORY_POOL */
726  JSONNode internalJSONNode::Dump(size_t & totalbytes) const json_nothrow {
727  JSONNode dumpage(JSON_NODE);
728  dumpage.set_name(JSON_TEXT("internalJSONNode"));
729  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("this"), (long)this)));
730 
731  START_MEM_SCOPE
732  size_t memory = sizeof(internalJSONNode);
733  memory += _name.capacity() * sizeof(json_char);
734  memory += _string.capacity() * sizeof(json_char);
735  if (isContainer()){
736  memory += sizeof(jsonChildren);
737  memory += CHILDREN -> capacity() * sizeof(JSONNode*);
738  }
739  #ifdef JSON_COMMENTS /*-> JSON_COMMENTS */
740  memory += _comment.capacity() * sizeof(json_char);
741  #endif /*<- */
742  totalbytes += memory;
743  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("bytes used"), memory)));
744  END_MEM_SCOPE
745 
746 
747  #ifdef JSON_REF_COUNT /*-> JSON_REF_COUNT */
748  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("refcount"), refcount)));
749  #endif /*<- */
750  #ifdef JSON_MUTEX_CALLBACKS /*-> JSON_MUTEX_CALLBACKS */
751  dumpage.push_back(JSON_NEW(DumpMutex()));
752  #endif /*<- */
753 
754 
755  #define DUMPCASE(ty)\
756  case ty:\
757  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("_type"), JSON_TEXT(#ty))));\
758  break;
759 
760  switch(type()){
761  DUMPCASE(JSON_NULL)
762  DUMPCASE(JSON_STRING)
763  DUMPCASE(JSON_NUMBER)
764  DUMPCASE(JSON_BOOL)
765  DUMPCASE(JSON_ARRAY)
766  DUMPCASE(JSON_NODE)
767  default:
768  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("_type"), JSON_TEXT("Unknown"))));
769  }
770 
771  JSONNode str(JSON_NODE);
772  str.set_name(JSON_TEXT("_name"));
773  str.push_back(JSON_NEW(JSONNode(json_string(JSON_TEXT("value")), _name)));
774  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("length"), _name.length())));
775  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("capactiy"), _name.capacity())));
776 
777  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("_name_encoded"), _name_encoded)));
778  dumpage.push_back(JSON_NEW(str));
779  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("_string_encoded"), _string_encoded)));
780  str.clear();
781  str.set_name(JSON_TEXT("_string"));
782  str.push_back(JSON_NEW(JSONNode(json_string(JSON_TEXT("value")), _string)));
783  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("length"), _string.length())));
784  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("capactiy"), _string.capacity())));
785  dumpage.push_back(JSON_NEW(str));
786 
787  if ((type() == JSON_BOOL) || (type() == JSON_NUMBER)){
788  JSONNode unio(JSON_NODE);
789  unio.set_name(JSON_TEXT("_value"));
790  if (type() == JSON_BOOL){
791  unio.push_back(JSON_NEW(JSONNode(JSON_TEXT("_bool"), _value._bool)));
792  } else if (type() == JSON_NUMBER){
793  unio.push_back(JSON_NEW(JSONNode(JSON_TEXT("_number"), _value._number)));
794  }
795  dumpage.push_back(JSON_NEW(unio));
796  }
797 
798  #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) /*-> !JSON_PREPARSE && JSON_READ_PRIORITY */
799  dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("fetched"), fetched)));
800  #endif /*<- */
801 
802  #ifdef JSON_COMMENTS /*-> JSON_COMMENTS */
803  str.clear();
804  str.set_name(JSON_TEXT("_comment"));
805  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("value"), _comment)));
806  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("length"), _comment.length())));
807  str.push_back(JSON_NEW(JSONNode(JSON_TEXT("capactiy"), _comment.capacity())));
808  dumpage.push_back(JSON_NEW(str));
809  #endif /*<- */
810 
811  if (isContainer()){
812  JSONNode arra(JSON_NODE);
813  arra.set_name(JSON_TEXT("Children"));
814  arra.push_back(JSON_NEW(JSONNode(JSON_TEXT("size"), CHILDREN -> size())));
815  arra.push_back(JSON_NEW(JSONNode(JSON_TEXT("capacity"), CHILDREN -> capacity())));
816  JSONNode chil(JSON_ARRAY);
817  chil.set_name(JSON_TEXT("array"));
818  json_foreach(CHILDREN, it){
819  chil.push_back(JSON_NEW((*it) -> dump(totalbytes)));
820  }
821  arra.push_back(JSON_NEW(chil));
822  dumpage.push_back(JSON_NEW(arra));
823  }
824 
825  return dumpage;
826  }
827  #endif /*<- */
828 #endif /*<- */