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