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