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