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