6 #if !defined(JSON_IS_AMALGAMATION)
10 #endif // if !defined(JSON_IS_AMALGAMATION)
17 #include <cpptl/conststring.h>
23 #if defined(_MSC_VER) && _MSC_VER < 1900
31 count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
33 count = _vscprintf(format, ap);
51 #pragma warning(disable : 4702)
54 #define JSON_ASSERT_UNREACHABLE assert(false)
58 static std::unique_ptr<T>
cloneUnique(
const std::unique_ptr<T>& p) {
61 r = std::unique_ptr<T>(
new T(*p));
69 #if defined(__ARMEL__)
70 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
72 #define ALIGNAS(byte_alignment)
77 static Value const nullStatic;
94 #if defined(JSON_HAS_INT64)
102 #endif // defined(JSON_HAS_INT64)
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) {
115 return d >= min && d <= max;
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));
123 template <
typename T>
static inline double integerToDouble(T value) {
124 return static_cast<double>(value);
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);
131 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
146 char* newString = static_cast<char*>(malloc(length + 1));
147 if (newString ==
nullptr) {
149 "Failed to allocate string value buffer");
151 memcpy(newString, value, length);
152 newString[length] = 0;
159 unsigned int length) {
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) {
170 "Failed to allocate string value buffer");
172 *reinterpret_cast<unsigned*>(newString) = length;
173 memcpy(newString +
sizeof(
unsigned), value, length);
174 newString[actualLength - 1U] =
179 char const* prefixed,
181 char const** value) {
183 *length = static_cast<unsigned>(strlen(prefixed));
186 *length = *reinterpret_cast<unsigned const*>(prefixed);
187 *value = prefixed +
sizeof(unsigned);
193 #if JSONCPP_USING_SECURE_MEMORY
196 char const* valueDecoded;
198 size_t const size =
sizeof(unsigned) + length + 1U;
199 memset(value, 0, size);
204 size_t size = (length == 0) ? strlen(value) : length;
205 memset(value, 0, size);
208 #else // !JSONCPP_USING_SECURE_MEMORY
211 #endif // JSONCPP_USING_SECURE_MEMORY
222 #if !defined(JSON_IS_AMALGAMATION)
225 #endif // if !defined(JSON_IS_AMALGAMATION)
229 #if JSON_USE_EXCEPTION
241 #else // !JSON_USE_EXCEPTION
257 Value::CZString::CZString(
ArrayIndex index) : cstr_(nullptr), index_(index) {}
259 Value::CZString::CZString(
char const* str,
261 DuplicationPolicy allocate)
264 storage_.policy_ = allocate & 0x3;
265 storage_.length_ = length & 0x3FFFFFFF;
268 Value::CZString::CZString(
const CZString& other) {
269 cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ !=
nullptr
273 static_cast<unsigned>(
275 ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
279 : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
281 storage_.length_ = other.storage_.length_;
284 Value::CZString::CZString(CZString&& other)
285 : cstr_(other.cstr_), index_(other.index_) {
286 other.cstr_ =
nullptr;
289 Value::CZString::~CZString() {
290 if (cstr_ && storage_.policy_ == duplicate) {
292 storage_.length_ + 1u);
304 Value::CZString& Value::CZString::operator=(
const CZString& other) {
306 index_ = other.index_;
310 Value::CZString& Value::CZString::operator=(CZString&& other) {
312 index_ = other.index_;
313 other.cstr_ =
nullptr;
317 bool Value::CZString::operator<(
const CZString& other)
const {
319 return index_ < other.index_;
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);
326 int comp = memcmp(this->cstr_, other.cstr_, min_len);
331 return (this_len < other_len);
336 return index_ == other.index_;
339 unsigned this_len = this->storage_.length_;
340 unsigned other_len = other.storage_.length_;
341 if (this_len != other_len)
344 int comp = memcmp(this->cstr_, other.cstr_, this_len);
348 ArrayIndex Value::CZString::index()
const {
return index_; }
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;
370 static char const emptyString[] =
"";
384 value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
388 value_.map_ =
new ObjectValues();
391 value_.bool_ =
false;
405 value_.uint_ = value;
407 #if defined(JSON_HAS_INT64)
414 value_.uint_ = value;
416 #endif // defined(JSON_HAS_INT64)
418 Value::Value(
double value) {
420 value_.real_ = value;
423 Value::Value(
const char* value) {
426 "Null Value Passed to Value Constructor");
428 value, static_cast<unsigned>(strlen(value)));
431 Value::Value(
const char* begin,
const char* end) {
440 value.data(), static_cast<unsigned>(value.length()));
445 value_.string_ = const_cast<char*>(value.
c_str());
448 #ifdef JSON_USE_CPPTL
449 Value::Value(
const CppTL::ConstString& value) {
452 value, static_cast<unsigned>(value.length()));
456 Value::Value(
bool value) {
458 value_.bool_ = value;
486 void Value::swapPayload(
Value& other) {
491 void Value::copyPayload(
const Value& other) {
503 void Value::copy(
const Value& other) {
509 return static_cast<ValueType>(bits_.value_type_);
512 int Value::compare(
const Value& other)
const {
520 bool Value::operator<(
const Value& other)
const {
521 int typeDelta = type() - other.
type();
523 return typeDelta < 0 ? true :
false;
528 return value_.int_ < other.value_.int_;
530 return value_.uint_ < other.value_.uint_;
532 return value_.real_ < other.value_.real_;
534 return value_.bool_ < other.value_.bool_;
536 if ((value_.string_ ==
nullptr) || (other.value_.string_ ==
nullptr)) {
537 if (other.value_.string_)
544 char const* this_str;
545 char const* other_str;
550 unsigned min_len = std::min<unsigned>(this_len, other_len);
552 int comp = memcmp(this_str, other_str, min_len);
557 return (this_len < other_len);
561 int delta = int(value_.map_->size() - other.value_.map_->size());
564 return (*value_.map_) < (*other.value_.map_);
572 bool Value::operator<=(
const Value& other)
const {
return !(other < *
this); }
574 bool Value::operator>=(
const Value& other)
const {
return !(*
this < other); }
576 bool Value::operator>(
const Value& other)
const {
return other < *
this; }
579 if (type() != other.
type())
585 return value_.int_ == other.value_.int_;
587 return value_.uint_ == other.value_.uint_;
589 return value_.real_ == other.value_.real_;
591 return value_.bool_ == other.value_.bool_;
593 if ((value_.string_ ==
nullptr) || (other.value_.string_ ==
nullptr)) {
594 return (value_.string_ == other.value_.string_);
598 char const* this_str;
599 char const* other_str;
604 if (this_len != other_len)
607 int comp = memcmp(this_str, other_str, this_len);
612 return value_.map_->size() == other.value_.map_->size() &&
613 (*value_.map_) == (*other.value_.map_);
622 const char* Value::asCString()
const {
624 "in Json::Value::asCString(): requires stringValue");
625 if (value_.string_ ==
nullptr)
628 char const* this_str;
634 #if JSONCPP_USING_SECURE_MEMORY
635 unsigned Value::getCStringLength()
const {
637 "in Json::Value::asCString(): requires stringValue");
638 if (value_.string_ == 0)
641 char const* this_str;
648 bool Value::getString(
char const** begin,
char const** end)
const {
651 if (value_.string_ ==
nullptr)
656 *end = *begin + length;
665 if (value_.string_ ==
nullptr)
668 char const* this_str;
671 return String(this_str, this_len);
674 return value_.bool_ ?
"true" :
"false";
686 #ifdef JSON_USE_CPPTL
687 CppTL::ConstString Value::asConstString()
const {
691 return CppTL::ConstString(str, len);
699 return Int(value_.int_);
702 return Int(value_.uint_);
705 "double out of Int range");
706 return Int(value_.real_);
710 return value_.bool_ ? 1 : 0;
721 return UInt(value_.int_);
724 return UInt(value_.uint_);
727 "double out of UInt range");
728 return UInt(value_.real_);
732 return value_.bool_ ? 1 : 0;
739 #if defined(JSON_HAS_INT64)
744 return Int64(value_.int_);
747 return Int64(value_.uint_);
750 "double out of Int64 range");
751 return Int64(value_.real_);
755 return value_.bool_ ? 1 : 0;
766 return UInt64(value_.int_);
768 return UInt64(value_.uint_);
771 "double out of UInt64 range");
772 return UInt64(value_.real_);
776 return value_.bool_ ? 1 : 0;
782 #endif // if defined(JSON_HAS_INT64)
785 #if defined(JSON_NO_INT64)
793 #if defined(JSON_NO_INT64)
800 double Value::asDouble()
const {
803 return static_cast<double>(value_.int_);
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)
815 return value_.bool_ ? 1.0 : 0.0;
822 float Value::asFloat()
const {
825 return static_cast<float>(value_.int_);
827 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
828 return static_cast<float>(value_.uint_);
829 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
831 return static_cast<float>(integerToDouble(value_.uint_));
832 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
834 return static_cast<float>(value_.real_);
838 return value_.bool_ ? 1.0f : 0.0f;
845 bool Value::asBool()
const {
852 return value_.int_ ? true :
false;
854 return value_.uint_ ? true :
false;
857 const auto value_classification = std::fpclassify(value_.real_);
858 return value_classification != FP_ZERO && value_classification != FP_NAN;
869 return (isNumeric() && asDouble() == 0.0) ||
872 (type() ==
arrayValue && value_.map_->empty()) ||
910 if (!value_.map_->empty()) {
911 ObjectValues::const_iterator itLast = value_.map_->end();
913 return (*itLast).first.index() + 1;
923 bool Value::empty()
const {
924 if (isNull() || isArray() || isObject())
930 Value::operator bool()
const {
return !isNull(); }
932 void Value::clear() {
935 "in Json::Value::clear(): requires complex value");
941 value_.map_->clear();
950 "in Json::Value::resize(): requires arrayValue");
956 else if (newSize > oldSize)
957 this->operator[](newSize - 1);
959 for (
ArrayIndex index = newSize; index < oldSize; ++index) {
960 value_.map_->erase(index);
969 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
973 auto it = value_.map_->lower_bound(key);
974 if (it != value_.map_->end() && (*it).first == key)
977 ObjectValues::value_type defaultValue(key, nullSingleton());
978 it = value_.map_->insert(it, defaultValue);
982 Value& Value::operator[](
int index) {
985 "in Json::Value::operator[](int index): index cannot be negative");
992 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
994 return nullSingleton();
996 ObjectValues::const_iterator it = value_.map_->find(key);
997 if (it == value_.map_->end())
998 return nullSingleton();
1002 const Value& Value::operator[](
int index)
const {
1005 "in Json::Value::operator[](int index) const: index cannot be negative");
1009 void Value::initBasic(
ValueType type,
bool allocated) {
1011 setIsAllocated(allocated);
1012 comments_ = Comments{};
1017 void Value::dupPayload(
const Value& other) {
1018 setType(other.type());
1019 setIsAllocated(
false);
1026 value_ = other.value_;
1029 if (other.value_.string_ && other.isAllocated()) {
1035 setIsAllocated(
true);
1037 value_.string_ = other.value_.string_;
1042 value_.map_ =
new ObjectValues(*other.value_.map_);
1049 void Value::releasePayload() {
1070 void Value::dupMeta(
const Value& other) {
1071 comments_ = other.comments_;
1072 start_ = other.start_;
1073 limit_ = other.limit_;
1079 Value& Value::resolveReference(
const char* key) {
1082 "in Json::Value::resolveReference(): requires objectValue");
1085 CZString actualKey(key, static_cast<unsigned>(strlen(key)),
1086 CZString::noDuplication);
1087 auto it = value_.map_->lower_bound(actualKey);
1088 if (it != value_.map_->end() && (*it).first == actualKey)
1089 return (*it).second;
1091 ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1092 it = value_.map_->insert(it, defaultValue);
1093 Value& value = (*it).second;
1098 Value& Value::resolveReference(
char const* key,
char const* end) {
1101 "in Json::Value::resolveReference(key, end): requires 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;
1110 ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1111 it = value_.map_->insert(it, defaultValue);
1112 Value& value = (*it).second;
1117 const Value* value = &((*this)[index]);
1118 return value == &nullSingleton() ? defaultValue : *value;
1121 bool Value::isValidIndex(
ArrayIndex index)
const {
return index < size(); }
1123 Value const* Value::find(
char const* begin,
char const* end)
const {
1125 "in Json::Value::find(begin, end): requires "
1126 "objectValue or nullValue");
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())
1134 return &(*it).second;
1136 Value* Value::demand(
char const* begin,
char const* end) {
1138 "in Json::Value::demand(begin, end): requires "
1139 "objectValue or nullValue");
1140 return &resolveReference(begin, end);
1142 const Value& Value::operator[](
const char* key)
const {
1143 Value const* found = find(key, key + strlen(key));
1145 return nullSingleton();
1149 Value const* found = find(key.data(), key.data() + key.length());
1151 return nullSingleton();
1155 Value& Value::operator[](
const char* key) {
1156 return resolveReference(key, key + strlen(key));
1160 return resolveReference(key.data(), key.data() + key.length());
1164 return resolveReference(key.
c_str());
1167 #ifdef JSON_USE_CPPTL
1168 Value& Value::operator[](
const CppTL::ConstString& key) {
1169 return resolveReference(key.c_str(), key.end_c_str());
1171 Value
const& Value::operator[](CppTL::ConstString
const& key)
const {
1172 Value
const* found = find(key.c_str(), key.end_c_str());
1174 return nullSingleton();
1179 Value& Value::append(
const Value& value) {
return (*
this)[size()] = value; }
1182 return (*
this)[size()] = std::move(value);
1187 Value const& defaultValue)
const {
1188 Value const* found = find(begin, end);
1189 return !found ? defaultValue : *found;
1191 Value Value::get(
char const* key,
Value const& defaultValue)
const {
1192 return get(key, key + strlen(key), defaultValue);
1195 return get(key.data(), key.data() + key.length(), defaultValue);
1198 bool Value::removeMember(
const char* begin,
const char* end,
Value* removed) {
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())
1208 *removed = std::move(it->second);
1209 value_.map_->erase(it);
1212 bool Value::removeMember(
const char* key,
Value* removed) {
1213 return removeMember(key, key + strlen(key), removed);
1216 return removeMember(key.data(), key.data() + key.length(), removed);
1218 void Value::removeMember(
const char* key) {
1220 "in Json::Value::removeMember(): requires objectValue");
1224 CZString actualKey(key,
unsigned(strlen(key)), CZString::noDuplication);
1225 value_.map_->erase(actualKey);
1227 void Value::removeMember(
const String& key) { removeMember(key.c_str()); }
1233 CZString key(index);
1234 auto it = value_.map_->find(key);
1235 if (it == value_.map_->end()) {
1239 *removed = it->second;
1242 for (
ArrayIndex i = index; i < (oldSize - 1); ++i) {
1244 (*value_.map_)[keey] = (*
this)[i + 1];
1247 CZString keyLast(oldSize - 1);
1248 auto itLast = value_.map_->find(keyLast);
1249 value_.map_->erase(itLast);
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);
1260 bool Value::isMember(
char const* begin,
char const* end)
const {
1261 Value const* value = find(begin, end);
1262 return nullptr != value;
1264 bool Value::isMember(
char const* key)
const {
1265 return isMember(key, key + strlen(key));
1267 bool Value::isMember(
String const& key)
const {
1268 return isMember(key.data(), key.data() + key.length());
1271 #ifdef JSON_USE_CPPTL
1272 bool Value::isMember(
const CppTL::ConstString& key)
const {
1273 return isMember(key.c_str(), key.end_c_str());
1280 "in Json::Value::getMemberNames(), value must be objectValue");
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()));
1319 double integral_part;
1320 return modf(d, &integral_part) == 0.0;
1327 bool Value::isInt()
const {
1330 #if defined(JSON_HAS_INT64)
1331 return value_.int_ >= minInt && value_.int_ <= maxInt;
1336 return value_.uint_ <=
UInt(maxInt);
1338 return value_.real_ >= minInt && value_.real_ <= maxInt &&
1346 bool Value::isUInt()
const {
1349 #if defined(JSON_HAS_INT64)
1352 return value_.int_ >= 0;
1355 #if defined(JSON_HAS_INT64)
1356 return value_.uint_ <= maxUInt;
1361 return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1369 bool Value::isInt64()
const {
1370 #if defined(JSON_HAS_INT64)
1375 return value_.uint_ <=
UInt64(maxInt64);
1380 return value_.real_ >= double(minInt64) &&
1381 value_.real_ < double(maxInt64) &&
IsIntegral(value_.real_);
1385 #endif // JSON_HAS_INT64
1389 bool Value::isUInt64()
const {
1390 #if defined(JSON_HAS_INT64)
1393 return value_.int_ >= 0;
1405 #endif // JSON_HAS_INT64
1409 bool Value::isIntegral()
const {
1415 #if defined(JSON_HAS_INT64)
1419 return value_.real_ >= double(minInt64) &&
1422 return value_.real_ >= minInt && value_.real_ <= maxUInt &&
1424 #endif // JSON_HAS_INT64
1431 bool Value::isDouble()
const {
1435 bool Value::isNumeric()
const {
return isDouble(); }
1443 Value::Comments::Comments(
const Comments& that)
1446 Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {}
1448 Value::Comments& Value::Comments::operator=(
const Comments& that) {
1453 Value::Comments& Value::Comments::operator=(Comments&& that) {
1454 ptr_ = std::move(that.ptr_);
1459 return ptr_ && !(*ptr_)[slot].empty();
1465 return (*ptr_)[slot];
1470 ptr_ = std::unique_ptr<Array>(
new Array());
1472 (*ptr_)[slot] = std::move(comment);
1476 if (!comment.empty() && (comment.back() ==
'\n')) {
1482 comment[0] ==
'\0' || comment[0] ==
'/',
1483 "in Json::Value::setComment(): Comments must start with /");
1484 comments_.set(
placement, std::move(comment));
1544 return iterator(value_.map_->begin());
1557 return iterator(value_.map_->end());
1571 : key_(), index_(index), kind_(kindIndex) {}
1574 : key_(key), index_(), kind_(kindKey) {}
1577 : key_(key.c_str()), index_(), kind_(kindKey) {}
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 ==
'[') {
1605 if (*current ==
'%')
1606 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1609 for (; current != end && *current >=
'0' && *current <=
'9'; ++current)
1610 index = index * 10 +
ArrayIndex(*current -
'0');
1611 args_.push_back(index);
1613 if (current == end || *++current !=
']')
1614 invalidPath(path,
int(current - path.c_str()));
1615 }
else if (*current ==
'%') {
1616 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1618 }
else if (*current ==
'.' || *current ==
']') {
1621 const char* beginName = current;
1622 while (current != end && !strchr(
"[.", *current))
1624 args_.push_back(
String(beginName, current));
1629 void Path::addPathInArg(
const String& ,
1631 InArgs::const_iterator& itInArg,
1632 PathArgument::Kind kind) {
1633 if (itInArg == in.end()) {
1635 }
else if ((*itInArg)->kind_ != kind) {
1638 args_.push_back(**itInArg++);
1642 void Path::invalidPath(
const String& ,
int ) {
1647 const Value* node = &root;
1648 for (
const auto& arg : args_) {
1649 if (arg.kind_ == PathArgument::kindIndex) {
1654 node = &((*node)[arg.index_]);
1655 }
else if (arg.kind_ == PathArgument::kindKey) {
1660 node = &((*node)[arg.key_]);
1672 const Value* node = &root;
1673 for (
const auto& arg : args_) {
1674 if (arg.kind_ == PathArgument::kindIndex) {
1676 return defaultValue;
1677 node = &((*node)[arg.index_]);
1678 }
else if (arg.kind_ == PathArgument::kindKey) {
1680 return defaultValue;
1681 node = &((*node)[arg.key_]);
1683 return defaultValue;
1690 Value* node = &root;
1691 for (
const auto& arg : args_) {
1692 if (arg.kind_ == PathArgument::kindIndex) {
1696 node = &((*node)[arg.index_]);
1697 }
else if (arg.kind_ == PathArgument::kindKey) {
1701 node = &((*node)[arg.key_]);