JsonCpp project page JsonCpp home page

json_value.cpp
Go to the documentation of this file.
1 // Copyright 2011 Baptiste Lepilleur
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 
6 #if !defined(JSON_IS_AMALGAMATION)
7 #include <json/assertions.h>
8 #include <json/value.h>
9 #include <json/writer.h>
10 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
11 #include "json_batchallocator.h"
12 #endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
13 #endif // if !defined(JSON_IS_AMALGAMATION)
14 #include <math.h>
15 #include <sstream>
16 #include <utility>
17 #include <cstring>
18 #include <cassert>
19 #ifdef JSON_USE_CPPTL
20 #include <cpptl/conststring.h>
21 #endif
22 #include <cstddef> // size_t
23 
24 #define JSON_ASSERT_UNREACHABLE assert(false)
25 
26 namespace Json {
27 
28 // This is a walkaround to avoid the static initialization of Value::null.
29 // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
30 // 8 (instead of 4) as a bit of future-proofing.
31 #if defined(__ARMEL__)
32 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
33 #else
34 #define ALIGNAS(byte_alignment)
35 #endif
36 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
37 const unsigned char& kNullRef = kNull[0];
38 const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
39 
40 const Int Value::minInt = Int(~(UInt(-1) / 2));
41 const Int Value::maxInt = Int(UInt(-1) / 2);
42 const UInt Value::maxUInt = UInt(-1);
43 #if defined(JSON_HAS_INT64)
44 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
45 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
46 const UInt64 Value::maxUInt64 = UInt64(-1);
47 // The constant is hard-coded because some compiler have trouble
48 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
49 // Assumes that UInt64 is a 64 bits integer.
50 static const double maxUInt64AsDouble = 18446744073709551615.0;
51 #endif // defined(JSON_HAS_INT64)
55 
57 static const unsigned int unknown = (unsigned)-1;
58 
59 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
60 template <typename T, typename U>
61 static inline bool InRange(double d, T min, U max) {
62  return d >= min && d <= max;
63 }
64 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
65 static inline double integerToDouble(Json::UInt64 value) {
66  return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
67 }
68 
69 template <typename T> static inline double integerToDouble(T value) {
70  return static_cast<double>(value);
71 }
72 
73 template <typename T, typename U>
74 static inline bool InRange(double d, T min, U max) {
75  return d >= integerToDouble(min) && d <= integerToDouble(max);
76 }
77 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
78 
86 static inline char* duplicateStringValue(const char* value,
87  unsigned int length = unknown) {
88  if (length == unknown)
89  length = (unsigned int)strlen(value);
90 
91  // Avoid an integer overflow in the call to malloc below by limiting length
92  // to a sane value.
93  if (length >= (unsigned)Value::maxInt)
94  length = Value::maxInt - 1;
95 
96  char* newString = static_cast<char*>(malloc(length + 1));
97  JSON_ASSERT_MESSAGE(newString != 0,
98  "in Json::Value::duplicateStringValue(): "
99  "Failed to allocate string value buffer");
100  memcpy(newString, value, length);
101  newString[length] = 0;
102  return newString;
103 }
104 
107 static inline void releaseStringValue(char* value) { free(value); }
108 
109 } // namespace Json
110 
111 // //////////////////////////////////////////////////////////////////
112 // //////////////////////////////////////////////////////////////////
113 // //////////////////////////////////////////////////////////////////
114 // ValueInternals...
115 // //////////////////////////////////////////////////////////////////
116 // //////////////////////////////////////////////////////////////////
117 // //////////////////////////////////////////////////////////////////
118 #if !defined(JSON_IS_AMALGAMATION)
119 #ifdef JSON_VALUE_USE_INTERNAL_MAP
120 #include "json_internalarray.inl"
121 #include "json_internalmap.inl"
122 #endif // JSON_VALUE_USE_INTERNAL_MAP
123 
124 #include "json_valueiterator.inl"
125 #endif // if !defined(JSON_IS_AMALGAMATION)
126 
127 namespace Json {
128 
129 // //////////////////////////////////////////////////////////////////
130 // //////////////////////////////////////////////////////////////////
131 // //////////////////////////////////////////////////////////////////
132 // class Value::CommentInfo
133 // //////////////////////////////////////////////////////////////////
134 // //////////////////////////////////////////////////////////////////
135 // //////////////////////////////////////////////////////////////////
136 
137 Value::CommentInfo::CommentInfo() : comment_(0) {}
138 
139 Value::CommentInfo::~CommentInfo() {
140  if (comment_)
141  releaseStringValue(comment_);
142 }
143 
144 void Value::CommentInfo::setComment(const char* text) {
145  if (comment_)
146  releaseStringValue(comment_);
147  JSON_ASSERT(text != 0);
149  text[0] == '\0' || text[0] == '/',
150  "in Json::Value::setComment(): Comments must start with /");
151  // It seems that /**/ style comments are acceptable as well.
152  comment_ = duplicateStringValue(text);
153 }
154 
155 // //////////////////////////////////////////////////////////////////
156 // //////////////////////////////////////////////////////////////////
157 // //////////////////////////////////////////////////////////////////
158 // class Value::CZString
159 // //////////////////////////////////////////////////////////////////
160 // //////////////////////////////////////////////////////////////////
161 // //////////////////////////////////////////////////////////////////
162 #ifndef JSON_VALUE_USE_INTERNAL_MAP
163 
164 // Notes: index_ indicates if the string was allocated when
165 // a string is stored.
166 
167 Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {}
168 
169 Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate)
170  : cstr_(allocate == duplicate ? duplicateStringValue(cstr) : cstr),
171  index_(allocate) {}
172 
173 Value::CZString::CZString(const CZString& other)
174  : cstr_(other.index_ != noDuplication && other.cstr_ != 0
175  ? duplicateStringValue(other.cstr_)
176  : other.cstr_),
177  index_(other.cstr_
178  ? (other.index_ == noDuplication ? noDuplication : duplicate)
179  : other.index_) {}
180 
181 Value::CZString::~CZString() {
182  if (cstr_ && index_ == duplicate)
183  releaseStringValue(const_cast<char*>(cstr_));
184 }
185 
186 void Value::CZString::swap(CZString& other) {
187  std::swap(cstr_, other.cstr_);
188  std::swap(index_, other.index_);
189 }
190 
191 Value::CZString &Value::CZString::operator=(const CZString &other) {
192  CZString temp(other);
193  swap(temp);
194  return *this;
195 }
196 
197 bool Value::CZString::operator<(const CZString& other) const {
198  if (cstr_)
199  return strcmp(cstr_, other.cstr_) < 0;
200  return index_ < other.index_;
201 }
202 
203 bool Value::CZString::operator==(const CZString& other) const {
204  if (cstr_)
205  return strcmp(cstr_, other.cstr_) == 0;
206  return index_ == other.index_;
207 }
208 
209 ArrayIndex Value::CZString::index() const { return index_; }
210 
211 const char* Value::CZString::c_str() const { return cstr_; }
212 
213 bool Value::CZString::isStaticString() const { return index_ == noDuplication; }
214 
215 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
216 
217 // //////////////////////////////////////////////////////////////////
218 // //////////////////////////////////////////////////////////////////
219 // //////////////////////////////////////////////////////////////////
220 // class Value::Value
221 // //////////////////////////////////////////////////////////////////
222 // //////////////////////////////////////////////////////////////////
223 // //////////////////////////////////////////////////////////////////
224 
229 Value::Value(ValueType type)
230  : type_(type), allocated_(false)
231 #ifdef JSON_VALUE_USE_INTERNAL_MAP
232  ,
233  itemIsUsed_(0)
234 #endif
235  ,
236  comments_(0), start_(0), limit_(0) {
237  switch (type) {
238  case nullValue:
239  break;
240  case intValue:
241  case uintValue:
242  value_.int_ = 0;
243  break;
244  case realValue:
245  value_.real_ = 0.0;
246  break;
247  case stringValue:
248  value_.string_ = 0;
249  break;
250 #ifndef JSON_VALUE_USE_INTERNAL_MAP
251  case arrayValue:
252  case objectValue:
253  value_.map_ = new ObjectValues();
254  break;
255 #else
256  case arrayValue:
257  value_.array_ = arrayAllocator()->newArray();
258  break;
259  case objectValue:
260  value_.map_ = mapAllocator()->newMap();
261  break;
262 #endif
263  case booleanValue:
264  value_.bool_ = false;
265  break;
266  default:
268  }
269 }
270 
272  : type_(uintValue), allocated_(false)
273 #ifdef JSON_VALUE_USE_INTERNAL_MAP
274  ,
275  itemIsUsed_(0)
276 #endif
277  ,
278  comments_(0), start_(0), limit_(0) {
279  value_.uint_ = value;
280 }
281 
283  : type_(intValue), allocated_(false)
284 #ifdef JSON_VALUE_USE_INTERNAL_MAP
285  ,
286  itemIsUsed_(0)
287 #endif
288  ,
289  comments_(0), start_(0), limit_(0) {
290  value_.int_ = value;
291 }
292 
293 #if defined(JSON_HAS_INT64)
295  : type_(intValue), allocated_(false)
296 #ifdef JSON_VALUE_USE_INTERNAL_MAP
297  ,
298  itemIsUsed_(0)
299 #endif
300  ,
301  comments_(0), start_(0), limit_(0) {
302  value_.int_ = value;
303 }
304 
306  : type_(uintValue), allocated_(false)
307 #ifdef JSON_VALUE_USE_INTERNAL_MAP
308  ,
309  itemIsUsed_(0)
310 #endif
311  ,
312  comments_(0), start_(0), limit_(0) {
313  value_.uint_ = value;
314 }
315 #endif // defined(JSON_HAS_INT64)
316 
317 Value::Value(double value)
318  : type_(realValue), allocated_(false)
319 #ifdef JSON_VALUE_USE_INTERNAL_MAP
320  ,
321  itemIsUsed_(0)
322 #endif
323  ,
324  comments_(0), start_(0), limit_(0) {
325  value_.real_ = value;
326 }
327 
328 Value::Value(const char* value)
329  : type_(stringValue), allocated_(true)
330 #ifdef JSON_VALUE_USE_INTERNAL_MAP
331  ,
332  itemIsUsed_(0)
333 #endif
334  ,
335  comments_(0), start_(0), limit_(0) {
336  value_.string_ = duplicateStringValue(value);
337 }
338 
339 Value::Value(const char* beginValue, const char* endValue)
340  : type_(stringValue), allocated_(true)
341 #ifdef JSON_VALUE_USE_INTERNAL_MAP
342  ,
343  itemIsUsed_(0)
344 #endif
345  ,
346  comments_(0), start_(0), limit_(0) {
347  value_.string_ =
348  duplicateStringValue(beginValue, (unsigned int)(endValue - beginValue));
349 }
350 
351 Value::Value(const std::string& value)
352  : type_(stringValue), allocated_(true)
353 #ifdef JSON_VALUE_USE_INTERNAL_MAP
354  ,
355  itemIsUsed_(0)
356 #endif
357  ,
358  comments_(0), start_(0), limit_(0) {
359  value_.string_ =
360  duplicateStringValue(value.c_str(), (unsigned int)value.length());
361 }
362 
364  : type_(stringValue), allocated_(false)
365 #ifdef JSON_VALUE_USE_INTERNAL_MAP
366  ,
367  itemIsUsed_(0)
368 #endif
369  ,
370  comments_(0), start_(0), limit_(0) {
371  value_.string_ = const_cast<char*>(value.c_str());
372 }
373 
374 #ifdef JSON_USE_CPPTL
375 Value::Value(const CppTL::ConstString& value)
376  : type_(stringValue), allocated_(true)
377 #ifdef JSON_VALUE_USE_INTERNAL_MAP
378  ,
379  itemIsUsed_(0)
380 #endif
381  ,
382  comments_(0), start_(0), limit_(0) {
383  value_.string_ = duplicateStringValue(value, value.length());
384 }
385 #endif
386 
387 Value::Value(bool value)
388  : type_(booleanValue), allocated_(false)
389 #ifdef JSON_VALUE_USE_INTERNAL_MAP
390  ,
391  itemIsUsed_(0)
392 #endif
393  ,
394  comments_(0), start_(0), limit_(0) {
395  value_.bool_ = value;
396 }
397 
398 Value::Value(const Value& other)
399  : type_(other.type_), allocated_(false)
400 #ifdef JSON_VALUE_USE_INTERNAL_MAP
401  ,
402  itemIsUsed_(0)
403 #endif
404  ,
405  comments_(0), start_(other.start_), limit_(other.limit_) {
406  switch (type_) {
407  case nullValue:
408  case intValue:
409  case uintValue:
410  case realValue:
411  case booleanValue:
412  value_ = other.value_;
413  break;
414  case stringValue:
415  if (other.value_.string_) {
416  value_.string_ = duplicateStringValue(other.value_.string_);
417  allocated_ = true;
418  } else {
419  value_.string_ = 0;
420  allocated_ = false;
421  }
422  break;
423 #ifndef JSON_VALUE_USE_INTERNAL_MAP
424  case arrayValue:
425  case objectValue:
426  value_.map_ = new ObjectValues(*other.value_.map_);
427  break;
428 #else
429  case arrayValue:
430  value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_);
431  break;
432  case objectValue:
433  value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_);
434  break;
435 #endif
436  default:
438  }
439  if (other.comments_) {
440  comments_ = new CommentInfo[numberOfCommentPlacement];
441  for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
442  const CommentInfo& otherComment = other.comments_[comment];
443  if (otherComment.comment_)
444  comments_[comment].setComment(otherComment.comment_);
445  }
446  }
447 }
448 
450  switch (type_) {
451  case nullValue:
452  case intValue:
453  case uintValue:
454  case realValue:
455  case booleanValue:
456  break;
457  case stringValue:
458  if (allocated_)
459  releaseStringValue(value_.string_);
460  break;
461 #ifndef JSON_VALUE_USE_INTERNAL_MAP
462  case arrayValue:
463  case objectValue:
464  delete value_.map_;
465  break;
466 #else
467  case arrayValue:
468  arrayAllocator()->destructArray(value_.array_);
469  break;
470  case objectValue:
471  mapAllocator()->destructMap(value_.map_);
472  break;
473 #endif
474  default:
476  }
477 
478  if (comments_)
479  delete[] comments_;
480 }
481 
482 Value &Value::operator=(const Value &other) {
483  Value temp(other);
484  swap(temp);
485  return *this;
486 }
487 
488 void Value::swap(Value& other) {
489  ValueType temp = type_;
490  type_ = other.type_;
491  other.type_ = temp;
492  std::swap(value_, other.value_);
493  int temp2 = allocated_;
494  allocated_ = other.allocated_;
495  other.allocated_ = temp2;
496  std::swap(start_, other.start_);
497  std::swap(limit_, other.limit_);
498 }
499 
500 ValueType Value::type() const { return type_; }
501 
502 int Value::compare(const Value& other) const {
503  if (*this < other)
504  return -1;
505  if (*this > other)
506  return 1;
507  return 0;
508 }
509 
510 bool Value::operator<(const Value& other) const {
511  int typeDelta = type_ - other.type_;
512  if (typeDelta)
513  return typeDelta < 0 ? true : false;
514  switch (type_) {
515  case nullValue:
516  return false;
517  case intValue:
518  return value_.int_ < other.value_.int_;
519  case uintValue:
520  return value_.uint_ < other.value_.uint_;
521  case realValue:
522  return value_.real_ < other.value_.real_;
523  case booleanValue:
524  return value_.bool_ < other.value_.bool_;
525  case stringValue:
526  return (value_.string_ == 0 && other.value_.string_) ||
527  (other.value_.string_ && value_.string_ &&
528  strcmp(value_.string_, other.value_.string_) < 0);
529 #ifndef JSON_VALUE_USE_INTERNAL_MAP
530  case arrayValue:
531  case objectValue: {
532  int delta = int(value_.map_->size() - other.value_.map_->size());
533  if (delta)
534  return delta < 0;
535  return (*value_.map_) < (*other.value_.map_);
536  }
537 #else
538  case arrayValue:
539  return value_.array_->compare(*(other.value_.array_)) < 0;
540  case objectValue:
541  return value_.map_->compare(*(other.value_.map_)) < 0;
542 #endif
543  default:
545  }
546  return false; // unreachable
547 }
548 
549 bool Value::operator<=(const Value& other) const { return !(other < *this); }
550 
551 bool Value::operator>=(const Value& other) const { return !(*this < other); }
552 
553 bool Value::operator>(const Value& other) const { return other < *this; }
554 
555 bool Value::operator==(const Value& other) const {
556  // if ( type_ != other.type_ )
557  // GCC 2.95.3 says:
558  // attempt to take address of bit-field structure member `Json::Value::type_'
559  // Beats me, but a temp solves the problem.
560  int temp = other.type_;
561  if (type_ != temp)
562  return false;
563  switch (type_) {
564  case nullValue:
565  return true;
566  case intValue:
567  return value_.int_ == other.value_.int_;
568  case uintValue:
569  return value_.uint_ == other.value_.uint_;
570  case realValue:
571  return value_.real_ == other.value_.real_;
572  case booleanValue:
573  return value_.bool_ == other.value_.bool_;
574  case stringValue:
575  return (value_.string_ == other.value_.string_) ||
576  (other.value_.string_ && value_.string_ &&
577  strcmp(value_.string_, other.value_.string_) == 0);
578 #ifndef JSON_VALUE_USE_INTERNAL_MAP
579  case arrayValue:
580  case objectValue:
581  return value_.map_->size() == other.value_.map_->size() &&
582  (*value_.map_) == (*other.value_.map_);
583 #else
584  case arrayValue:
585  return value_.array_->compare(*(other.value_.array_)) == 0;
586  case objectValue:
587  return value_.map_->compare(*(other.value_.map_)) == 0;
588 #endif
589  default:
591  }
592  return false; // unreachable
593 }
594 
595 bool Value::operator!=(const Value& other) const { return !(*this == other); }
596 
597 const char* Value::asCString() const {
599  "in Json::Value::asCString(): requires stringValue");
600  return value_.string_;
601 }
602 
603 std::string Value::asString() const {
604  switch (type_) {
605  case nullValue:
606  return "";
607  case stringValue:
608  return value_.string_ ? value_.string_ : "";
609  case booleanValue:
610  return value_.bool_ ? "true" : "false";
611  case intValue:
612  return valueToString(value_.int_);
613  case uintValue:
614  return valueToString(value_.uint_);
615  case realValue:
616  return valueToString(value_.real_);
617  default:
618  JSON_FAIL_MESSAGE("Type is not convertible to string");
619  }
620 }
621 
622 #ifdef JSON_USE_CPPTL
623 CppTL::ConstString Value::asConstString() const {
624  return CppTL::ConstString(asString().c_str());
625 }
626 #endif
627 
629  switch (type_) {
630  case intValue:
631  JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
632  return Int(value_.int_);
633  case uintValue:
634  JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
635  return Int(value_.uint_);
636  case realValue:
637  JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
638  "double out of Int range");
639  return Int(value_.real_);
640  case nullValue:
641  return 0;
642  case booleanValue:
643  return value_.bool_ ? 1 : 0;
644  default:
645  break;
646  }
647  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
648 }
649 
651  switch (type_) {
652  case intValue:
653  JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
654  return UInt(value_.int_);
655  case uintValue:
656  JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
657  return UInt(value_.uint_);
658  case realValue:
659  JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
660  "double out of UInt range");
661  return UInt(value_.real_);
662  case nullValue:
663  return 0;
664  case booleanValue:
665  return value_.bool_ ? 1 : 0;
666  default:
667  break;
668  }
669  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
670 }
671 
672 #if defined(JSON_HAS_INT64)
673 
675  switch (type_) {
676  case intValue:
677  return Int64(value_.int_);
678  case uintValue:
679  JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
680  return Int64(value_.uint_);
681  case realValue:
683  "double out of Int64 range");
684  return Int64(value_.real_);
685  case nullValue:
686  return 0;
687  case booleanValue:
688  return value_.bool_ ? 1 : 0;
689  default:
690  break;
691  }
692  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
693 }
694 
696  switch (type_) {
697  case intValue:
698  JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
699  return UInt64(value_.int_);
700  case uintValue:
701  return UInt64(value_.uint_);
702  case realValue:
703  JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
704  "double out of UInt64 range");
705  return UInt64(value_.real_);
706  case nullValue:
707  return 0;
708  case booleanValue:
709  return value_.bool_ ? 1 : 0;
710  default:
711  break;
712  }
713  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
714 }
715 #endif // if defined(JSON_HAS_INT64)
716 
718 #if defined(JSON_NO_INT64)
719  return asInt();
720 #else
721  return asInt64();
722 #endif
723 }
724 
726 #if defined(JSON_NO_INT64)
727  return asUInt();
728 #else
729  return asUInt64();
730 #endif
731 }
732 
733 double Value::asDouble() const {
734  switch (type_) {
735  case intValue:
736  return static_cast<double>(value_.int_);
737  case uintValue:
738 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
739  return static_cast<double>(value_.uint_);
740 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
741  return integerToDouble(value_.uint_);
742 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
743  case realValue:
744  return value_.real_;
745  case nullValue:
746  return 0.0;
747  case booleanValue:
748  return value_.bool_ ? 1.0 : 0.0;
749  default:
750  break;
751  }
752  JSON_FAIL_MESSAGE("Value is not convertible to double.");
753 }
754 
755 float Value::asFloat() const {
756  switch (type_) {
757  case intValue:
758  return static_cast<float>(value_.int_);
759  case uintValue:
760 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
761  return static_cast<float>(value_.uint_);
762 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
763  return integerToDouble(value_.uint_);
764 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
765  case realValue:
766  return static_cast<float>(value_.real_);
767  case nullValue:
768  return 0.0;
769  case booleanValue:
770  return value_.bool_ ? 1.0f : 0.0f;
771  default:
772  break;
773  }
774  JSON_FAIL_MESSAGE("Value is not convertible to float.");
775 }
776 
777 bool Value::asBool() const {
778  switch (type_) {
779  case booleanValue:
780  return value_.bool_;
781  case nullValue:
782  return false;
783  case intValue:
784  return value_.int_ ? true : false;
785  case uintValue:
786  return value_.uint_ ? true : false;
787  case realValue:
788  return value_.real_ ? true : false;
789  default:
790  break;
791  }
792  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
793 }
794 
796  switch (other) {
797  case nullValue:
798  return (isNumeric() && asDouble() == 0.0) ||
799  (type_ == booleanValue && value_.bool_ == false) ||
800  (type_ == stringValue && asString() == "") ||
801  (type_ == arrayValue && value_.map_->size() == 0) ||
802  (type_ == objectValue && value_.map_->size() == 0) ||
803  type_ == nullValue;
804  case intValue:
805  return isInt() ||
806  (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
807  type_ == booleanValue || type_ == nullValue;
808  case uintValue:
809  return isUInt() ||
810  (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
811  type_ == booleanValue || type_ == nullValue;
812  case realValue:
813  return isNumeric() || type_ == booleanValue || type_ == nullValue;
814  case booleanValue:
815  return isNumeric() || type_ == booleanValue || type_ == nullValue;
816  case stringValue:
817  return isNumeric() || type_ == booleanValue || type_ == stringValue ||
818  type_ == nullValue;
819  case arrayValue:
820  return type_ == arrayValue || type_ == nullValue;
821  case objectValue:
822  return type_ == objectValue || type_ == nullValue;
823  }
825  return false;
826 }
827 
830  switch (type_) {
831  case nullValue:
832  case intValue:
833  case uintValue:
834  case realValue:
835  case booleanValue:
836  case stringValue:
837  return 0;
838 #ifndef JSON_VALUE_USE_INTERNAL_MAP
839  case arrayValue: // size of the array is highest index + 1
840  if (!value_.map_->empty()) {
841  ObjectValues::const_iterator itLast = value_.map_->end();
842  --itLast;
843  return (*itLast).first.index() + 1;
844  }
845  return 0;
846  case objectValue:
847  return ArrayIndex(value_.map_->size());
848 #else
849  case arrayValue:
850  return Int(value_.array_->size());
851  case objectValue:
852  return Int(value_.map_->size());
853 #endif
854  }
856  return 0; // unreachable;
857 }
858 
859 bool Value::empty() const {
860  if (isNull() || isArray() || isObject())
861  return size() == 0u;
862  else
863  return false;
864 }
865 
866 bool Value::operator!() const { return isNull(); }
867 
868 void Value::clear() {
869  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
870  type_ == objectValue,
871  "in Json::Value::clear(): requires complex value");
872  start_ = 0;
873  limit_ = 0;
874  switch (type_) {
875 #ifndef JSON_VALUE_USE_INTERNAL_MAP
876  case arrayValue:
877  case objectValue:
878  value_.map_->clear();
879  break;
880 #else
881  case arrayValue:
882  value_.array_->clear();
883  break;
884  case objectValue:
885  value_.map_->clear();
886  break;
887 #endif
888  default:
889  break;
890  }
891 }
892 
893 void Value::resize(ArrayIndex newSize) {
894  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
895  "in Json::Value::resize(): requires arrayValue");
896  if (type_ == nullValue)
897  *this = Value(arrayValue);
898 #ifndef JSON_VALUE_USE_INTERNAL_MAP
899  ArrayIndex oldSize = size();
900  if (newSize == 0)
901  clear();
902  else if (newSize > oldSize)
903  (*this)[newSize - 1];
904  else {
905  for (ArrayIndex index = newSize; index < oldSize; ++index) {
906  value_.map_->erase(index);
907  }
908  assert(size() == newSize);
909  }
910 #else
911  value_.array_->resize(newSize);
912 #endif
913 }
914 
917  type_ == nullValue || type_ == arrayValue,
918  "in Json::Value::operator[](ArrayIndex): requires arrayValue");
919  if (type_ == nullValue)
920  *this = Value(arrayValue);
921 #ifndef JSON_VALUE_USE_INTERNAL_MAP
922  CZString key(index);
923  ObjectValues::iterator it = value_.map_->lower_bound(key);
924  if (it != value_.map_->end() && (*it).first == key)
925  return (*it).second;
926 
927  ObjectValues::value_type defaultValue(key, null);
928  it = value_.map_->insert(it, defaultValue);
929  return (*it).second;
930 #else
931  return value_.array_->resolveReference(index);
932 #endif
933 }
934 
937  index >= 0,
938  "in Json::Value::operator[](int index): index cannot be negative");
939  return (*this)[ArrayIndex(index)];
940 }
941 
942 const Value& Value::operator[](ArrayIndex index) const {
944  type_ == nullValue || type_ == arrayValue,
945  "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
946  if (type_ == nullValue)
947  return null;
948 #ifndef JSON_VALUE_USE_INTERNAL_MAP
949  CZString key(index);
950  ObjectValues::const_iterator it = value_.map_->find(key);
951  if (it == value_.map_->end())
952  return null;
953  return (*it).second;
954 #else
955  Value* value = value_.array_->find(index);
956  return value ? *value : null;
957 #endif
958 }
959 
960 const Value& Value::operator[](int index) const {
962  index >= 0,
963  "in Json::Value::operator[](int index) const: index cannot be negative");
964  return (*this)[ArrayIndex(index)];
965 }
966 
967 Value& Value::operator[](const char* key) {
968  return resolveReference(key, false);
969 }
970 
971 Value& Value::resolveReference(const char* key, bool isStatic) {
973  type_ == nullValue || type_ == objectValue,
974  "in Json::Value::resolveReference(): requires objectValue");
975  if (type_ == nullValue)
976  *this = Value(objectValue);
977 #ifndef JSON_VALUE_USE_INTERNAL_MAP
978  CZString actualKey(
979  key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
980  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
981  if (it != value_.map_->end() && (*it).first == actualKey)
982  return (*it).second;
983 
984  ObjectValues::value_type defaultValue(actualKey, null);
985  it = value_.map_->insert(it, defaultValue);
986  Value& value = (*it).second;
987  return value;
988 #else
989  return value_.map_->resolveReference(key, isStatic);
990 #endif
991 }
992 
993 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
994  const Value* value = &((*this)[index]);
995  return value == &null ? defaultValue : *value;
996 }
997 
998 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
999 
1000 const Value& Value::operator[](const char* key) const {
1002  type_ == nullValue || type_ == objectValue,
1003  "in Json::Value::operator[](char const*)const: requires objectValue");
1004  if (type_ == nullValue)
1005  return null;
1006 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1007  CZString actualKey(key, CZString::noDuplication);
1008  ObjectValues::const_iterator it = value_.map_->find(actualKey);
1009  if (it == value_.map_->end())
1010  return null;
1011  return (*it).second;
1012 #else
1013  const Value* value = value_.map_->find(key);
1014  return value ? *value : null;
1015 #endif
1016 }
1017 
1018 Value& Value::operator[](const std::string& key) {
1019  return (*this)[key.c_str()];
1020 }
1021 
1022 const Value& Value::operator[](const std::string& key) const {
1023  return (*this)[key.c_str()];
1024 }
1025 
1027  return resolveReference(key, true);
1028 }
1029 
1030 #ifdef JSON_USE_CPPTL
1031 Value& Value::operator[](const CppTL::ConstString& key) {
1032  return (*this)[key.c_str()];
1033 }
1034 
1035 const Value& Value::operator[](const CppTL::ConstString& key) const {
1036  return (*this)[key.c_str()];
1037 }
1038 #endif
1039 
1040 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
1041 
1042 Value Value::get(const char* key, const Value& defaultValue) const {
1043  const Value* value = &((*this)[key]);
1044  return value == &null ? defaultValue : *value;
1045 }
1046 
1047 Value Value::get(const std::string& key, const Value& defaultValue) const {
1048  return get(key.c_str(), defaultValue);
1049 }
1050 
1051 Value Value::removeMember(const char* key) {
1052  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
1053  "in Json::Value::removeMember(): requires objectValue");
1054  if (type_ == nullValue)
1055  return null;
1056 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1057  CZString actualKey(key, CZString::noDuplication);
1058  ObjectValues::iterator it = value_.map_->find(actualKey);
1059  if (it == value_.map_->end())
1060  return null;
1061  Value old(it->second);
1062  value_.map_->erase(it);
1063  return old;
1064 #else
1065  Value* value = value_.map_->find(key);
1066  if (value) {
1067  Value old(*value);
1068  value_.map_.remove(key);
1069  return old;
1070  } else {
1071  return null;
1072  }
1073 #endif
1074 }
1075 
1076 Value Value::removeMember(const std::string& key) {
1077  return removeMember(key.c_str());
1078 }
1079 
1080 #ifdef JSON_USE_CPPTL
1081 Value Value::get(const CppTL::ConstString& key,
1082  const Value& defaultValue) const {
1083  return get(key.c_str(), defaultValue);
1084 }
1085 #endif
1086 
1087 bool Value::isMember(const char* key) const {
1088  const Value* value = &((*this)[key]);
1089  return value != &null;
1090 }
1091 
1092 bool Value::isMember(const std::string& key) const {
1093  return isMember(key.c_str());
1094 }
1095 
1096 #ifdef JSON_USE_CPPTL
1097 bool Value::isMember(const CppTL::ConstString& key) const {
1098  return isMember(key.c_str());
1099 }
1100 #endif
1101 
1104  type_ == nullValue || type_ == objectValue,
1105  "in Json::Value::getMemberNames(), value must be objectValue");
1106  if (type_ == nullValue)
1107  return Value::Members();
1108  Members members;
1109  members.reserve(value_.map_->size());
1110 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1111  ObjectValues::const_iterator it = value_.map_->begin();
1112  ObjectValues::const_iterator itEnd = value_.map_->end();
1113  for (; it != itEnd; ++it)
1114  members.push_back(std::string((*it).first.c_str()));
1115 #else
1116  ValueInternalMap::IteratorState it;
1117  ValueInternalMap::IteratorState itEnd;
1118  value_.map_->makeBeginIterator(it);
1119  value_.map_->makeEndIterator(itEnd);
1120  for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
1121  members.push_back(std::string(ValueInternalMap::key(it)));
1122 #endif
1123  return members;
1124 }
1125 //
1126 //# ifdef JSON_USE_CPPTL
1127 // EnumMemberNames
1128 // Value::enumMemberNames() const
1129 //{
1130 // if ( type_ == objectValue )
1131 // {
1132 // return CppTL::Enum::any( CppTL::Enum::transform(
1133 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
1134 // MemberNamesTransform() ) );
1135 // }
1136 // return EnumMemberNames();
1137 //}
1138 //
1139 //
1140 // EnumValues
1141 // Value::enumValues() const
1142 //{
1143 // if ( type_ == objectValue || type_ == arrayValue )
1144 // return CppTL::Enum::anyValues( *(value_.map_),
1145 // CppTL::Type<const Value &>() );
1146 // return EnumValues();
1147 //}
1148 //
1149 //# endif
1150 
1151 static bool IsIntegral(double d) {
1152  double integral_part;
1153  return modf(d, &integral_part) == 0.0;
1154 }
1155 
1156 bool Value::isNull() const { return type_ == nullValue; }
1157 
1158 bool Value::isBool() const { return type_ == booleanValue; }
1159 
1160 bool Value::isInt() const {
1161  switch (type_) {
1162  case intValue:
1163  return value_.int_ >= minInt && value_.int_ <= maxInt;
1164  case uintValue:
1165  return value_.uint_ <= UInt(maxInt);
1166  case realValue:
1167  return value_.real_ >= minInt && value_.real_ <= maxInt &&
1168  IsIntegral(value_.real_);
1169  default:
1170  break;
1171  }
1172  return false;
1173 }
1174 
1175 bool Value::isUInt() const {
1176  switch (type_) {
1177  case intValue:
1178  return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
1179  case uintValue:
1180  return value_.uint_ <= maxUInt;
1181  case realValue:
1182  return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1183  IsIntegral(value_.real_);
1184  default:
1185  break;
1186  }
1187  return false;
1188 }
1189 
1190 bool Value::isInt64() const {
1191 #if defined(JSON_HAS_INT64)
1192  switch (type_) {
1193  case intValue:
1194  return true;
1195  case uintValue:
1196  return value_.uint_ <= UInt64(maxInt64);
1197  case realValue:
1198  // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1199  // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1200  // require the value to be strictly less than the limit.
1201  return value_.real_ >= double(minInt64) &&
1202  value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
1203  default:
1204  break;
1205  }
1206 #endif // JSON_HAS_INT64
1207  return false;
1208 }
1209 
1210 bool Value::isUInt64() const {
1211 #if defined(JSON_HAS_INT64)
1212  switch (type_) {
1213  case intValue:
1214  return value_.int_ >= 0;
1215  case uintValue:
1216  return true;
1217  case realValue:
1218  // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1219  // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1220  // require the value to be strictly less than the limit.
1221  return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1222  IsIntegral(value_.real_);
1223  default:
1224  break;
1225  }
1226 #endif // JSON_HAS_INT64
1227  return false;
1228 }
1229 
1230 bool Value::isIntegral() const {
1231 #if defined(JSON_HAS_INT64)
1232  return isInt64() || isUInt64();
1233 #else
1234  return isInt() || isUInt();
1235 #endif
1236 }
1237 
1238 bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
1239 
1240 bool Value::isNumeric() const { return isIntegral() || isDouble(); }
1241 
1242 bool Value::isString() const { return type_ == stringValue; }
1243 
1244 bool Value::isArray() const { return type_ == arrayValue; }
1245 
1246 bool Value::isObject() const { return type_ == objectValue; }
1247 
1248 void Value::setComment(const char* comment, CommentPlacement placement) {
1249  if (!comments_)
1250  comments_ = new CommentInfo[numberOfCommentPlacement];
1251  comments_[placement].setComment(comment);
1252 }
1253 
1254 void Value::setComment(const std::string& comment, CommentPlacement placement) {
1255  setComment(comment.c_str(), placement);
1256 }
1257 
1258 bool Value::hasComment(CommentPlacement placement) const {
1259  return comments_ != 0 && comments_[placement].comment_ != 0;
1260 }
1261 
1262 std::string Value::getComment(CommentPlacement placement) const {
1263  if (hasComment(placement))
1264  return comments_[placement].comment_;
1265  return "";
1266 }
1267 
1268 void Value::setOffsetStart(size_t start) { start_ = start; }
1269 
1270 void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
1271 
1272 size_t Value::getOffsetStart() const { return start_; }
1273 
1274 size_t Value::getOffsetLimit() const { return limit_; }
1275 
1276 std::string Value::toStyledString() const {
1277  StyledWriter writer;
1278  return writer.write(*this);
1279 }
1280 
1282  switch (type_) {
1283 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1284  case arrayValue:
1285  if (value_.array_) {
1286  ValueInternalArray::IteratorState it;
1287  value_.array_->makeBeginIterator(it);
1288  return const_iterator(it);
1289  }
1290  break;
1291  case objectValue:
1292  if (value_.map_) {
1293  ValueInternalMap::IteratorState it;
1294  value_.map_->makeBeginIterator(it);
1295  return const_iterator(it);
1296  }
1297  break;
1298 #else
1299  case arrayValue:
1300  case objectValue:
1301  if (value_.map_)
1302  return const_iterator(value_.map_->begin());
1303  break;
1304 #endif
1305  default:
1306  break;
1307  }
1308  return const_iterator();
1309 }
1310 
1312  switch (type_) {
1313 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1314  case arrayValue:
1315  if (value_.array_) {
1316  ValueInternalArray::IteratorState it;
1317  value_.array_->makeEndIterator(it);
1318  return const_iterator(it);
1319  }
1320  break;
1321  case objectValue:
1322  if (value_.map_) {
1323  ValueInternalMap::IteratorState it;
1324  value_.map_->makeEndIterator(it);
1325  return const_iterator(it);
1326  }
1327  break;
1328 #else
1329  case arrayValue:
1330  case objectValue:
1331  if (value_.map_)
1332  return const_iterator(value_.map_->end());
1333  break;
1334 #endif
1335  default:
1336  break;
1337  }
1338  return const_iterator();
1339 }
1340 
1342  switch (type_) {
1343 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1344  case arrayValue:
1345  if (value_.array_) {
1346  ValueInternalArray::IteratorState it;
1347  value_.array_->makeBeginIterator(it);
1348  return iterator(it);
1349  }
1350  break;
1351  case objectValue:
1352  if (value_.map_) {
1353  ValueInternalMap::IteratorState it;
1354  value_.map_->makeBeginIterator(it);
1355  return iterator(it);
1356  }
1357  break;
1358 #else
1359  case arrayValue:
1360  case objectValue:
1361  if (value_.map_)
1362  return iterator(value_.map_->begin());
1363  break;
1364 #endif
1365  default:
1366  break;
1367  }
1368  return iterator();
1369 }
1370 
1372  switch (type_) {
1373 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1374  case arrayValue:
1375  if (value_.array_) {
1376  ValueInternalArray::IteratorState it;
1377  value_.array_->makeEndIterator(it);
1378  return iterator(it);
1379  }
1380  break;
1381  case objectValue:
1382  if (value_.map_) {
1383  ValueInternalMap::IteratorState it;
1384  value_.map_->makeEndIterator(it);
1385  return iterator(it);
1386  }
1387  break;
1388 #else
1389  case arrayValue:
1390  case objectValue:
1391  if (value_.map_)
1392  return iterator(value_.map_->end());
1393  break;
1394 #endif
1395  default:
1396  break;
1397  }
1398  return iterator();
1399 }
1400 
1401 // class PathArgument
1402 // //////////////////////////////////////////////////////////////////
1403 
1404 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
1405 
1407  : key_(), index_(index), kind_(kindIndex) {}
1408 
1410  : key_(key), index_(), kind_(kindKey) {}
1411 
1412 PathArgument::PathArgument(const std::string& key)
1413  : key_(key.c_str()), index_(), kind_(kindKey) {}
1414 
1415 // class Path
1416 // //////////////////////////////////////////////////////////////////
1417 
1418 Path::Path(const std::string& path,
1419  const PathArgument& a1,
1420  const PathArgument& a2,
1421  const PathArgument& a3,
1422  const PathArgument& a4,
1423  const PathArgument& a5) {
1424  InArgs in;
1425  in.push_back(&a1);
1426  in.push_back(&a2);
1427  in.push_back(&a3);
1428  in.push_back(&a4);
1429  in.push_back(&a5);
1430  makePath(path, in);
1431 }
1432 
1433 void Path::makePath(const std::string& path, const InArgs& in) {
1434  const char* current = path.c_str();
1435  const char* end = current + path.length();
1436  InArgs::const_iterator itInArg = in.begin();
1437  while (current != end) {
1438  if (*current == '[') {
1439  ++current;
1440  if (*current == '%')
1441  addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1442  else {
1443  ArrayIndex index = 0;
1444  for (; current != end && *current >= '0' && *current <= '9'; ++current)
1445  index = index * 10 + ArrayIndex(*current - '0');
1446  args_.push_back(index);
1447  }
1448  if (current == end || *current++ != ']')
1449  invalidPath(path, int(current - path.c_str()));
1450  } else if (*current == '%') {
1451  addPathInArg(path, in, itInArg, PathArgument::kindKey);
1452  ++current;
1453  } else if (*current == '.') {
1454  ++current;
1455  } else {
1456  const char* beginName = current;
1457  while (current != end && !strchr("[.", *current))
1458  ++current;
1459  args_.push_back(std::string(beginName, current));
1460  }
1461  }
1462 }
1463 
1464 void Path::addPathInArg(const std::string& /*path*/,
1465  const InArgs& in,
1466  InArgs::const_iterator& itInArg,
1467  PathArgument::Kind kind) {
1468  if (itInArg == in.end()) {
1469  // Error: missing argument %d
1470  } else if ((*itInArg)->kind_ != kind) {
1471  // Error: bad argument type
1472  } else {
1473  args_.push_back(**itInArg);
1474  }
1475 }
1476 
1477 void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
1478  // Error: invalid path.
1479 }
1480 
1481 const Value& Path::resolve(const Value& root) const {
1482  const Value* node = &root;
1483  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1484  const PathArgument& arg = *it;
1485  if (arg.kind_ == PathArgument::kindIndex) {
1486  if (!node->isArray() || !node->isValidIndex(arg.index_)) {
1487  // Error: unable to resolve path (array value expected at position...
1488  }
1489  node = &((*node)[arg.index_]);
1490  } else if (arg.kind_ == PathArgument::kindKey) {
1491  if (!node->isObject()) {
1492  // Error: unable to resolve path (object value expected at position...)
1493  }
1494  node = &((*node)[arg.key_]);
1495  if (node == &Value::null) {
1496  // Error: unable to resolve path (object has no member named '' at
1497  // position...)
1498  }
1499  }
1500  }
1501  return *node;
1502 }
1503 
1504 Value Path::resolve(const Value& root, const Value& defaultValue) const {
1505  const Value* node = &root;
1506  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1507  const PathArgument& arg = *it;
1508  if (arg.kind_ == PathArgument::kindIndex) {
1509  if (!node->isArray() || !node->isValidIndex(arg.index_))
1510  return defaultValue;
1511  node = &((*node)[arg.index_]);
1512  } else if (arg.kind_ == PathArgument::kindKey) {
1513  if (!node->isObject())
1514  return defaultValue;
1515  node = &((*node)[arg.key_]);
1516  if (node == &Value::null)
1517  return defaultValue;
1518  }
1519  }
1520  return *node;
1521 }
1522 
1523 Value& Path::make(Value& root) const {
1524  Value* node = &root;
1525  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1526  const PathArgument& arg = *it;
1527  if (arg.kind_ == PathArgument::kindIndex) {
1528  if (!node->isArray()) {
1529  // Error: node is not an array at position ...
1530  }
1531  node = &((*node)[arg.index_]);
1532  } else if (arg.kind_ == PathArgument::kindKey) {
1533  if (!node->isObject()) {
1534  // Error: node is not an object at position...
1535  }
1536  node = &((*node)[arg.key_]);
1537  }
1538  }
1539  return *node;
1540 }
1541 
1542 } // namespace Json
const unsigned char & kNullRef
Definition: json_value.cpp:37
bool hasComment(CommentPlacement placement) const
Path(const std::string &path, const PathArgument &a1=PathArgument(), const PathArgument &a2=PathArgument(), const PathArgument &a3=PathArgument(), const PathArgument &a4=PathArgument(), const PathArgument &a5=PathArgument())
Int64 LargestInt
Definition: config.h:106
UInt64 asUInt64() const
Definition: json_value.cpp:695
Writes a Value in JSON format in a human friendly way.
Definition: writer.h:94
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
static bool IsIntegral(double d)
Int asInt() const
Definition: json_value.cpp:628
std::string asString() const
Definition: json_value.cpp:603
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
Definition: value.h:155
unsigned int ArrayIndex
Definition: forwards.h:23
static const Value & null
Definition: value.h:136
bool isNull() const
std::vector< std::string > Members
Definition: value.h:123
double asDouble() const
Definition: json_value.cpp:733
array value (ordered list)
Definition: value.h:44
static char * duplicateStringValue(const char *value, unsigned int length=unknown)
Duplicates the specified string value.
Definition: json_value.cpp:86
unsigned __int64 UInt64
Definition: config.h:101
LargestUInt asLargestUInt() const
Definition: json_value.cpp:725
#define JSON_ASSERT_MESSAGE(condition, message)
Definition: assertions.h:36
unsigned integer value
Definition: value.h:40
bool isBool() const
#define ALIGNAS(byte_alignment)
Definition: json_value.cpp:34
bool operator<(const Value &other) const
Definition: json_value.cpp:510
Json::ArrayIndex ArrayIndex
Definition: value.h:134
int compare(const Value &other) const
Definition: json_value.cpp:502
object value (collection of name/value pairs).
Definition: value.h:45
void setOffsetStart(size_t start)
static const Int maxInt
Maximum signed int value that can be stored in a Json::Value.
Definition: value.h:147
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Definition: json_value.cpp:859
Lightweight wrapper to tag static string.
Definition: value.h:75
Value removeMember(const char *key)
Remove and return the named member.
#define JSON_ASSERT(condition)
Definition: assertions.h:17
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
Definition: value.h:149
Json::LargestUInt LargestUInt
Definition: value.h:133
bool isUInt64() const
static ValueArrayAllocator *& arrayAllocator()
virtual ValueInternalMap * newMap()=0
const iterator for object and array value.
Definition: value.h:972
bool asBool() const
Definition: json_value.cpp:777
virtual void destructArray(ValueInternalArray *array)=0
bool isObject() const
Value(ValueType type=nullValue)
Create a default Value of the given type.
Definition: json_value.cpp:229
Experimental and untested: represents an element of the "path" to access a node.
Definition: value.h:506
void setComment(const char *comment, CommentPlacement placement)
Comments must be //... or /* ... */.
static bool InRange(double d, T min, U max)
Definition: json_value.cpp:61
bool isDouble() const
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
Definition: value.h:138
'null' value
Definition: value.h:38
CommentPlacement
Definition: value.h:48
virtual ValueInternalArray * newArray()=0
bool isMember(const char *key) const
Return true if the object has a member named key.
virtual ValueInternalArray * newArrayCopy(const ValueInternalArray &other)=0
static const unsigned char kNull[sizeof(Value)]
Definition: json_value.cpp:36
UInt64 LargestUInt
Definition: config.h:107
Value & operator[](ArrayIndex index)
Access an array element (zero based index ).
Definition: json_value.cpp:915
size_t getOffsetLimit() const
bool isIntegral() const
ValueConstIterator const_iterator
Definition: value.h:125
std::string valueToString(Int value)
Definition: json_writer.cpp:67
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: json_reader.cpp:50
virtual std::string write(const Value &root)
Serialize a Value in JSON format.
UInt asUInt() const
Definition: json_value.cpp:650
Members getMemberNames() const
Return a list of the member names.
Json::Int64 Int64
Definition: value.h:130
#define JSON_FAIL_MESSAGE(message)
Definition: assertions.h:19
bool isString() const
void swap(Value &other)
Swap values.
Definition: json_value.cpp:488
Json::LargestInt LargestInt
Definition: value.h:132
const char * c_str() const
Definition: value.h:81
static const double maxUInt64AsDouble
Definition: json_value.cpp:50
const char * asCString() const
Definition: json_value.cpp:597
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
Definition: value.h:157
bool isInt() const
static const unsigned int unknown
Unknown size marker.
Definition: json_value.cpp:57
double value
Definition: value.h:41
bool operator>(const Value &other) const
Definition: json_value.cpp:553
static ValueMapAllocator *& mapAllocator()
bool operator>=(const Value &other) const
Definition: json_value.cpp:551
Json::UInt UInt
Definition: value.h:126
bool operator==(const Value &other) const
Definition: json_value.cpp:555
const Value & resolve(const Value &root) const
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
Definition: json_value.cpp:998
Value & append(const Value &value)
Append value to array at the end.
Value & operator=(const Value &other)
Definition: json_value.cpp:482
float asFloat() const
Definition: json_value.cpp:755
ArrayIndex size() const
Number of values in array or object.
Definition: json_value.cpp:829
std::string toStyledString() const
Json::UInt64 UInt64
Definition: value.h:129
Json::Int Int
Definition: value.h:127
bool isUInt() const
#define JSON_ASSERT_UNREACHABLE
Definition: json_value.cpp:24
Represents a JSON value.
Definition: value.h:116
Int64 asInt64() const
Definition: json_value.cpp:674
ValueType type() const
Definition: json_value.cpp:500
ValueIterator iterator
Definition: value.h:124
bool isConvertibleTo(ValueType other) const
Definition: json_value.cpp:795
void setOffsetLimit(size_t limit)
static const Int64 minInt64
Minimum signed 64 bits int value that can be stored in a Json::Value.
Definition: value.h:153
static const Int minInt
Minimum signed int value that can be stored in a Json::Value.
Definition: value.h:145
bool operator!() const
Return isNull()
Definition: json_value.cpp:866
LargestInt asLargestInt() const
Definition: json_value.cpp:717
unsigned int UInt
Definition: config.h:92
virtual ValueInternalMap * newMapCopy(const ValueInternalMap &other)=0
void resize(ArrayIndex size)
Resize the array to size elements.
Definition: json_value.cpp:893
void clear()
Remove all object members and array elements.
Definition: json_value.cpp:868
Iterator for object and array value.
Definition: value.h:1026
bool operator<=(const Value &other) const
Definition: json_value.cpp:549
__int64 Int64
Definition: config.h:100
virtual void destructMap(ValueInternalMap *map)=0
static void releaseStringValue(char *value)
Free the string duplicated by duplicateStringValue().
Definition: json_value.cpp:107
ValueType
Type of the value held by a Value object.
Definition: value.h:37
Value get(ArrayIndex index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
Definition: json_value.cpp:993
bool isArray() const
bool value
Definition: value.h:43
signed integer value
Definition: value.h:39
size_t getOffsetStart() const
int Int
Definition: config.h:91
UTF-8 string value.
Definition: value.h:42
const_iterator begin() const
bool isNumeric() const
bool operator!=(const Value &other) const
Definition: json_value.cpp:595
bool isInt64() const
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
Definition: value.h:140
const_iterator end() const
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.
Definition: value.h:142