6 #if !defined(JSON_IS_AMALGAMATION)
10 #endif // if !defined(JSON_IS_AMALGAMATION)
17 #include <cpptl/conststring.h>
22 #define JSON_ASSERT_UNREACHABLE assert(false)
29 #if defined(__ARMEL__)
30 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
32 #define ALIGNAS(byte_alignment)
42 static Value const nullStatic;
54 #if defined(JSON_HAS_INT64)
62 #endif // defined(JSON_HAS_INT64)
67 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
68 template <
typename T,
typename U>
69 static inline bool InRange(
double d, T min, U max) {
73 return d >= min && d <= max;
75 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
76 static inline double integerToDouble(
Json::UInt64 value) {
77 return static_cast<double>(
Int64(value / 2)) * 2.0 +
static_cast<double>(
Int64(value & 1));
80 template <
typename T>
static inline double integerToDouble(T value) {
81 return static_cast<double>(value);
84 template <
typename T,
typename U>
85 static inline bool InRange(
double d, T min, U max) {
86 return d >= integerToDouble(min) && d <= integerToDouble(max);
88 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
105 char* newString =
static_cast<char*
>(malloc(length + 1));
106 if (newString == NULL) {
108 "in Json::Value::duplicateStringValue(): "
109 "Failed to allocate string value buffer");
111 memcpy(newString, value, length);
112 newString[length] = 0;
125 "in Json::Value::duplicateAndPrefixStringValue(): "
126 "length too big for prefixing");
127 unsigned actualLength = length +
static_cast<unsigned>(
sizeof(unsigned)) + 1U;
128 char* newString =
static_cast<char*
>(malloc(actualLength));
129 if (newString == 0) {
131 "in Json::Value::duplicateAndPrefixStringValue(): "
132 "Failed to allocate string value buffer");
134 *
reinterpret_cast<unsigned*
>(newString) = length;
135 memcpy(newString +
sizeof(
unsigned), value, length);
136 newString[actualLength - 1U] = 0;
140 bool isPrefixed,
char const* prefixed,
141 unsigned* length,
char const** value)
144 *length =
static_cast<unsigned>(strlen(prefixed));
147 *length = *
reinterpret_cast<unsigned const*
>(prefixed);
148 *value = prefixed +
sizeof(unsigned);
153 #if JSONCPP_USING_SECURE_MEMORY
156 char const* valueDecoded;
158 size_t const size =
sizeof(unsigned) + length + 1U;
159 memset(value, 0, size);
164 size_t size = (length==0) ? strlen(value) : length;
165 memset(value, 0, size);
168 #else // !JSONCPP_USING_SECURE_MEMORY
175 #endif // JSONCPP_USING_SECURE_MEMORY
186 #if !defined(JSON_IS_AMALGAMATION)
189 #endif // if !defined(JSON_IS_AMALGAMATION)
214 throw LogicError(msg);
225 Value::CommentInfo::CommentInfo() : comment_(0)
228 Value::CommentInfo::~CommentInfo() {
233 void Value::CommentInfo::setComment(
const char* text,
size_t len) {
240 text[0] ==
'\0' || text[0] ==
'/',
241 "in Json::Value::setComment(): Comments must start with /");
257 Value::CZString::CZString(
ArrayIndex aindex) : cstr_(0), index_(aindex) {}
259 Value::CZString::CZString(
char const* str,
unsigned ulength, DuplicationPolicy allocate)
262 storage_.policy_ = allocate & 0x3;
263 storage_.length_ = ulength & 0x3FFFFFFF;
266 Value::CZString::CZString(
const CZString& other) {
267 cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
270 storage_.policy_ =
static_cast<unsigned>(other.cstr_
271 ? (
static_cast<DuplicationPolicy
>(other.storage_.policy_) == noDuplication
272 ? noDuplication : duplicate)
273 :
static_cast<DuplicationPolicy
>(other.storage_.policy_)) & 3U;
274 storage_.length_ = other.storage_.length_;
277 #if JSON_HAS_RVALUE_REFERENCES
278 Value::CZString::CZString(CZString&& other)
279 : cstr_(other.cstr_), index_(other.index_) {
280 other.cstr_ =
nullptr;
284 Value::CZString::~CZString() {
285 if (cstr_ && storage_.policy_ == duplicate) {
290 void Value::CZString::swap(CZString& other) {
295 Value::CZString& Value::CZString::operator=(
const CZString& other) {
297 index_ = other.index_;
301 #if JSON_HAS_RVALUE_REFERENCES
302 Value::CZString& Value::CZString::operator=(CZString&& other) {
304 index_ = other.index_;
305 other.cstr_ =
nullptr;
310 bool Value::CZString::operator<(
const CZString& other)
const {
311 if (!cstr_)
return index_ < other.index_;
314 unsigned this_len = this->storage_.length_;
315 unsigned other_len = other.storage_.length_;
316 unsigned min_len = std::min<unsigned>(this_len, other_len);
318 int comp = memcmp(this->cstr_, other.cstr_, min_len);
319 if (comp < 0)
return true;
320 if (comp > 0)
return false;
321 return (this_len < other_len);
325 if (!cstr_)
return index_ == other.index_;
328 unsigned this_len = this->storage_.length_;
329 unsigned other_len = other.storage_.length_;
330 if (this_len != other_len)
return false;
332 int comp = memcmp(this->cstr_, other.cstr_, this_len);
336 ArrayIndex Value::CZString::index()
const {
return index_; }
339 const char* Value::CZString::data()
const {
return cstr_; }
340 unsigned Value::CZString::length()
const {
return storage_.length_; }
341 bool Value::CZString::isStaticString()
const {
return storage_.policy_ == noDuplication; }
356 static char const emptyString[] =
"";
370 value_.string_ =
const_cast<char*
>(
static_cast<char const*
>(emptyString));
374 value_.map_ =
new ObjectValues();
377 value_.bool_ =
false;
391 value_.uint_ = value;
393 #if defined(JSON_HAS_INT64)
400 value_.uint_ = value;
402 #endif // defined(JSON_HAS_INT64)
404 Value::Value(
double value) {
406 value_.real_ = value;
409 Value::Value(
const char* value) {
415 Value::Value(
const char* beginValue,
const char* endValue) {
429 value_.string_ =
const_cast<char*
>(value.
c_str());
432 #ifdef JSON_USE_CPPTL
433 Value::Value(
const CppTL::ConstString& value) {
439 Value::Value(
bool value) {
441 value_.bool_ = value;
445 : type_(other.type_), allocated_(false)
447 comments_(0), start_(other.start_), limit_(other.limit_)
455 value_ = other.value_;
458 if (other.value_.string_ && other.allocated_) {
466 value_.string_ = other.value_.string_;
472 value_.map_ =
new ObjectValues(*other.value_.map_);
477 if (other.comments_) {
480 const CommentInfo& otherComment = other.comments_[comment];
481 if (otherComment.comment_)
482 comments_[comment].setComment(
483 otherComment.comment_, strlen(otherComment.comment_));
488 #if JSON_HAS_RVALUE_REFERENCES
530 std::swap(value_, other.value_);
531 int temp2 = allocated_;
532 allocated_ = other.allocated_;
533 other.allocated_ = temp2 & 0x1;
538 value_ = other.value_;
539 allocated_ = other.allocated_;
544 std::swap(comments_, other.comments_);
545 std::swap(start_, other.start_);
546 std::swap(limit_, other.limit_);
551 comments_ = other.comments_;
552 start_ = other.start_;
553 limit_ = other.limit_;
567 int typeDelta = type_ - other.type_;
569 return typeDelta < 0 ? true :
false;
574 return value_.int_ < other.value_.int_;
576 return value_.uint_ < other.value_.uint_;
578 return value_.real_ < other.value_.real_;
580 return value_.bool_ < other.value_.bool_;
583 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
584 if (other.value_.string_)
return true;
589 char const* this_str;
590 char const* other_str;
593 unsigned min_len = std::min<unsigned>(this_len, other_len);
595 int comp = memcmp(this_str, other_str, min_len);
596 if (comp < 0)
return true;
597 if (comp > 0)
return false;
598 return (this_len < other_len);
602 int delta = int(value_.map_->size() - other.value_.map_->size());
605 return (*value_.map_) < (*other.value_.map_);
624 int temp = other.type_;
631 return value_.int_ == other.value_.int_;
633 return value_.uint_ == other.value_.uint_;
635 return value_.real_ == other.value_.real_;
637 return value_.bool_ == other.value_.bool_;
640 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
641 return (value_.string_ == other.value_.string_);
645 char const* this_str;
646 char const* other_str;
649 if (this_len != other_len)
return false;
651 int comp = memcmp(this_str, other_str, this_len);
656 return value_.map_->size() == other.value_.map_->size() &&
657 (*value_.map_) == (*other.value_.map_);
668 "in Json::Value::asCString(): requires stringValue");
669 if (value_.string_ == 0)
return 0;
671 char const* this_str;
676 #if JSONCPP_USING_SECURE_MEMORY
677 unsigned Value::getCStringLength()
const {
679 "in Json::Value::asCString(): requires stringValue");
680 if (value_.string_ == 0)
return 0;
682 char const* this_str;
690 if (value_.string_ == 0)
return false;
693 *cend = *str + length;
703 if (value_.string_ == 0)
return "";
705 char const* this_str;
710 return value_.bool_ ?
"true" :
"false";
722 #ifdef JSON_USE_CPPTL
723 CppTL::ConstString Value::asConstString()
const {
728 return CppTL::ConstString(str, len);
736 return Int(value_.int_);
739 return Int(value_.uint_);
742 "double out of Int range");
743 return Int(value_.real_);
747 return value_.bool_ ? 1 : 0;
758 return UInt(value_.int_);
761 return UInt(value_.uint_);
764 "double out of UInt range");
765 return UInt(value_.real_);
769 return value_.bool_ ? 1 : 0;
776 #if defined(JSON_HAS_INT64)
781 return Int64(value_.int_);
784 return Int64(value_.uint_);
787 "double out of Int64 range");
788 return Int64(value_.real_);
792 return value_.bool_ ? 1 : 0;
803 return UInt64(value_.int_);
805 return UInt64(value_.uint_);
808 "double out of UInt64 range");
809 return UInt64(value_.real_);
813 return value_.bool_ ? 1 : 0;
819 #endif // if defined(JSON_HAS_INT64)
822 #if defined(JSON_NO_INT64)
830 #if defined(JSON_NO_INT64)
840 return static_cast<double>(value_.int_);
842 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
843 return static_cast<double>(value_.uint_);
844 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
845 return integerToDouble(value_.uint_);
846 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
852 return value_.bool_ ? 1.0 : 0.0;
862 return static_cast<float>(value_.int_);
864 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
865 return static_cast<float>(value_.uint_);
866 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
868 return static_cast<float>(integerToDouble(value_.uint_));
869 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
871 return static_cast<float>(value_.real_);
875 return value_.bool_ ? 1.0f : 0.0f;
889 return value_.int_ ? true :
false;
891 return value_.uint_ ? true :
false;
894 return (value_.real_ != 0.0) ? true :
false;
907 (type_ ==
arrayValue && value_.map_->size() == 0) ||
908 (type_ ==
objectValue && value_.map_->size() == 0) ||
945 if (!value_.map_->empty()) {
946 ObjectValues::const_iterator itLast = value_.map_->end();
948 return (*itLast).first.index() + 1;
965 Value::operator bool()
const {
return ! isNull(); }
970 "in Json::Value::clear(): requires complex value");
976 value_.map_->clear();
985 "in Json::Value::resize(): requires arrayValue");
991 else if (newSize > oldSize)
992 (*this)[newSize - 1];
994 for (
ArrayIndex index = newSize; index < oldSize; ++index) {
995 value_.map_->erase(index);
1004 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
1007 CZString key(index);
1008 ObjectValues::iterator it = value_.map_->lower_bound(key);
1009 if (it != value_.map_->end() && (*it).first == key)
1010 return (*it).second;
1012 ObjectValues::value_type defaultValue(key,
nullSingleton());
1013 it = value_.map_->insert(it, defaultValue);
1014 return (*it).second;
1020 "in Json::Value::operator[](int index): index cannot be negative");
1027 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
1030 CZString key(index);
1031 ObjectValues::const_iterator it = value_.map_->find(key);
1032 if (it == value_.map_->end())
1034 return (*it).second;
1040 "in Json::Value::operator[](int index) const: index cannot be negative");
1044 void Value::initBasic(
ValueType vtype,
bool allocated) {
1046 allocated_ = allocated;
1055 Value& Value::resolveReference(
const char* key) {
1058 "in Json::Value::resolveReference(): requires objectValue");
1062 key,
static_cast<unsigned>(strlen(key)), CZString::noDuplication);
1063 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
1064 if (it != value_.map_->end() && (*it).first == actualKey)
1065 return (*it).second;
1067 ObjectValues::value_type defaultValue(actualKey,
nullSingleton());
1068 it = value_.map_->insert(it, defaultValue);
1069 Value& value = (*it).second;
1074 Value& Value::resolveReference(
char const* key,
char const* cend)
1078 "in Json::Value::resolveReference(key, end): requires objectValue");
1082 key,
static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
1083 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
1084 if (it != value_.map_->end() && (*it).first == actualKey)
1085 return (*it).second;
1087 ObjectValues::value_type defaultValue(actualKey,
nullSingleton());
1088 it = value_.map_->insert(it, defaultValue);
1089 Value& value = (*it).second;
1094 const Value* value = &((*this)[index]);
1104 "in Json::Value::find(key, end, found): requires objectValue or nullValue");
1106 CZString actualKey(key,
static_cast<unsigned>(cend-key), CZString::noDuplication);
1107 ObjectValues::const_iterator it = value_.map_->find(actualKey);
1108 if (it == value_.map_->end())
return NULL;
1109 return &(*it).second;
1113 Value const* found =
find(key, key + strlen(key));
1119 Value const* found =
find(key.data(), key.data() + key.length());
1125 return resolveReference(key, key + strlen(key));
1129 return resolveReference(key.data(), key.data() + key.length());
1133 return resolveReference(key.
c_str());
1136 #ifdef JSON_USE_CPPTL
1138 return resolveReference(key.c_str(), key.end_c_str());
1142 Value const* found =
find(key.c_str(), key.end_c_str());
1150 #if JSON_HAS_RVALUE_REFERENCES
1157 return !found ? defaultValue : *found;
1161 return get(key, key + strlen(key), defaultValue);
1165 return get(key.data(), key.data() + key.length(), defaultValue);
1174 CZString actualKey(key,
static_cast<unsigned>(cend-key), CZString::noDuplication);
1175 ObjectValues::iterator it = value_.map_->find(actualKey);
1176 if (it == value_.map_->end())
1178 *removed = it->second;
1179 value_.map_->erase(it);
1188 return removeMember(key.data(), key.data() + key.length(), removed);
1193 "in Json::Value::removeMember(): requires objectValue");
1197 CZString actualKey(key,
unsigned(strlen(key)), CZString::noDuplication);
1198 value_.map_->erase(actualKey);
1209 CZString key(index);
1210 ObjectValues::iterator it = value_.map_->find(key);
1211 if (it == value_.map_->end()) {
1214 *removed = it->second;
1217 for (
ArrayIndex i = index; i < (oldSize - 1); ++i){
1219 (*value_.map_)[keey] = (*
this)[i + 1];
1222 CZString keyLast(oldSize - 1);
1223 ObjectValues::iterator itLast = value_.map_->find(keyLast);
1224 value_.map_->erase(itLast);
1228 #ifdef JSON_USE_CPPTL
1230 const Value& defaultValue)
const {
1231 return get(key.c_str(), key.end_c_str(), defaultValue);
1238 return NULL != value;
1242 return isMember(key, key + strlen(key));
1246 return isMember(key.data(), key.data() + key.length());
1249 #ifdef JSON_USE_CPPTL
1251 return isMember(key.c_str(), key.end_c_str());
1258 "in Json::Value::getMemberNames(), value must be objectValue");
1262 members.reserve(value_.map_->size());
1263 ObjectValues::const_iterator it = value_.map_->begin();
1264 ObjectValues::const_iterator itEnd = value_.map_->end();
1265 for (; it != itEnd; ++it) {
1267 (*it).first.length()));
1298 double integral_part;
1299 return modf(d, &integral_part) == 0.0;
1309 #if defined(JSON_HAS_INT64)
1317 return value_.real_ >=
minInt && value_.real_ <=
maxInt &&
1328 #if defined(JSON_HAS_INT64)
1331 return value_.int_ >= 0;
1334 #if defined(JSON_HAS_INT64)
1335 return value_.uint_ <=
maxUInt;
1340 return value_.real_ >= 0 && value_.real_ <=
maxUInt &&
1349 #if defined(JSON_HAS_INT64)
1359 return value_.real_ >= double(
minInt64) &&
1364 #endif // JSON_HAS_INT64
1369 #if defined(JSON_HAS_INT64)
1372 return value_.int_ >= 0;
1384 #endif // JSON_HAS_INT64
1394 #if defined(JSON_HAS_INT64)
1401 #endif // JSON_HAS_INT64
1421 if ((len > 0) && (comment[len-1] ==
'\n')) {
1425 comments_[placement].setComment(comment, len);
1429 setComment(comment, strlen(comment), placement);
1433 setComment(comment.c_str(), comment.length(), placement);
1437 return comments_ != 0 && comments_[placement].comment_ != 0;
1442 return comments_[placement].comment_;
1495 return iterator(value_.map_->begin());
1508 return iterator(value_.map_->end());
1522 : key_(), index_(index), kind_(kindIndex) {}
1525 : key_(key), index_(), kind_(kindKey) {}
1528 : key_(key.c_str()), index_(), kind_(kindKey) {}
1549 void Path::makePath(
const JSONCPP_STRING& path,
const InArgs& in) {
1550 const char* current = path.c_str();
1551 const char* end = current + path.length();
1552 InArgs::const_iterator itInArg = in.begin();
1553 while (current != end) {
1554 if (*current ==
'[') {
1556 if (*current ==
'%')
1557 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1560 for (; current != end && *current >=
'0' && *current <=
'9'; ++current)
1561 index = index * 10 +
ArrayIndex(*current -
'0');
1562 args_.push_back(index);
1564 if (current == end || *++current !=
']')
1565 invalidPath(path,
int(current - path.c_str()));
1566 }
else if (*current ==
'%') {
1567 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1569 }
else if (*current ==
'.' || *current ==
']') {
1572 const char* beginName = current;
1573 while (current != end && !strchr(
"[.", *current))
1582 InArgs::const_iterator& itInArg,
1583 PathArgument::Kind kind) {
1584 if (itInArg == in.end()) {
1586 }
else if ((*itInArg)->kind_ != kind) {
1589 args_.push_back(**itInArg++);
1598 const Value* node = &root;
1599 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1601 if (arg.kind_ == PathArgument::kindIndex) {
1606 node = &((*node)[arg.index_]);
1607 }
else if (arg.kind_ == PathArgument::kindKey) {
1612 node = &((*node)[arg.key_]);
1624 const Value* node = &root;
1625 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1627 if (arg.kind_ == PathArgument::kindIndex) {
1629 return defaultValue;
1630 node = &((*node)[arg.index_]);
1631 }
else if (arg.kind_ == PathArgument::kindKey) {
1633 return defaultValue;
1634 node = &((*node)[arg.key_]);
1636 return defaultValue;
1643 Value* node = &root;
1644 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1646 if (arg.kind_ == PathArgument::kindIndex) {
1650 node = &((*node)[arg.index_]);
1651 }
else if (arg.kind_ == PathArgument::kindKey) {
1655 node = &((*node)[arg.key_]);