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