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 #if defined(JSON_HAS_INT64)
50 #endif // defined(JSON_HAS_INT64)
55 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
56 template <
typename T,
typename U>
57 static inline bool InRange(
double d, T min, U max) {
58 return d >= min && d <= max;
60 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
61 static inline double integerToDouble(
Json::UInt64 value) {
62 return static_cast<double>(
Int64(value / 2)) * 2.0 +
Int64(value & 1);
65 template <
typename T>
static inline double integerToDouble(T value) {
66 return static_cast<double>(value);
69 template <
typename T,
typename U>
70 static inline bool InRange(
double d, T min, U max) {
71 return d >= integerToDouble(min) && d <= integerToDouble(max);
73 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
87 length = Value::maxInt - 1;
89 char* newString =
static_cast<char*
>(malloc(length + 1));
90 if (newString == NULL) {
92 "in Json::Value::duplicateStringValue(): "
93 "Failed to allocate string value buffer");
95 memcpy(newString, value, length);
96 newString[length] = 0;
109 "in Json::Value::duplicateAndPrefixStringValue(): "
110 "length too big for prefixing");
111 unsigned actualLength = length +
static_cast<unsigned>(
sizeof(unsigned)) + 1U;
112 char* newString =
static_cast<char*
>(malloc(actualLength));
113 if (newString == 0) {
115 "in Json::Value::duplicateAndPrefixStringValue(): "
116 "Failed to allocate string value buffer");
118 *
reinterpret_cast<unsigned*
>(newString) = length;
119 memcpy(newString +
sizeof(
unsigned), value, length);
120 newString[actualLength - 1U] = 0;
124 bool isPrefixed,
char const* prefixed,
125 unsigned* length,
char const** value)
128 *length =
static_cast<unsigned>(strlen(prefixed));
131 *length = *
reinterpret_cast<unsigned const*
>(prefixed);
132 *value = prefixed +
sizeof(unsigned);
148 #if !defined(JSON_IS_AMALGAMATION)
151 #endif // if !defined(JSON_IS_AMALGAMATION)
187 Value::CommentInfo::CommentInfo() : comment_(0) {}
189 Value::CommentInfo::~CommentInfo() {
194 void Value::CommentInfo::setComment(
const char* text,
size_t len) {
201 text[0] ==
'\0' || text[0] ==
'/',
202 "in Json::Value::setComment(): Comments must start with /");
218 Value::CZString::CZString(
ArrayIndex aindex) : cstr_(0), index_(aindex) {}
220 Value::CZString::CZString(
char const* str,
unsigned ulength, DuplicationPolicy allocate)
224 storage_.policy_ = allocate & 0x3;
225 storage_.length_ = ulength & 0x3FFFFFFF;
228 Value::CZString::CZString(
const CZString& other)
229 : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
233 storage_.policy_ = (other.cstr_
234 ? (
static_cast<DuplicationPolicy
>(other.storage_.policy_) == noDuplication
235 ? noDuplication : duplicate)
236 :
static_cast<DuplicationPolicy
>(other.storage_.policy_));
237 storage_.length_ = other.storage_.length_;
240 Value::CZString::~CZString() {
241 if (cstr_ && storage_.policy_ == duplicate)
245 void Value::CZString::swap(CZString& other) {
246 std::swap(cstr_, other.cstr_);
247 std::swap(index_, other.index_);
250 Value::CZString& Value::CZString::operator=(CZString other) {
255 bool Value::CZString::operator<(
const CZString& other)
const {
256 if (!cstr_)
return index_ < other.index_;
259 unsigned this_len = this->storage_.length_;
260 unsigned other_len = other.storage_.length_;
261 unsigned min_len = std::min(this_len, other_len);
262 int comp = memcmp(this->cstr_, other.cstr_, min_len);
263 if (comp < 0)
return true;
264 if (comp > 0)
return false;
265 return (this_len < other_len);
268 bool Value::CZString::operator==(
const CZString& other)
const {
269 if (!cstr_)
return index_ == other.index_;
272 unsigned this_len = this->storage_.length_;
273 unsigned other_len = other.storage_.length_;
274 if (this_len != other_len)
return false;
275 int comp = memcmp(this->cstr_, other.cstr_, this_len);
279 ArrayIndex Value::CZString::index()
const {
return index_; }
282 const char* Value::CZString::data()
const {
return cstr_; }
283 unsigned Value::CZString::length()
const {
return storage_.length_; }
284 bool Value::CZString::isStaticString()
const {
return storage_.policy_ == noDuplication; }
315 value_.map_ =
new ObjectValues();
318 value_.bool_ =
false;
332 value_.uint_ = value;
334 #if defined(JSON_HAS_INT64)
341 value_.uint_ = value;
343 #endif // defined(JSON_HAS_INT64)
345 Value::Value(
double value) {
347 value_.real_ = value;
350 Value::Value(
const char* value) {
355 Value::Value(
const char* beginValue,
const char* endValue) {
361 Value::Value(
const std::string& value) {
369 value_.string_ =
const_cast<char*
>(value.
c_str());
372 #ifdef JSON_USE_CPPTL
373 Value::Value(
const CppTL::ConstString& value) {
379 Value::Value(
bool value) {
381 value_.bool_ = value;
385 : type_(other.type_), allocated_(false)
387 comments_(0), start_(other.start_), limit_(other.limit_)
395 value_ = other.value_;
398 if (other.value_.string_ && other.allocated_) {
406 value_.string_ = other.value_.string_;
412 value_.map_ =
new ObjectValues(*other.value_.map_);
417 if (other.comments_) {
420 const CommentInfo& otherComment = other.comments_[comment];
421 if (otherComment.comment_)
422 comments_[comment].setComment(
423 otherComment.comment_, strlen(otherComment.comment_));
461 std::swap(value_, other.value_);
462 int temp2 = allocated_;
463 allocated_ = other.allocated_;
464 other.allocated_ = temp2 & 0x1;
469 std::swap(comments_, other.comments_);
470 std::swap(start_, other.start_);
471 std::swap(limit_, other.limit_);
485 int typeDelta = type_ - other.type_;
487 return typeDelta < 0 ?
true :
false;
492 return value_.int_ < other.value_.int_;
494 return value_.uint_ < other.value_.uint_;
496 return value_.real_ < other.value_.real_;
498 return value_.bool_ < other.value_.bool_;
501 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
502 if (other.value_.string_)
return true;
507 char const* this_str;
508 char const* other_str;
511 unsigned min_len = std::min(this_len, other_len);
512 int comp = memcmp(this_str, other_str, min_len);
513 if (comp < 0)
return true;
514 if (comp > 0)
return false;
515 return (this_len < other_len);
519 int delta = int(value_.map_->size() - other.value_.map_->size());
522 return (*value_.map_) < (*other.value_.map_);
541 int temp = other.type_;
548 return value_.int_ == other.value_.int_;
550 return value_.uint_ == other.value_.uint_;
552 return value_.real_ == other.value_.real_;
554 return value_.bool_ == other.value_.bool_;
557 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
558 return (value_.string_ == other.value_.string_);
562 char const* this_str;
563 char const* other_str;
566 if (this_len != other_len)
return false;
567 int comp = memcmp(this_str, other_str, this_len);
572 return value_.map_->size() == other.value_.map_->size() &&
573 (*value_.map_) == (*other.value_.map_);
584 "in Json::Value::asCString(): requires stringValue");
585 if (value_.string_ == 0)
return 0;
587 char const* this_str;
594 if (value_.string_ == 0)
return false;
597 *cend = *str + length;
607 if (value_.string_ == 0)
return "";
609 char const* this_str;
611 return std::string(this_str, this_len);
614 return value_.bool_ ?
"true" :
"false";
626 #ifdef JSON_USE_CPPTL
627 CppTL::ConstString Value::asConstString()
const {
632 return CppTL::ConstString(str, len);
640 return Int(value_.int_);
643 return Int(value_.uint_);
646 "double out of Int range");
647 return Int(value_.real_);
651 return value_.bool_ ? 1 : 0;
662 return UInt(value_.int_);
665 return UInt(value_.uint_);
668 "double out of UInt range");
669 return UInt(value_.real_);
673 return value_.bool_ ? 1 : 0;
680 #if defined(JSON_HAS_INT64)
685 return Int64(value_.int_);
688 return Int64(value_.uint_);
691 "double out of Int64 range");
692 return Int64(value_.real_);
696 return value_.bool_ ? 1 : 0;
707 return UInt64(value_.int_);
709 return UInt64(value_.uint_);
712 "double out of UInt64 range");
713 return UInt64(value_.real_);
717 return value_.bool_ ? 1 : 0;
723 #endif // if defined(JSON_HAS_INT64)
726 #if defined(JSON_NO_INT64)
734 #if defined(JSON_NO_INT64)
744 return static_cast<double>(value_.int_);
746 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
747 return static_cast<double>(value_.uint_);
748 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
749 return integerToDouble(value_.uint_);
750 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
756 return value_.bool_ ? 1.0 : 0.0;
766 return static_cast<float>(value_.int_);
768 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
769 return static_cast<float>(value_.uint_);
770 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
771 return integerToDouble(value_.uint_);
772 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
774 return static_cast<float>(value_.real_);
778 return value_.bool_ ? 1.0f : 0.0f;
792 return value_.int_ ?
true :
false;
794 return value_.uint_ ?
true :
false;
797 return (value_.real_ != 0.0) ?
true :
false;
810 (type_ ==
arrayValue && value_.map_->size() == 0) ||
811 (type_ ==
objectValue && value_.map_->size() == 0) ||
848 if (!value_.map_->empty()) {
849 ObjectValues::const_iterator itLast = value_.map_->end();
851 return (*itLast).first.index() + 1;
873 "in Json::Value::clear(): requires complex value");
879 value_.map_->clear();
888 "in Json::Value::resize(): requires arrayValue");
894 else if (newSize > oldSize)
895 (*this)[newSize - 1];
897 for (
ArrayIndex index = newSize; index < oldSize; ++index) {
898 value_.map_->erase(index);
900 assert(
size() == newSize);
907 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
911 ObjectValues::iterator it = value_.map_->lower_bound(key);
912 if (it != value_.map_->end() && (*it).first == key)
915 ObjectValues::value_type defaultValue(key,
nullRef);
916 it = value_.map_->insert(it, defaultValue);
923 "in Json::Value::operator[](int index): index cannot be negative");
930 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
934 ObjectValues::const_iterator it = value_.map_->find(key);
935 if (it == value_.map_->end())
943 "in Json::Value::operator[](int index) const: index cannot be negative");
947 void Value::initBasic(
ValueType vtype,
bool allocated) {
949 allocated_ = allocated;
958 Value& Value::resolveReference(
const char* key) {
961 "in Json::Value::resolveReference(): requires objectValue");
965 key, static_cast<unsigned>(strlen(key)), CZString::noDuplication);
966 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
967 if (it != value_.map_->end() && (*it).first == actualKey)
970 ObjectValues::value_type defaultValue(actualKey,
nullRef);
971 it = value_.map_->insert(it, defaultValue);
972 Value& value = (*it).second;
977 Value& Value::resolveReference(
char const* key,
char const* cend)
981 "in Json::Value::resolveReference(key, end): requires objectValue");
985 key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
986 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
987 if (it != value_.map_->end() && (*it).first == actualKey)
990 ObjectValues::value_type defaultValue(actualKey,
nullRef);
991 it = value_.map_->insert(it, defaultValue);
992 Value& value = (*it).second;
997 const Value* value = &((*this)[index]);
998 return value == &
nullRef ? defaultValue : *value;
1007 "in Json::Value::find(key, end, found): requires objectValue or nullValue");
1009 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1010 ObjectValues::const_iterator it = value_.map_->find(actualKey);
1011 if (it == value_.map_->end())
return NULL;
1012 return &(*it).second;
1016 Value const* found =
find(key, key + strlen(key));
1022 Value const* found =
find(key.data(), key.data() + key.length());
1028 return resolveReference(key, key + strlen(key));
1032 return resolveReference(key.data(), key.data() + key.length());
1036 return resolveReference(key.
c_str());
1039 #ifdef JSON_USE_CPPTL
1041 return resolveReference(key.c_str(), key.end_c_str());
1045 Value const* found =
find(key.c_str(), key.end_c_str());
1056 return !found ? defaultValue : *found;
1060 return get(key, key + strlen(key), defaultValue);
1064 return get(key.data(), key.data() + key.length(), defaultValue);
1073 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1074 ObjectValues::iterator it = value_.map_->find(actualKey);
1075 if (it == value_.map_->end())
1077 *removed = it->second;
1078 value_.map_->erase(it);
1087 return removeMember(key.data(), key.data() + key.length(), removed);
1092 "in Json::Value::removeMember(): requires objectValue");
1109 CZString key(index);
1110 ObjectValues::iterator it = value_.map_->find(key);
1111 if (it == value_.map_->end()) {
1114 *removed = it->second;
1117 for (
ArrayIndex i = index; i < (oldSize - 1); ++i){
1119 (*value_.map_)[keey] = (*
this)[i + 1];
1122 CZString keyLast(oldSize - 1);
1123 ObjectValues::iterator itLast = value_.map_->find(keyLast);
1124 value_.map_->erase(itLast);
1128 #ifdef JSON_USE_CPPTL
1130 const Value& defaultValue)
const {
1131 return get(key.c_str(), key.end_c_str(), defaultValue);
1138 return NULL != value;
1142 return isMember(key, key + strlen(key));
1146 return isMember(key.data(), key.data() + key.length());
1149 #ifdef JSON_USE_CPPTL
1151 return isMember(key.c_str(), key.end_c_str());
1158 "in Json::Value::getMemberNames(), value must be objectValue");
1162 members.reserve(value_.map_->size());
1163 ObjectValues::const_iterator it = value_.map_->begin();
1164 ObjectValues::const_iterator itEnd = value_.map_->end();
1165 for (; it != itEnd; ++it) {
1166 members.push_back(std::string((*it).first.data(),
1167 (*it).first.length()));
1198 double integral_part;
1199 return modf(d, &integral_part) == 0.0;
1213 return value_.real_ >=
minInt && value_.real_ <=
maxInt &&
1226 return value_.uint_ <=
maxUInt;
1228 return value_.real_ >= 0 && value_.real_ <=
maxUInt &&
1237 #if defined(JSON_HAS_INT64)
1247 return value_.real_ >= double(
minInt64) &&
1252 #endif // JSON_HAS_INT64
1257 #if defined(JSON_HAS_INT64)
1260 return value_.int_ >= 0;
1272 #endif // JSON_HAS_INT64
1277 #if defined(JSON_HAS_INT64)
1297 if ((len > 0) && (comment[len-1] ==
'\n')) {
1301 comments_[placement].setComment(comment, len);
1305 setComment(comment, strlen(comment), placement);
1309 setComment(comment.c_str(), comment.length(), placement);
1313 return comments_ != 0 && comments_[placement].comment_ != 0;
1318 return comments_[placement].comment_;
1332 return writer.
write(*
this);
1366 return iterator(value_.map_->begin());
1379 return iterator(value_.map_->end());
1393 : key_(), index_(index), kind_(kindIndex) {}
1396 : key_(key), index_(), kind_(kindKey) {}
1399 : key_(key.c_str()), index_(), kind_(kindKey) {}
1419 void Path::makePath(
const std::string& path,
const InArgs& in) {
1420 const char* current = path.c_str();
1421 const char* end = current + path.length();
1422 InArgs::const_iterator itInArg = in.begin();
1423 while (current != end) {
1424 if (*current ==
'[') {
1426 if (*current ==
'%')
1427 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1430 for (; current != end && *current >=
'0' && *current <=
'9'; ++current)
1431 index = index * 10 +
ArrayIndex(*current -
'0');
1432 args_.push_back(index);
1434 if (current == end || *current++ !=
']')
1435 invalidPath(path,
int(current - path.c_str()));
1436 }
else if (*current ==
'%') {
1437 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1439 }
else if (*current ==
'.') {
1442 const char* beginName = current;
1443 while (current != end && !strchr(
"[.", *current))
1445 args_.push_back(std::string(beginName, current));
1450 void Path::addPathInArg(
const std::string& ,
1452 InArgs::const_iterator& itInArg,
1453 PathArgument::Kind kind) {
1454 if (itInArg == in.end()) {
1456 }
else if ((*itInArg)->kind_ != kind) {
1459 args_.push_back(**itInArg);
1463 void Path::invalidPath(
const std::string& ,
int ) {
1468 const Value* node = &root;
1469 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1471 if (arg.kind_ == PathArgument::kindIndex) {
1475 node = &((*node)[arg.index_]);
1476 }
else if (arg.kind_ == PathArgument::kindKey) {
1480 node = &((*node)[arg.key_]);
1491 const Value* node = &root;
1492 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1494 if (arg.kind_ == PathArgument::kindIndex) {
1496 return defaultValue;
1497 node = &((*node)[arg.index_]);
1498 }
else if (arg.kind_ == PathArgument::kindKey) {
1500 return defaultValue;
1501 node = &((*node)[arg.key_]);
1503 return defaultValue;
1510 Value* node = &root;
1511 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1513 if (arg.kind_ == PathArgument::kindIndex) {
1517 node = &((*node)[arg.index_]);
1518 }
else if (arg.kind_ == PathArgument::kindKey) {
1522 node = &((*node)[arg.key_]);
const unsigned char & kNullRef
bool hasComment(CommentPlacement placement) const
Path(const std::string &path, const PathArgument &a1=PathArgument(), const PathArgument &a2=PathArgument(), const PathArgument &a3=PathArgument(), const PathArgument &a4=PathArgument(), const PathArgument &a5=PathArgument())
Writes a Value in JSON format in a human friendly way.
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
static bool IsIntegral(double d)
std::string asString() const
Embedded zeroes are possible.
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
static const Value & null
We regret this reference to a global instance; prefer the simpler Value().
std::vector< std::string > Members
array value (ordered list)
LargestUInt asLargestUInt() const
#define JSON_ASSERT_MESSAGE(condition, message)
#define ALIGNAS(byte_alignment)
void throwLogicError(std::string const &msg)
used internally
bool operator<(const Value &other) const
Compare payload only, not comments etc.
Json::ArrayIndex ArrayIndex
Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
int compare(const Value &other) const
object value (collection of name/value pairs).
void swapPayload(Value &other)
Swap values but leave comments and source offsets in place.
void setOffsetStart(size_t start)
RuntimeError(std::string const &msg)
bool removeIndex(ArrayIndex i, Value *removed)
Remove the indexed array element.
static const Int maxInt
Maximum signed int value that can be stored in a Json::Value.
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Lightweight wrapper to tag static string.
Value removeMember(const char *key)
Remove and return the named member.
#define JSON_ASSERT(condition)
It should not be possible for a maliciously designed file to cause an abort() or seg-fault, so these macros are used only for pre-condition violations and internal logic errors.
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
Json::LargestUInt LargestUInt
LogicError(std::string const &msg)
Value & operator=(Value other)
Deep copy, then swap(other).
const iterator for object and array value.
Value(ValueType type=nullValue)
Create a default Value of the given type.
Experimental and untested: represents an element of the "path" to access a node.
void setComment(const char *comment, CommentPlacement placement)
static bool InRange(double d, T min, U max)
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
bool isMember(const char *key) const
Return true if the object has a member named key.
static void decodePrefixedString(bool isPrefixed, char const *prefixed, unsigned *length, char const **value)
static const unsigned char kNull[sizeof(Value)]
static const Value & nullRef
just a kludge for binary-compatibility; same as null
Value & operator[](ArrayIndex index)
Access an array element (zero based index ).
size_t getOffsetLimit() const
ValueConstIterator const_iterator
std::string valueToString(Int value)
virtual std::string write(const Value &root)
Serialize a Value in JSON format.
Members getMemberNames() const
Return a list of the member names.
#define JSON_FAIL_MESSAGE(message)
void swap(Value &other)
Swap everything.
Json::LargestInt LargestInt
const char * c_str() const
static const double maxUInt64AsDouble
const char * asCString() const
Embedded zeroes could cause you trouble!
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
void throwRuntimeError(std::string const &msg)
used internally
bool operator>(const Value &other) const
Exception(std::string const &msg)
bool operator>=(const Value &other) const
bool operator==(const Value &other) const
const Value & resolve(const Value &root) const
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
Value & append(const Value &value)
Append value to array at the end.
ArrayIndex size() const
Number of values in array or object.
std::string toStyledString() const
static char * duplicateAndPrefixStringValue(const char *value, unsigned int length)
#define JSON_ASSERT_UNREACHABLE
bool isConvertibleTo(ValueType other) const
static char * duplicateStringValue(const char *value, size_t length)
Duplicates the specified string value.
void setOffsetLimit(size_t limit)
static const Int64 minInt64
Minimum signed 64 bits int value that can be stored in a Json::Value.
static const Int minInt
Minimum signed int value that can be stored in a Json::Value.
Exceptions which the user cannot easily avoid.
bool operator!() const
Return isNull()
LargestInt asLargestInt() const
Value const * find(char const *begin, char const *end) const
Most general and efficient version of isMember()const, get()const, and operator[]const.
void resize(ArrayIndex size)
Resize the array to size elements.
void clear()
Remove all object members and array elements.
Iterator for object and array value.
bool operator<=(const Value &other) const
static void releaseStringValue(char *value)
Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
ValueType
Type of the value held by a Value object.
Value get(ArrayIndex index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
size_t getOffsetStart() const
virtual char const * what() const
const_iterator begin() const
Base class for all exceptions we throw.
bool operator!=(const Value &other) const
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
const_iterator end() const
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.