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
internalJSONNode(const internalJSONNode & orig)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 */
internalJSONNode(const json_string & unparsed)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
internalJSONNode(const json_string & name_t,const json_string & value_t)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
~internalJSONNode(void)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
FetchString(void) const159 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
FetchNode(void) const169 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
FetchArray(void) const177 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
FetchNumber(void) const188 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)
Fetch(void) const227 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
Set(const json_string & val)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
Set(json_int_t val)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
Set(json_number val)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)
SET_INTEGER(short)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
IsEqualTo(const internalJSONNode * val) const346 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
Nullify(void) const379 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 */
push_back(JSONNode * node)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 /*<- */
829