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