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