JsonCpp project page Classes Namespace JsonCpp home page

json_value.cpp
Go to the documentation of this file.
1 // Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 
6 #if !defined(JSON_IS_AMALGAMATION)
7 #include <json/assertions.h>
8 #include <json/value.h>
9 #include <json/writer.h>
10 #endif // if !defined(JSON_IS_AMALGAMATION)
11 #include <math.h>
12 #include <sstream>
13 #include <utility>
14 #include <cstring>
15 #include <cassert>
16 #ifdef JSON_USE_CPPTL
17 #include <cpptl/conststring.h>
18 #endif
19 #include <cstddef> // size_t
20 #include <algorithm> // min()
21 
22 #define JSON_ASSERT_UNREACHABLE assert(false)
23 
24 namespace Json {
25 
26 // This is a walkaround to avoid the static initialization of Value::null.
27 // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
28 // 8 (instead of 4) as a bit of future-proofing.
29 #if defined(__ARMEL__)
30 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
31 #else
32 #define ALIGNAS(byte_alignment)
33 #endif
34 //static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
35 //const unsigned char& kNullRef = kNull[0];
36 //const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
37 //const Value& Value::nullRef = null;
38 
39 // static
41 {
42  static Value const nullStatic;
43  return nullStatic;
44 }
45 
46 // for backwards compatibility, we'll leave these global references around, but DO NOT
47 // use them in JSONCPP library code any more!
50 
51 const Int Value::minInt = Int(~(UInt(-1) / 2));
52 const Int Value::maxInt = Int(UInt(-1) / 2);
53 const UInt Value::maxUInt = UInt(-1);
54 #if defined(JSON_HAS_INT64)
55 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
56 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
57 const UInt64 Value::maxUInt64 = UInt64(-1);
58 // The constant is hard-coded because some compiler have trouble
59 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
60 // Assumes that UInt64 is a 64 bits integer.
61 static const double maxUInt64AsDouble = 18446744073709551615.0;
62 #endif // defined(JSON_HAS_INT64)
66 
67 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
68 template <typename T, typename U>
69 static inline bool InRange(double d, T min, U max) {
70  // The casts can lose precision, but we are looking only for
71  // an approximate range. Might fail on edge cases though. ~cdunn
72  //return d >= static_cast<double>(min) && d <= static_cast<double>(max);
73  return d >= min && d <= max;
74 }
75 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
76 static inline double integerToDouble(Json::UInt64 value) {
77  return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1));
78 }
79 
80 template <typename T> static inline double integerToDouble(T value) {
81  return static_cast<double>(value);
82 }
83 
84 template <typename T, typename U>
85 static inline bool InRange(double d, T min, U max) {
86  return d >= integerToDouble(min) && d <= integerToDouble(max);
87 }
88 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
89 
97 static inline char* duplicateStringValue(const char* value,
98  size_t length)
99 {
100  // Avoid an integer overflow in the call to malloc below by limiting length
101  // to a sane value.
102  if (length >= static_cast<size_t>(Value::maxInt))
103  length = Value::maxInt - 1;
104 
105  char* newString = static_cast<char*>(malloc(length + 1));
106  if (newString == NULL) {
107  throwRuntimeError(
108  "in Json::Value::duplicateStringValue(): "
109  "Failed to allocate string value buffer");
110  }
111  memcpy(newString, value, length);
112  newString[length] = 0;
113  return newString;
114 }
115 
116 /* Record the length as a prefix.
117  */
118 static inline char* duplicateAndPrefixStringValue(
119  const char* value,
120  unsigned int length)
121 {
122  // Avoid an integer overflow in the call to malloc below by limiting length
123  // to a sane value.
124  JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U,
125  "in Json::Value::duplicateAndPrefixStringValue(): "
126  "length too big for prefixing");
127  unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
128  char* newString = static_cast<char*>(malloc(actualLength));
129  if (newString == 0) {
130  throwRuntimeError(
131  "in Json::Value::duplicateAndPrefixStringValue(): "
132  "Failed to allocate string value buffer");
133  }
134  *reinterpret_cast<unsigned*>(newString) = length;
135  memcpy(newString + sizeof(unsigned), value, length);
136  newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
137  return newString;
138 }
139 inline static void decodePrefixedString(
140  bool isPrefixed, char const* prefixed,
141  unsigned* length, char const** value)
142 {
143  if (!isPrefixed) {
144  *length = static_cast<unsigned>(strlen(prefixed));
145  *value = prefixed;
146  } else {
147  *length = *reinterpret_cast<unsigned const*>(prefixed);
148  *value = prefixed + sizeof(unsigned);
149  }
150 }
153 #if JSONCPP_USING_SECURE_MEMORY
154 static inline void releasePrefixedStringValue(char* value) {
155  unsigned length = 0;
156  char const* valueDecoded;
157  decodePrefixedString(true, value, &length, &valueDecoded);
158  size_t const size = sizeof(unsigned) + length + 1U;
159  memset(value, 0, size);
160  free(value);
161 }
162 static inline void releaseStringValue(char* value, unsigned length) {
163  // length==0 => we allocated the strings memory
164  size_t size = (length==0) ? strlen(value) : length;
165  memset(value, 0, size);
166  free(value);
167 }
168 #else // !JSONCPP_USING_SECURE_MEMORY
169 static inline void releasePrefixedStringValue(char* value) {
170  free(value);
171 }
172 static inline void releaseStringValue(char* value, unsigned) {
173  free(value);
174 }
175 #endif // JSONCPP_USING_SECURE_MEMORY
176 
177 } // namespace Json
178 
179 // //////////////////////////////////////////////////////////////////
180 // //////////////////////////////////////////////////////////////////
181 // //////////////////////////////////////////////////////////////////
182 // ValueInternals...
183 // //////////////////////////////////////////////////////////////////
184 // //////////////////////////////////////////////////////////////////
185 // //////////////////////////////////////////////////////////////////
186 #if !defined(JSON_IS_AMALGAMATION)
187 
188 #include "json_valueiterator.inl"
189 #endif // if !defined(JSON_IS_AMALGAMATION)
190 
191 namespace Json {
192 
194  : msg_(msg)
195 {}
197 {}
199 {
200  return msg_.c_str();
201 }
203  : Exception(msg)
204 {}
206  : Exception(msg)
207 {}
208 JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
209 {
210  throw RuntimeError(msg);
211 }
212 JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
213 {
214  throw LogicError(msg);
215 }
216 
217 // //////////////////////////////////////////////////////////////////
218 // //////////////////////////////////////////////////////////////////
219 // //////////////////////////////////////////////////////////////////
220 // class Value::CommentInfo
221 // //////////////////////////////////////////////////////////////////
222 // //////////////////////////////////////////////////////////////////
223 // //////////////////////////////////////////////////////////////////
224 
225 Value::CommentInfo::CommentInfo() : comment_(0)
226 {}
227 
228 Value::CommentInfo::~CommentInfo() {
229  if (comment_)
230  releaseStringValue(comment_, 0u);
231 }
232 
233 void Value::CommentInfo::setComment(const char* text, size_t len) {
234  if (comment_) {
235  releaseStringValue(comment_, 0u);
236  comment_ = 0;
237  }
238  JSON_ASSERT(text != 0);
240  text[0] == '\0' || text[0] == '/',
241  "in Json::Value::setComment(): Comments must start with /");
242  // It seems that /**/ style comments are acceptable as well.
243  comment_ = duplicateStringValue(text, len);
244 }
245 
246 // //////////////////////////////////////////////////////////////////
247 // //////////////////////////////////////////////////////////////////
248 // //////////////////////////////////////////////////////////////////
249 // class Value::CZString
250 // //////////////////////////////////////////////////////////////////
251 // //////////////////////////////////////////////////////////////////
252 // //////////////////////////////////////////////////////////////////
253 
254 // Notes: policy_ indicates if the string was allocated when
255 // a string is stored.
256 
257 Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
258 
259 Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
260  : cstr_(str) {
261  // allocate != duplicate
262  storage_.policy_ = allocate & 0x3;
263  storage_.length_ = ulength & 0x3FFFFFFF;
264 }
265 
266 Value::CZString::CZString(const CZString& other) {
267  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
268  ? duplicateStringValue(other.cstr_, other.storage_.length_)
269  : other.cstr_);
270  storage_.policy_ = static_cast<unsigned>(other.cstr_
271  ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
272  ? noDuplication : duplicate)
273  : static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U;
274  storage_.length_ = other.storage_.length_;
275 }
276 
277 #if JSON_HAS_RVALUE_REFERENCES
278 Value::CZString::CZString(CZString&& other)
279  : cstr_(other.cstr_), index_(other.index_) {
280  other.cstr_ = nullptr;
281 }
282 #endif
283 
284 Value::CZString::~CZString() {
285  if (cstr_ && storage_.policy_ == duplicate) {
286  releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary
287  }
288 }
289 
290 void Value::CZString::swap(CZString& other) {
291  std::swap(cstr_, other.cstr_);
292  std::swap(index_, other.index_);
293 }
294 
295 Value::CZString& Value::CZString::operator=(const CZString& other) {
296  cstr_ = other.cstr_;
297  index_ = other.index_;
298  return *this;
299 }
300 
301 #if JSON_HAS_RVALUE_REFERENCES
302 Value::CZString& Value::CZString::operator=(CZString&& other) {
303  cstr_ = other.cstr_;
304  index_ = other.index_;
305  other.cstr_ = nullptr;
306  return *this;
307 }
308 #endif
309 
310 bool Value::CZString::operator<(const CZString& other) const {
311  if (!cstr_) return index_ < other.index_;
312  //return strcmp(cstr_, other.cstr_) < 0;
313  // Assume both are strings.
314  unsigned this_len = this->storage_.length_;
315  unsigned other_len = other.storage_.length_;
316  unsigned min_len = std::min<unsigned>(this_len, other_len);
317  JSON_ASSERT(this->cstr_ && other.cstr_);
318  int comp = memcmp(this->cstr_, other.cstr_, min_len);
319  if (comp < 0) return true;
320  if (comp > 0) return false;
321  return (this_len < other_len);
322 }
323 
324 bool Value::CZString::operator==(const CZString& other) const {
325  if (!cstr_) return index_ == other.index_;
326  //return strcmp(cstr_, other.cstr_) == 0;
327  // Assume both are strings.
328  unsigned this_len = this->storage_.length_;
329  unsigned other_len = other.storage_.length_;
330  if (this_len != other_len) return false;
331  JSON_ASSERT(this->cstr_ && other.cstr_);
332  int comp = memcmp(this->cstr_, other.cstr_, this_len);
333  return comp == 0;
334 }
335 
336 ArrayIndex Value::CZString::index() const { return index_; }
337 
338 //const char* Value::CZString::c_str() const { return cstr_; }
339 const char* Value::CZString::data() const { return cstr_; }
340 unsigned Value::CZString::length() const { return storage_.length_; }
341 bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
342 
343 // //////////////////////////////////////////////////////////////////
344 // //////////////////////////////////////////////////////////////////
345 // //////////////////////////////////////////////////////////////////
346 // class Value::Value
347 // //////////////////////////////////////////////////////////////////
348 // //////////////////////////////////////////////////////////////////
349 // //////////////////////////////////////////////////////////////////
350 
355 Value::Value(ValueType vtype) {
356  static char const emptyString[] = "";
357  initBasic(vtype);
358  switch (vtype) {
359  case nullValue:
360  break;
361  case intValue:
362  case uintValue:
363  value_.int_ = 0;
364  break;
365  case realValue:
366  value_.real_ = 0.0;
367  break;
368  case stringValue:
369  // allocated_ == false, so this is safe.
370  value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
371  break;
372  case arrayValue:
373  case objectValue:
374  value_.map_ = new ObjectValues();
375  break;
376  case booleanValue:
377  value_.bool_ = false;
378  break;
379  default:
381  }
382 }
383 
384 Value::Value(Int value) {
385  initBasic(intValue);
386  value_.int_ = value;
387 }
388 
389 Value::Value(UInt value) {
390  initBasic(uintValue);
391  value_.uint_ = value;
392 }
393 #if defined(JSON_HAS_INT64)
394 Value::Value(Int64 value) {
395  initBasic(intValue);
396  value_.int_ = value;
397 }
398 Value::Value(UInt64 value) {
399  initBasic(uintValue);
400  value_.uint_ = value;
401 }
402 #endif // defined(JSON_HAS_INT64)
403 
404 Value::Value(double value) {
405  initBasic(realValue);
406  value_.real_ = value;
407 }
408 
409 Value::Value(const char* value) {
410  initBasic(stringValue, true);
411  JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
412  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
413 }
414 
415 Value::Value(const char* beginValue, const char* endValue) {
416  initBasic(stringValue, true);
417  value_.string_ =
418  duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
419 }
420 
421 Value::Value(const JSONCPP_STRING& value) {
422  initBasic(stringValue, true);
423  value_.string_ =
424  duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
425 }
426 
427 Value::Value(const StaticString& value) {
428  initBasic(stringValue);
429  value_.string_ = const_cast<char*>(value.c_str());
430 }
431 
432 #ifdef JSON_USE_CPPTL
433 Value::Value(const CppTL::ConstString& value) {
434  initBasic(stringValue, true);
435  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
436 }
437 #endif
438 
439 Value::Value(bool value) {
440  initBasic(booleanValue);
441  value_.bool_ = value;
442 }
443 
444 Value::Value(Value const& other)
445  : type_(other.type_), allocated_(false)
446  ,
447  comments_(0), start_(other.start_), limit_(other.limit_)
448 {
449  switch (type_) {
450  case nullValue:
451  case intValue:
452  case uintValue:
453  case realValue:
454  case booleanValue:
455  value_ = other.value_;
456  break;
457  case stringValue:
458  if (other.value_.string_ && other.allocated_) {
459  unsigned len;
460  char const* str;
461  decodePrefixedString(other.allocated_, other.value_.string_,
462  &len, &str);
463  value_.string_ = duplicateAndPrefixStringValue(str, len);
464  allocated_ = true;
465  } else {
466  value_.string_ = other.value_.string_;
467  allocated_ = false;
468  }
469  break;
470  case arrayValue:
471  case objectValue:
472  value_.map_ = new ObjectValues(*other.value_.map_);
473  break;
474  default:
476  }
477  if (other.comments_) {
478  comments_ = new CommentInfo[numberOfCommentPlacement];
479  for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
480  const CommentInfo& otherComment = other.comments_[comment];
481  if (otherComment.comment_)
482  comments_[comment].setComment(
483  otherComment.comment_, strlen(otherComment.comment_));
484  }
485  }
486 }
487 
488 #if JSON_HAS_RVALUE_REFERENCES
489 // Move constructor
490 Value::Value(Value&& other) {
491  initBasic(nullValue);
492  swap(other);
493 }
494 #endif
495 
497  switch (type_) {
498  case nullValue:
499  case intValue:
500  case uintValue:
501  case realValue:
502  case booleanValue:
503  break;
504  case stringValue:
505  if (allocated_)
506  releasePrefixedStringValue(value_.string_);
507  break;
508  case arrayValue:
509  case objectValue:
510  delete value_.map_;
511  break;
512  default:
514  }
515 
516  delete[] comments_;
517 
518  value_.uint_ = 0;
519 }
520 
522  swap(other);
523  return *this;
524 }
525 
526 void Value::swapPayload(Value& other) {
527  ValueType temp = type_;
528  type_ = other.type_;
529  other.type_ = temp;
530  std::swap(value_, other.value_);
531  int temp2 = allocated_;
532  allocated_ = other.allocated_;
533  other.allocated_ = temp2 & 0x1;
534 }
535 
536 void Value::copyPayload(const Value& other) {
537  type_ = other.type_;
538  value_ = other.value_;
539  allocated_ = other.allocated_;
540 }
541 
542 void Value::swap(Value& other) {
543  swapPayload(other);
544  std::swap(comments_, other.comments_);
545  std::swap(start_, other.start_);
546  std::swap(limit_, other.limit_);
547 }
548 
549 void Value::copy(const Value& other) {
550  copyPayload(other);
551  comments_ = other.comments_;
552  start_ = other.start_;
553  limit_ = other.limit_;
554 }
555 
556 ValueType Value::type() const { return type_; }
557 
558 int Value::compare(const Value& other) const {
559  if (*this < other)
560  return -1;
561  if (*this > other)
562  return 1;
563  return 0;
564 }
565 
566 bool Value::operator<(const Value& other) const {
567  int typeDelta = type_ - other.type_;
568  if (typeDelta)
569  return typeDelta < 0 ? true : false;
570  switch (type_) {
571  case nullValue:
572  return false;
573  case intValue:
574  return value_.int_ < other.value_.int_;
575  case uintValue:
576  return value_.uint_ < other.value_.uint_;
577  case realValue:
578  return value_.real_ < other.value_.real_;
579  case booleanValue:
580  return value_.bool_ < other.value_.bool_;
581  case stringValue:
582  {
583  if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
584  if (other.value_.string_) return true;
585  else return false;
586  }
587  unsigned this_len;
588  unsigned other_len;
589  char const* this_str;
590  char const* other_str;
591  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
592  decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
593  unsigned min_len = std::min<unsigned>(this_len, other_len);
594  JSON_ASSERT(this_str && other_str);
595  int comp = memcmp(this_str, other_str, min_len);
596  if (comp < 0) return true;
597  if (comp > 0) return false;
598  return (this_len < other_len);
599  }
600  case arrayValue:
601  case objectValue: {
602  int delta = int(value_.map_->size() - other.value_.map_->size());
603  if (delta)
604  return delta < 0;
605  return (*value_.map_) < (*other.value_.map_);
606  }
607  default:
609  }
610  return false; // unreachable
611 }
612 
613 bool Value::operator<=(const Value& other) const { return !(other < *this); }
614 
615 bool Value::operator>=(const Value& other) const { return !(*this < other); }
616 
617 bool Value::operator>(const Value& other) const { return other < *this; }
618 
619 bool Value::operator==(const Value& other) const {
620  // if ( type_ != other.type_ )
621  // GCC 2.95.3 says:
622  // attempt to take address of bit-field structure member `Json::Value::type_'
623  // Beats me, but a temp solves the problem.
624  int temp = other.type_;
625  if (type_ != temp)
626  return false;
627  switch (type_) {
628  case nullValue:
629  return true;
630  case intValue:
631  return value_.int_ == other.value_.int_;
632  case uintValue:
633  return value_.uint_ == other.value_.uint_;
634  case realValue:
635  return value_.real_ == other.value_.real_;
636  case booleanValue:
637  return value_.bool_ == other.value_.bool_;
638  case stringValue:
639  {
640  if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
641  return (value_.string_ == other.value_.string_);
642  }
643  unsigned this_len;
644  unsigned other_len;
645  char const* this_str;
646  char const* other_str;
647  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
648  decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
649  if (this_len != other_len) return false;
650  JSON_ASSERT(this_str && other_str);
651  int comp = memcmp(this_str, other_str, this_len);
652  return comp == 0;
653  }
654  case arrayValue:
655  case objectValue:
656  return value_.map_->size() == other.value_.map_->size() &&
657  (*value_.map_) == (*other.value_.map_);
658  default:
660  }
661  return false; // unreachable
662 }
663 
664 bool Value::operator!=(const Value& other) const { return !(*this == other); }
665 
666 const char* Value::asCString() const {
668  "in Json::Value::asCString(): requires stringValue");
669  if (value_.string_ == 0) return 0;
670  unsigned this_len;
671  char const* this_str;
672  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
673  return this_str;
674 }
675 
676 #if JSONCPP_USING_SECURE_MEMORY
677 unsigned Value::getCStringLength() const {
679  "in Json::Value::asCString(): requires stringValue");
680  if (value_.string_ == 0) return 0;
681  unsigned this_len;
682  char const* this_str;
683  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
684  return this_len;
685 }
686 #endif
687 
688 bool Value::getString(char const** str, char const** cend) const {
689  if (type_ != stringValue) return false;
690  if (value_.string_ == 0) return false;
691  unsigned length;
692  decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
693  *cend = *str + length;
694  return true;
695 }
696 
698  switch (type_) {
699  case nullValue:
700  return "";
701  case stringValue:
702  {
703  if (value_.string_ == 0) return "";
704  unsigned this_len;
705  char const* this_str;
706  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
707  return JSONCPP_STRING(this_str, this_len);
708  }
709  case booleanValue:
710  return value_.bool_ ? "true" : "false";
711  case intValue:
712  return valueToString(value_.int_);
713  case uintValue:
714  return valueToString(value_.uint_);
715  case realValue:
716  return valueToString(value_.real_);
717  default:
718  JSON_FAIL_MESSAGE("Type is not convertible to string");
719  }
720 }
721 
722 #ifdef JSON_USE_CPPTL
723 CppTL::ConstString Value::asConstString() const {
724  unsigned len;
725  char const* str;
726  decodePrefixedString(allocated_, value_.string_,
727  &len, &str);
728  return CppTL::ConstString(str, len);
729 }
730 #endif
731 
733  switch (type_) {
734  case intValue:
735  JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
736  return Int(value_.int_);
737  case uintValue:
738  JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
739  return Int(value_.uint_);
740  case realValue:
741  JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
742  "double out of Int range");
743  return Int(value_.real_);
744  case nullValue:
745  return 0;
746  case booleanValue:
747  return value_.bool_ ? 1 : 0;
748  default:
749  break;
750  }
751  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
752 }
753 
755  switch (type_) {
756  case intValue:
757  JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
758  return UInt(value_.int_);
759  case uintValue:
760  JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
761  return UInt(value_.uint_);
762  case realValue:
763  JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
764  "double out of UInt range");
765  return UInt(value_.real_);
766  case nullValue:
767  return 0;
768  case booleanValue:
769  return value_.bool_ ? 1 : 0;
770  default:
771  break;
772  }
773  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
774 }
775 
776 #if defined(JSON_HAS_INT64)
777 
779  switch (type_) {
780  case intValue:
781  return Int64(value_.int_);
782  case uintValue:
783  JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
784  return Int64(value_.uint_);
785  case realValue:
787  "double out of Int64 range");
788  return Int64(value_.real_);
789  case nullValue:
790  return 0;
791  case booleanValue:
792  return value_.bool_ ? 1 : 0;
793  default:
794  break;
795  }
796  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
797 }
798 
800  switch (type_) {
801  case intValue:
802  JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
803  return UInt64(value_.int_);
804  case uintValue:
805  return UInt64(value_.uint_);
806  case realValue:
807  JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
808  "double out of UInt64 range");
809  return UInt64(value_.real_);
810  case nullValue:
811  return 0;
812  case booleanValue:
813  return value_.bool_ ? 1 : 0;
814  default:
815  break;
816  }
817  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
818 }
819 #endif // if defined(JSON_HAS_INT64)
820 
822 #if defined(JSON_NO_INT64)
823  return asInt();
824 #else
825  return asInt64();
826 #endif
827 }
828 
830 #if defined(JSON_NO_INT64)
831  return asUInt();
832 #else
833  return asUInt64();
834 #endif
835 }
836 
837 double Value::asDouble() const {
838  switch (type_) {
839  case intValue:
840  return static_cast<double>(value_.int_);
841  case uintValue:
842 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
843  return static_cast<double>(value_.uint_);
844 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
845  return integerToDouble(value_.uint_);
846 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
847  case realValue:
848  return value_.real_;
849  case nullValue:
850  return 0.0;
851  case booleanValue:
852  return value_.bool_ ? 1.0 : 0.0;
853  default:
854  break;
855  }
856  JSON_FAIL_MESSAGE("Value is not convertible to double.");
857 }
858 
859 float Value::asFloat() const {
860  switch (type_) {
861  case intValue:
862  return static_cast<float>(value_.int_);
863  case uintValue:
864 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
865  return static_cast<float>(value_.uint_);
866 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
867  // This can fail (silently?) if the value is bigger than MAX_FLOAT.
868  return static_cast<float>(integerToDouble(value_.uint_));
869 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
870  case realValue:
871  return static_cast<float>(value_.real_);
872  case nullValue:
873  return 0.0;
874  case booleanValue:
875  return value_.bool_ ? 1.0f : 0.0f;
876  default:
877  break;
878  }
879  JSON_FAIL_MESSAGE("Value is not convertible to float.");
880 }
881 
882 bool Value::asBool() const {
883  switch (type_) {
884  case booleanValue:
885  return value_.bool_;
886  case nullValue:
887  return false;
888  case intValue:
889  return value_.int_ ? true : false;
890  case uintValue:
891  return value_.uint_ ? true : false;
892  case realValue:
893  // This is kind of strange. Not recommended.
894  return (value_.real_ != 0.0) ? true : false;
895  default:
896  break;
897  }
898  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
899 }
900 
902  switch (other) {
903  case nullValue:
904  return (isNumeric() && asDouble() == 0.0) ||
905  (type_ == booleanValue && value_.bool_ == false) ||
906  (type_ == stringValue && asString().empty()) ||
907  (type_ == arrayValue && value_.map_->size() == 0) ||
908  (type_ == objectValue && value_.map_->size() == 0) ||
909  type_ == nullValue;
910  case intValue:
911  return isInt() ||
912  (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
913  type_ == booleanValue || type_ == nullValue;
914  case uintValue:
915  return isUInt() ||
916  (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
917  type_ == booleanValue || type_ == nullValue;
918  case realValue:
919  return isNumeric() || type_ == booleanValue || type_ == nullValue;
920  case booleanValue:
921  return isNumeric() || type_ == booleanValue || type_ == nullValue;
922  case stringValue:
923  return isNumeric() || type_ == booleanValue || type_ == stringValue ||
924  type_ == nullValue;
925  case arrayValue:
926  return type_ == arrayValue || type_ == nullValue;
927  case objectValue:
928  return type_ == objectValue || type_ == nullValue;
929  }
931  return false;
932 }
933 
936  switch (type_) {
937  case nullValue:
938  case intValue:
939  case uintValue:
940  case realValue:
941  case booleanValue:
942  case stringValue:
943  return 0;
944  case arrayValue: // size of the array is highest index + 1
945  if (!value_.map_->empty()) {
946  ObjectValues::const_iterator itLast = value_.map_->end();
947  --itLast;
948  return (*itLast).first.index() + 1;
949  }
950  return 0;
951  case objectValue:
952  return ArrayIndex(value_.map_->size());
953  }
955  return 0; // unreachable;
956 }
957 
958 bool Value::empty() const {
959  if (isNull() || isArray() || isObject())
960  return size() == 0u;
961  else
962  return false;
963 }
964 
965 Value::operator bool() const { return ! isNull(); }
966 
967 void Value::clear() {
968  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
969  type_ == objectValue,
970  "in Json::Value::clear(): requires complex value");
971  start_ = 0;
972  limit_ = 0;
973  switch (type_) {
974  case arrayValue:
975  case objectValue:
976  value_.map_->clear();
977  break;
978  default:
979  break;
980  }
981 }
982 
983 void Value::resize(ArrayIndex newSize) {
984  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
985  "in Json::Value::resize(): requires arrayValue");
986  if (type_ == nullValue)
987  *this = Value(arrayValue);
988  ArrayIndex oldSize = size();
989  if (newSize == 0)
990  clear();
991  else if (newSize > oldSize)
992  (*this)[newSize - 1];
993  else {
994  for (ArrayIndex index = newSize; index < oldSize; ++index) {
995  value_.map_->erase(index);
996  }
997  JSON_ASSERT(size() == newSize);
998  }
999 }
1000 
1003  type_ == nullValue || type_ == arrayValue,
1004  "in Json::Value::operator[](ArrayIndex): requires arrayValue");
1005  if (type_ == nullValue)
1006  *this = Value(arrayValue);
1007  CZString key(index);
1008  ObjectValues::iterator it = value_.map_->lower_bound(key);
1009  if (it != value_.map_->end() && (*it).first == key)
1010  return (*it).second;
1011 
1012  ObjectValues::value_type defaultValue(key, nullSingleton());
1013  it = value_.map_->insert(it, defaultValue);
1014  return (*it).second;
1015 }
1016 
1019  index >= 0,
1020  "in Json::Value::operator[](int index): index cannot be negative");
1021  return (*this)[ArrayIndex(index)];
1022 }
1023 
1024 const Value& Value::operator[](ArrayIndex index) const {
1026  type_ == nullValue || type_ == arrayValue,
1027  "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
1028  if (type_ == nullValue)
1029  return nullSingleton();
1030  CZString key(index);
1031  ObjectValues::const_iterator it = value_.map_->find(key);
1032  if (it == value_.map_->end())
1033  return nullSingleton();
1034  return (*it).second;
1035 }
1036 
1037 const Value& Value::operator[](int index) const {
1039  index >= 0,
1040  "in Json::Value::operator[](int index) const: index cannot be negative");
1041  return (*this)[ArrayIndex(index)];
1042 }
1043 
1044 void Value::initBasic(ValueType vtype, bool allocated) {
1045  type_ = vtype;
1046  allocated_ = allocated;
1047  comments_ = 0;
1048  start_ = 0;
1049  limit_ = 0;
1050 }
1051 
1052 // Access an object value by name, create a null member if it does not exist.
1053 // @pre Type of '*this' is object or null.
1054 // @param key is null-terminated.
1055 Value& Value::resolveReference(const char* key) {
1057  type_ == nullValue || type_ == objectValue,
1058  "in Json::Value::resolveReference(): requires objectValue");
1059  if (type_ == nullValue)
1060  *this = Value(objectValue);
1061  CZString actualKey(
1062  key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
1063  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
1064  if (it != value_.map_->end() && (*it).first == actualKey)
1065  return (*it).second;
1066 
1067  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1068  it = value_.map_->insert(it, defaultValue);
1069  Value& value = (*it).second;
1070  return value;
1071 }
1072 
1073 // @param key is not null-terminated.
1074 Value& Value::resolveReference(char const* key, char const* cend)
1075 {
1077  type_ == nullValue || type_ == objectValue,
1078  "in Json::Value::resolveReference(key, end): requires objectValue");
1079  if (type_ == nullValue)
1080  *this = Value(objectValue);
1081  CZString actualKey(
1082  key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
1083  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
1084  if (it != value_.map_->end() && (*it).first == actualKey)
1085  return (*it).second;
1086 
1087  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1088  it = value_.map_->insert(it, defaultValue);
1089  Value& value = (*it).second;
1090  return value;
1091 }
1092 
1093 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
1094  const Value* value = &((*this)[index]);
1095  return value == &nullSingleton() ? defaultValue : *value;
1096 }
1097 
1098 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
1099 
1100 Value const* Value::find(char const* key, char const* cend) const
1101 {
1103  type_ == nullValue || type_ == objectValue,
1104  "in Json::Value::find(key, end, found): requires objectValue or nullValue");
1105  if (type_ == nullValue) return NULL;
1106  CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1107  ObjectValues::const_iterator it = value_.map_->find(actualKey);
1108  if (it == value_.map_->end()) return NULL;
1109  return &(*it).second;
1110 }
1111 const Value& Value::operator[](const char* key) const
1112 {
1113  Value const* found = find(key, key + strlen(key));
1114  if (!found) return nullSingleton();
1115  return *found;
1116 }
1117 Value const& Value::operator[](JSONCPP_STRING const& key) const
1118 {
1119  Value const* found = find(key.data(), key.data() + key.length());
1120  if (!found) return nullSingleton();
1121  return *found;
1122 }
1123 
1124 Value& Value::operator[](const char* key) {
1125  return resolveReference(key, key + strlen(key));
1126 }
1127 
1129  return resolveReference(key.data(), key.data() + key.length());
1130 }
1131 
1133  return resolveReference(key.c_str());
1134 }
1135 
1136 #ifdef JSON_USE_CPPTL
1137 Value& Value::operator[](const CppTL::ConstString& key) {
1138  return resolveReference(key.c_str(), key.end_c_str());
1139 }
1140 Value const& Value::operator[](CppTL::ConstString const& key) const
1141 {
1142  Value const* found = find(key.c_str(), key.end_c_str());
1143  if (!found) return nullSingleton();
1144  return *found;
1145 }
1146 #endif
1147 
1148 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
1149 
1150 #if JSON_HAS_RVALUE_REFERENCES
1151  Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); }
1152 #endif
1153 
1154 Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
1155 {
1156  Value const* found = find(key, cend);
1157  return !found ? defaultValue : *found;
1158 }
1159 Value Value::get(char const* key, Value const& defaultValue) const
1160 {
1161  return get(key, key + strlen(key), defaultValue);
1162 }
1163 Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const
1164 {
1165  return get(key.data(), key.data() + key.length(), defaultValue);
1166 }
1167 
1168 
1169 bool Value::removeMember(const char* key, const char* cend, Value* removed)
1170 {
1171  if (type_ != objectValue) {
1172  return false;
1173  }
1174  CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1175  ObjectValues::iterator it = value_.map_->find(actualKey);
1176  if (it == value_.map_->end())
1177  return false;
1178  *removed = it->second;
1179  value_.map_->erase(it);
1180  return true;
1181 }
1182 bool Value::removeMember(const char* key, Value* removed)
1183 {
1184  return removeMember(key, key + strlen(key), removed);
1185 }
1186 bool Value::removeMember(JSONCPP_STRING const& key, Value* removed)
1187 {
1188  return removeMember(key.data(), key.data() + key.length(), removed);
1189 }
1190 void Value::removeMember(const char* key)
1191 {
1192  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
1193  "in Json::Value::removeMember(): requires objectValue");
1194  if (type_ == nullValue)
1195  return;
1196 
1197  CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
1198  value_.map_->erase(actualKey);
1199 }
1201 {
1202  removeMember(key.c_str());
1203 }
1204 
1205 bool Value::removeIndex(ArrayIndex index, Value* removed) {
1206  if (type_ != arrayValue) {
1207  return false;
1208  }
1209  CZString key(index);
1210  ObjectValues::iterator it = value_.map_->find(key);
1211  if (it == value_.map_->end()) {
1212  return false;
1213  }
1214  *removed = it->second;
1215  ArrayIndex oldSize = size();
1216  // shift left all items left, into the place of the "removed"
1217  for (ArrayIndex i = index; i < (oldSize - 1); ++i){
1218  CZString keey(i);
1219  (*value_.map_)[keey] = (*this)[i + 1];
1220  }
1221  // erase the last one ("leftover")
1222  CZString keyLast(oldSize - 1);
1223  ObjectValues::iterator itLast = value_.map_->find(keyLast);
1224  value_.map_->erase(itLast);
1225  return true;
1226 }
1227 
1228 #ifdef JSON_USE_CPPTL
1229 Value Value::get(const CppTL::ConstString& key,
1230  const Value& defaultValue) const {
1231  return get(key.c_str(), key.end_c_str(), defaultValue);
1232 }
1233 #endif
1234 
1235 bool Value::isMember(char const* key, char const* cend) const
1236 {
1237  Value const* value = find(key, cend);
1238  return NULL != value;
1239 }
1240 bool Value::isMember(char const* key) const
1241 {
1242  return isMember(key, key + strlen(key));
1243 }
1244 bool Value::isMember(JSONCPP_STRING const& key) const
1245 {
1246  return isMember(key.data(), key.data() + key.length());
1247 }
1248 
1249 #ifdef JSON_USE_CPPTL
1250 bool Value::isMember(const CppTL::ConstString& key) const {
1251  return isMember(key.c_str(), key.end_c_str());
1252 }
1253 #endif
1254 
1257  type_ == nullValue || type_ == objectValue,
1258  "in Json::Value::getMemberNames(), value must be objectValue");
1259  if (type_ == nullValue)
1260  return Value::Members();
1261  Members members;
1262  members.reserve(value_.map_->size());
1263  ObjectValues::const_iterator it = value_.map_->begin();
1264  ObjectValues::const_iterator itEnd = value_.map_->end();
1265  for (; it != itEnd; ++it) {
1266  members.push_back(JSONCPP_STRING((*it).first.data(),
1267  (*it).first.length()));
1268  }
1269  return members;
1270 }
1271 //
1272 //# ifdef JSON_USE_CPPTL
1273 // EnumMemberNames
1274 // Value::enumMemberNames() const
1275 //{
1276 // if ( type_ == objectValue )
1277 // {
1278 // return CppTL::Enum::any( CppTL::Enum::transform(
1279 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
1280 // MemberNamesTransform() ) );
1281 // }
1282 // return EnumMemberNames();
1283 //}
1284 //
1285 //
1286 // EnumValues
1287 // Value::enumValues() const
1288 //{
1289 // if ( type_ == objectValue || type_ == arrayValue )
1290 // return CppTL::Enum::anyValues( *(value_.map_),
1291 // CppTL::Type<const Value &>() );
1292 // return EnumValues();
1293 //}
1294 //
1295 //# endif
1296 
1297 static bool IsIntegral(double d) {
1298  double integral_part;
1299  return modf(d, &integral_part) == 0.0;
1300 }
1301 
1302 bool Value::isNull() const { return type_ == nullValue; }
1303 
1304 bool Value::isBool() const { return type_ == booleanValue; }
1305 
1306 bool Value::isInt() const {
1307  switch (type_) {
1308  case intValue:
1309 #if defined(JSON_HAS_INT64)
1310  return value_.int_ >= minInt && value_.int_ <= maxInt;
1311 #else
1312  return true;
1313 #endif
1314  case uintValue:
1315  return value_.uint_ <= UInt(maxInt);
1316  case realValue:
1317  return value_.real_ >= minInt && value_.real_ <= maxInt &&
1318  IsIntegral(value_.real_);
1319  default:
1320  break;
1321  }
1322  return false;
1323 }
1324 
1325 bool Value::isUInt() const {
1326  switch (type_) {
1327  case intValue:
1328 #if defined(JSON_HAS_INT64)
1329  return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
1330 #else
1331  return value_.int_ >= 0;
1332 #endif
1333  case uintValue:
1334 #if defined(JSON_HAS_INT64)
1335  return value_.uint_ <= maxUInt;
1336 #else
1337  return true;
1338 #endif
1339  case realValue:
1340  return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1341  IsIntegral(value_.real_);
1342  default:
1343  break;
1344  }
1345  return false;
1346 }
1347 
1348 bool Value::isInt64() const {
1349 #if defined(JSON_HAS_INT64)
1350  switch (type_) {
1351  case intValue:
1352  return true;
1353  case uintValue:
1354  return value_.uint_ <= UInt64(maxInt64);
1355  case realValue:
1356  // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1357  // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1358  // require the value to be strictly less than the limit.
1359  return value_.real_ >= double(minInt64) &&
1360  value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
1361  default:
1362  break;
1363  }
1364 #endif // JSON_HAS_INT64
1365  return false;
1366 }
1367 
1368 bool Value::isUInt64() const {
1369 #if defined(JSON_HAS_INT64)
1370  switch (type_) {
1371  case intValue:
1372  return value_.int_ >= 0;
1373  case uintValue:
1374  return true;
1375  case realValue:
1376  // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1377  // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1378  // require the value to be strictly less than the limit.
1379  return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1380  IsIntegral(value_.real_);
1381  default:
1382  break;
1383  }
1384 #endif // JSON_HAS_INT64
1385  return false;
1386 }
1387 
1388 bool Value::isIntegral() const {
1389  switch (type_) {
1390  case intValue:
1391  case uintValue:
1392  return true;
1393  case realValue:
1394 #if defined(JSON_HAS_INT64)
1395  // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1396  // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1397  // require the value to be strictly less than the limit.
1398  return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
1399 #else
1400  return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_);
1401 #endif // JSON_HAS_INT64
1402  default:
1403  break;
1404  }
1405  return false;
1406 }
1407 
1408 bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }
1409 
1410 bool Value::isNumeric() const { return isDouble(); }
1411 
1412 bool Value::isString() const { return type_ == stringValue; }
1413 
1414 bool Value::isArray() const { return type_ == arrayValue; }
1415 
1416 bool Value::isObject() const { return type_ == objectValue; }
1417 
1418 void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
1419  if (!comments_)
1420  comments_ = new CommentInfo[numberOfCommentPlacement];
1421  if ((len > 0) && (comment[len-1] == '\n')) {
1422  // Always discard trailing newline, to aid indentation.
1423  len -= 1;
1424  }
1425  comments_[placement].setComment(comment, len);
1426 }
1427 
1428 void Value::setComment(const char* comment, CommentPlacement placement) {
1429  setComment(comment, strlen(comment), placement);
1430 }
1431 
1432 void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) {
1433  setComment(comment.c_str(), comment.length(), placement);
1434 }
1435 
1436 bool Value::hasComment(CommentPlacement placement) const {
1437  return comments_ != 0 && comments_[placement].comment_ != 0;
1438 }
1439 
1441  if (hasComment(placement))
1442  return comments_[placement].comment_;
1443  return "";
1444 }
1445 
1446 void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
1447 
1448 void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
1449 
1450 ptrdiff_t Value::getOffsetStart() const { return start_; }
1451 
1452 ptrdiff_t Value::getOffsetLimit() const { return limit_; }
1453 
1455  StreamWriterBuilder builder;
1456 
1457  JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : "";
1458  out += Json::writeString(builder, *this);
1459  out += "\n";
1460 
1461  return out;
1462 }
1463 
1465  switch (type_) {
1466  case arrayValue:
1467  case objectValue:
1468  if (value_.map_)
1469  return const_iterator(value_.map_->begin());
1470  break;
1471  default:
1472  break;
1473  }
1474  return const_iterator();
1475 }
1476 
1478  switch (type_) {
1479  case arrayValue:
1480  case objectValue:
1481  if (value_.map_)
1482  return const_iterator(value_.map_->end());
1483  break;
1484  default:
1485  break;
1486  }
1487  return const_iterator();
1488 }
1489 
1491  switch (type_) {
1492  case arrayValue:
1493  case objectValue:
1494  if (value_.map_)
1495  return iterator(value_.map_->begin());
1496  break;
1497  default:
1498  break;
1499  }
1500  return iterator();
1501 }
1502 
1504  switch (type_) {
1505  case arrayValue:
1506  case objectValue:
1507  if (value_.map_)
1508  return iterator(value_.map_->end());
1509  break;
1510  default:
1511  break;
1512  }
1513  return iterator();
1514 }
1515 
1516 // class PathArgument
1517 // //////////////////////////////////////////////////////////////////
1518 
1519 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
1520 
1522  : key_(), index_(index), kind_(kindIndex) {}
1523 
1525  : key_(key), index_(), kind_(kindKey) {}
1526 
1528  : key_(key.c_str()), index_(), kind_(kindKey) {}
1529 
1530 // class Path
1531 // //////////////////////////////////////////////////////////////////
1532 
1534  const PathArgument& a1,
1535  const PathArgument& a2,
1536  const PathArgument& a3,
1537  const PathArgument& a4,
1538  const PathArgument& a5) {
1539  InArgs in;
1540  in.reserve(5);
1541  in.push_back(&a1);
1542  in.push_back(&a2);
1543  in.push_back(&a3);
1544  in.push_back(&a4);
1545  in.push_back(&a5);
1546  makePath(path, in);
1547 }
1548 
1549 void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) {
1550  const char* current = path.c_str();
1551  const char* end = current + path.length();
1552  InArgs::const_iterator itInArg = in.begin();
1553  while (current != end) {
1554  if (*current == '[') {
1555  ++current;
1556  if (*current == '%')
1557  addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1558  else {
1559  ArrayIndex index = 0;
1560  for (; current != end && *current >= '0' && *current <= '9'; ++current)
1561  index = index * 10 + ArrayIndex(*current - '0');
1562  args_.push_back(index);
1563  }
1564  if (current == end || *++current != ']')
1565  invalidPath(path, int(current - path.c_str()));
1566  } else if (*current == '%') {
1567  addPathInArg(path, in, itInArg, PathArgument::kindKey);
1568  ++current;
1569  } else if (*current == '.' || *current == ']') {
1570  ++current;
1571  } else {
1572  const char* beginName = current;
1573  while (current != end && !strchr("[.", *current))
1574  ++current;
1575  args_.push_back(JSONCPP_STRING(beginName, current));
1576  }
1577  }
1578 }
1579 
1580 void Path::addPathInArg(const JSONCPP_STRING& /*path*/,
1581  const InArgs& in,
1582  InArgs::const_iterator& itInArg,
1583  PathArgument::Kind kind) {
1584  if (itInArg == in.end()) {
1585  // Error: missing argument %d
1586  } else if ((*itInArg)->kind_ != kind) {
1587  // Error: bad argument type
1588  } else {
1589  args_.push_back(**itInArg++);
1590  }
1591 }
1592 
1593 void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) {
1594  // Error: invalid path.
1595 }
1596 
1597 const Value& Path::resolve(const Value& root) const {
1598  const Value* node = &root;
1599  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1600  const PathArgument& arg = *it;
1601  if (arg.kind_ == PathArgument::kindIndex) {
1602  if (!node->isArray() || !node->isValidIndex(arg.index_)) {
1603  // Error: unable to resolve path (array value expected at position...
1604  return Value::null;
1605  }
1606  node = &((*node)[arg.index_]);
1607  } else if (arg.kind_ == PathArgument::kindKey) {
1608  if (!node->isObject()) {
1609  // Error: unable to resolve path (object value expected at position...)
1610  return Value::null;
1611  }
1612  node = &((*node)[arg.key_]);
1613  if (node == &Value::nullSingleton()) {
1614  // Error: unable to resolve path (object has no member named '' at
1615  // position...)
1616  return Value::null;
1617  }
1618  }
1619  }
1620  return *node;
1621 }
1622 
1623 Value Path::resolve(const Value& root, const Value& defaultValue) const {
1624  const Value* node = &root;
1625  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1626  const PathArgument& arg = *it;
1627  if (arg.kind_ == PathArgument::kindIndex) {
1628  if (!node->isArray() || !node->isValidIndex(arg.index_))
1629  return defaultValue;
1630  node = &((*node)[arg.index_]);
1631  } else if (arg.kind_ == PathArgument::kindKey) {
1632  if (!node->isObject())
1633  return defaultValue;
1634  node = &((*node)[arg.key_]);
1635  if (node == &Value::nullSingleton())
1636  return defaultValue;
1637  }
1638  }
1639  return *node;
1640 }
1641 
1642 Value& Path::make(Value& root) const {
1643  Value* node = &root;
1644  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1645  const PathArgument& arg = *it;
1646  if (arg.kind_ == PathArgument::kindIndex) {
1647  if (!node->isArray()) {
1648  // Error: node is not an array at position ...
1649  }
1650  node = &((*node)[arg.index_]);
1651  } else if (arg.kind_ == PathArgument::kindKey) {
1652  if (!node->isObject()) {
1653  // Error: node is not an object at position...
1654  }
1655  node = &((*node)[arg.key_]);
1656  }
1657  }
1658  return *node;
1659 }
1660 
1661 } // namespace Json
Path(const std::string &path, const PathArgument &a1=PathArgument(), const PathArgument &a2=PathArgument(), const PathArgument &a3=PathArgument(), const PathArgument &a4=PathArgument(), const PathArgument &a5=PathArgument())
Int64 LargestInt
Definition: config.h:168
Int64 asInt64() const
Definition: json_value.cpp:778
bool isArray() const
static bool IsIntegral(double d)
int compare(const Value &other) const
Definition: json_value.cpp:558
bool isUInt() const
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
Definition: value.h:218
unsigned int ArrayIndex
Definition: forwards.h:23
Value const * find(char const *begin, char const *end) const
Most general and efficient version of isMember()const, get()const, and operator[]const.
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
LargestUInt asLargestUInt() const
Definition: json_value.cpp:829
array value (ordered list)
Definition: value.h:100
void copy(const Value &other)
copy everything.
Definition: json_value.cpp:549
unsigned __int64 UInt64
Definition: config.h:163
bool isNumeric() const
bool asBool() const
Definition: json_value.cpp:882
#define JSON_ASSERT_MESSAGE(condition, message)
Definition: assertions.h:49
static Value const & nullSingleton()
Prefer this to null or nullRef.
Definition: json_value.cpp:40
unsigned integer value
Definition: value.h:96
#define JSONCPP_STRING
Definition: config.h:179
UInt64 asUInt64() const
Definition: json_value.cpp:799
Json::ArrayIndex ArrayIndex
Definition: value.h:191
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Definition: json_value.cpp:958
Members getMemberNames() const
Return a list of the member names.
object value (collection of name/value pairs).
Definition: value.h:101
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.
Definition: json_value.cpp:688
void swapPayload(Value &other)
Swap values but leave comments and source offsets in place.
Definition: json_value.cpp:526
RuntimeError(std::string const &msg)
Definition: json_value.cpp:202
bool removeIndex(ArrayIndex i, Value *removed)
Remove the indexed array element.
static const Int maxInt
Maximum signed int value that can be stored in a Json::Value.
Definition: value.h:210
ptrdiff_t getOffsetStart() const
static const Value & null
We regret this reference to a global instance; prefer the simpler Value().
Definition: value.h:196
Lightweight wrapper to tag static string.
Definition: value.h:131
std::string toStyledString() const
#define JSON_ASSERT(condition)
It should not be possible for a maliciously designed file to cause an abort() or seg-fault, so these macros are used only for pre-condition violations and internal logic errors.
Definition: assertions.h:23
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
Definition: value.h:212
static const Value & nullRef
just a kludge for binary-compatibility; same as null
Definition: value.h:197
Json::LargestUInt LargestUInt
Definition: value.h:190
LogicError(std::string const &msg)
Definition: json_value.cpp:205
bool isBool() const
Value & operator=(Value other)
Deep copy, then swap(other).
Definition: json_value.cpp:521
static void releaseStringValue(char *value, unsigned)
Definition: json_value.cpp:172
const iterator for object and array value.
Definition: value.h:774
bool isDouble() const
#define JSONCPP_NORETURN
Definition: value.h:30
Value(ValueType type=nullValue)
Create a default Value of the given type.
Definition: json_value.cpp:355
Experimental and untested: represents an element of the "path" to access a node.
Definition: value.h:646
void setComment(const char *comment, CommentPlacement placement)
static bool InRange(double d, T min, U max)
Definition: json_value.cpp:69
double asDouble() const
Definition: json_value.cpp:837
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
Definition: value.h:201
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
&#39;null&#39; value
Definition: value.h:94
CommentPlacement
Definition: value.h:104
#define JSONCPP_NOEXCEPT
Definition: config.h:95
static void decodePrefixedString(bool isPrefixed, char const *prefixed, unsigned *length, char const **value)
Definition: json_value.cpp:139
UInt64 LargestUInt
Definition: config.h:169
Value & operator[](ArrayIndex index)
Access an array element (zero based index ).
ArrayIndex size() const
Number of values in array or object.
Definition: json_value.cpp:935
const char * asCString() const
Embedded zeroes could cause you trouble!
Definition: json_value.cpp:666
bool operator==(const Value &other) const
Definition: json_value.cpp:619
ValueConstIterator const_iterator
Definition: value.h:182
LargestInt asLargestInt() const
Definition: json_value.cpp:821
bool operator>(const Value &other) const
Definition: json_value.cpp:617
std::string valueToString(Int value)
UInt asUInt() const
Definition: json_value.cpp:754
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
std::string msg_
Definition: value.h:61
std::string asString() const
Embedded zeroes are possible.
Definition: json_value.cpp:697
bool operator>=(const Value &other) const
Definition: json_value.cpp:615
JSON (JavaScript Object Notation).
Definition: allocator.h:14
void removeMember(const char *key)
Remove and return the named member.
bool operator==(const SecureAllocator< T > &, const SecureAllocator< U > &)
Definition: allocator.h:85
bool isInt64() const
Json::Int64 Int64
Definition: value.h:187
#define JSON_FAIL_MESSAGE(message)
Definition: assertions.h:26
float asFloat() const
Definition: json_value.cpp:859
void swap(Value &other)
Swap everything.
Definition: json_value.cpp:542
Json::LargestInt LargestInt
Definition: value.h:189
static const double maxUInt64AsDouble
Definition: json_value.cpp:61
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
Definition: value.h:220
ptrdiff_t getOffsetLimit() const
const char * c_str() const
Definition: value.h:137
double value
Definition: value.h:97
Value get(ArrayIndex index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
Int asInt() const
Definition: json_value.cpp:732
const_iterator begin() const
Exception(std::string const &msg)
Definition: json_value.cpp:193
Json::UInt UInt
Definition: value.h:183
Value & append(const Value &value)
Append value to array at the end.
Json::UInt64 UInt64
Definition: value.h:186
Json::Int Int
Definition: value.h:184
static char * duplicateAndPrefixStringValue(const char *value, unsigned int length)
Definition: json_value.cpp:118
#define JSON_ASSERT_UNREACHABLE
Definition: json_value.cpp:22
Represents a JSON value.
Definition: value.h:177
void setOffsetStart(ptrdiff_t start)
ValueIterator iterator
Definition: value.h:181
ValueType type() const
Definition: json_value.cpp:556
static char * duplicateStringValue(const char *value, size_t length)
Duplicates the specified string value.
Definition: json_value.cpp:97
static const Int64 minInt64
Minimum signed 64 bits int value that can be stored in a Json::Value.
Definition: value.h:216
static const Int minInt
Minimum signed int value that can be stored in a Json::Value.
Definition: value.h:208
Exceptions which the user cannot easily avoid.
Definition: value.h:70
bool isUInt64() const
bool isString() const
unsigned int UInt
Definition: config.h:154
bool hasComment(CommentPlacement placement) const
bool isNull() const
void resize(ArrayIndex size)
Resize the array to size elements.
Definition: json_value.cpp:983
void clear()
Remove all object members and array elements.
Definition: json_value.cpp:967
bool operator!=(const Value &other) const
Definition: json_value.cpp:664
Iterator for object and array value.
Definition: value.h:824
static void releasePrefixedStringValue(char *value)
Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
Definition: json_value.cpp:169
bool isInt() const
__int64 Int64
Definition: config.h:162
void setOffsetLimit(ptrdiff_t limit)
bool isMember(const char *key) const
Return true if the object has a member named key.
ValueType
used internally
Definition: value.h:93
std::vector< std::string > Members
Definition: value.h:180
bool operator<=(const Value &other) const
Definition: json_value.cpp:613
std::string writeString(StreamWriter::Factory const &factory, Value const &root)
Write into stringstream, then return string, for convenience.
bool value
Definition: value.h:99
const Value & resolve(const Value &root) const
bool isConvertibleTo(ValueType other) const
Definition: json_value.cpp:901
bool operator<(const Value &other) const
Compare payload only, not comments etc.
Definition: json_value.cpp:566
signed integer value
Definition: value.h:95
bool isObject() const
void copyPayload(const Value &other)
copy values but leave comments and source offsets in place.
Definition: json_value.cpp:536
int Int
Definition: config.h:153
a comment placed on the line before a value
Definition: value.h:105
UTF-8 string value.
Definition: value.h:98
char const * what() const
Definition: json_value.cpp:198
Build a StreamWriter implementation.
Definition: writer.h:89
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: value.h:879
Base class for all exceptions we throw.
Definition: value.h:55
bool isIntegral() const
const_iterator end() const
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
Definition: value.h:203
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.
Definition: value.h:205