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