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