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))) 34 #define ALIGNAS(byte_alignment) 43 #if defined(JSON_HAS_INT64) 51 #endif // defined(JSON_HAS_INT64) 56 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 57 template <
typename T,
typename U>
58 static inline bool InRange(
double d, T min, U max) {
59 return d >= min && d <= max;
61 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 62 static inline double integerToDouble(
Json::UInt64 value) {
63 return static_cast<double>(
Int64(value / 2)) * 2.0 +
Int64(value & 1);
66 template <
typename T>
static inline double integerToDouble(T value) {
67 return static_cast<double>(value);
70 template <
typename T,
typename U>
71 static inline bool InRange(
double d, T min, U max) {
72 return d >= integerToDouble(min) && d <= integerToDouble(max);
74 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 87 if (length >= (
size_t)Value::maxInt)
88 length = Value::maxInt - 1;
90 char* newString =
static_cast<char*
>(malloc(length + 1));
91 if (newString == NULL) {
93 "in Json::Value::duplicateStringValue(): " 94 "Failed to allocate string value buffer");
96 memcpy(newString, value, length);
97 newString[length] = 0;
110 "in Json::Value::duplicateAndPrefixStringValue(): " 111 "length too big for prefixing");
112 unsigned actualLength = length +
static_cast<unsigned>(
sizeof(unsigned)) + 1U;
113 char* newString =
static_cast<char*
>(malloc(actualLength));
114 if (newString == 0) {
116 "in Json::Value::duplicateAndPrefixStringValue(): " 117 "Failed to allocate string value buffer");
119 *
reinterpret_cast<unsigned*
>(newString) = length;
120 memcpy(newString +
sizeof(
unsigned), value, length);
121 newString[actualLength - 1U] = 0;
125 bool isPrefixed,
char const* prefixed,
126 unsigned* length,
char const** value)
129 *length =
static_cast<unsigned>(strlen(prefixed));
132 *length = *
reinterpret_cast<unsigned const*
>(prefixed);
133 *value = prefixed +
sizeof(unsigned);
149 #if !defined(JSON_IS_AMALGAMATION) 152 #endif // if !defined(JSON_IS_AMALGAMATION) 188 Value::CommentInfo::CommentInfo() : comment_(0) {}
190 Value::CommentInfo::~CommentInfo() {
195 void Value::CommentInfo::setComment(
const char* text,
size_t len) {
202 text[0] ==
'\0' || text[0] ==
'/',
203 "in Json::Value::setComment(): Comments must start with /");
219 Value::CZString::CZString(
ArrayIndex aindex) : cstr_(0), index_(aindex) {}
221 Value::CZString::CZString(
char const* str,
unsigned ulength, DuplicationPolicy allocate)
225 storage_.policy_ = allocate & 0x3;
226 storage_.length_ = ulength & 0x3FFFFFFF;
229 Value::CZString::CZString(
const CZString& other)
230 : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
234 storage_.policy_ = (other.cstr_
235 ? (
static_cast<DuplicationPolicy
>(other.storage_.policy_) == noDuplication
236 ? noDuplication : duplicate)
237 :
static_cast<DuplicationPolicy
>(other.storage_.policy_));
238 storage_.length_ = other.storage_.length_;
241 Value::CZString::~CZString() {
242 if (cstr_ && storage_.policy_ == duplicate)
246 void Value::CZString::swap(CZString& other) {
247 std::swap(cstr_, other.cstr_);
248 std::swap(index_, other.index_);
251 Value::CZString& Value::CZString::operator=(CZString other) {
256 bool Value::CZString::operator<(
const CZString& other)
const {
257 if (!cstr_)
return index_ < other.index_;
260 unsigned this_len = this->storage_.length_;
261 unsigned other_len = other.storage_.length_;
262 unsigned min_len = std::min(this_len, other_len);
263 int comp = memcmp(this->cstr_, other.cstr_, min_len);
264 if (comp < 0)
return true;
265 if (comp > 0)
return false;
266 return (this_len < other_len);
269 bool Value::CZString::operator==(
const CZString& other)
const {
270 if (!cstr_)
return index_ == other.index_;
273 unsigned this_len = this->storage_.length_;
274 unsigned other_len = other.storage_.length_;
275 if (this_len != other_len)
return false;
276 int comp = memcmp(this->cstr_, other.cstr_, this_len);
280 ArrayIndex Value::CZString::index()
const {
return index_; }
283 const char* Value::CZString::data()
const {
return cstr_; }
284 unsigned Value::CZString::length()
const {
return storage_.length_; }
285 bool Value::CZString::isStaticString()
const {
return storage_.policy_ == noDuplication; }
316 value_.map_ =
new ObjectValues();
319 value_.bool_ =
false;
333 value_.uint_ = value;
335 #if defined(JSON_HAS_INT64) 342 value_.uint_ = value;
344 #endif // defined(JSON_HAS_INT64) 348 value_.real_ = value;
370 value_.string_ =
const_cast<char*
>(value.
c_str());
373 #ifdef JSON_USE_CPPTL 382 value_.bool_ = value;
386 : type_(other.type_), allocated_(false)
396 value_ = other.value_;
399 if (other.value_.string_ && other.allocated_) {
407 value_.string_ = other.value_.string_;
413 value_.map_ =
new ObjectValues(*other.value_.map_);
418 if (other.comments_) {
421 const CommentInfo& otherComment = other.comments_[comment];
422 if (otherComment.comment_)
423 comments_[comment].setComment(
424 otherComment.comment_, strlen(otherComment.comment_));
463 std::swap(value_, other.value_);
464 int temp2 = allocated_;
465 allocated_ = other.allocated_;
466 other.allocated_ = temp2 & 0x1;
471 std::swap(comments_, other.comments_);
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");
877 value_.map_->clear();
886 "in Json::Value::resize(): requires arrayValue");
892 else if (newSize > oldSize)
893 (*this)[newSize - 1];
895 for (
ArrayIndex index = newSize; index < oldSize; ++index) {
896 value_.map_->erase(index);
898 assert(
size() == newSize);
905 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
909 ObjectValues::iterator it = value_.map_->lower_bound(key);
910 if (it != value_.map_->end() && (*it).first == key)
913 ObjectValues::value_type defaultValue(key,
nullRef);
914 it = value_.map_->insert(it, defaultValue);
921 "in Json::Value::operator[](int index): index cannot be negative");
928 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
932 ObjectValues::const_iterator it = value_.map_->find(key);
933 if (it == value_.map_->end())
941 "in Json::Value::operator[](int index) const: index cannot be negative");
945 void Value::initBasic(
ValueType vtype,
bool allocated) {
947 allocated_ = allocated;
954 Value& Value::resolveReference(
const char* key) {
957 "in Json::Value::resolveReference(): requires objectValue");
961 key, static_cast<unsigned>(strlen(key)), CZString::noDuplication);
962 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
963 if (it != value_.map_->end() && (*it).first == actualKey)
966 ObjectValues::value_type defaultValue(actualKey,
nullRef);
967 it = value_.map_->insert(it, defaultValue);
968 Value& value = (*it).second;
973 Value& Value::resolveReference(
char const* key,
char const* cend)
977 "in Json::Value::resolveReference(key, end): requires objectValue");
981 key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
982 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
983 if (it != value_.map_->end() && (*it).first == actualKey)
986 ObjectValues::value_type defaultValue(actualKey,
nullRef);
987 it = value_.map_->insert(it, defaultValue);
988 Value& value = (*it).second;
993 const Value* value = &((*this)[index]);
994 return value == &
nullRef ? defaultValue : *value;
1003 "in Json::Value::find(key, end, found): requires objectValue or nullValue");
1005 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1006 ObjectValues::const_iterator it = value_.map_->find(actualKey);
1007 if (it == value_.map_->end())
return NULL;
1008 return &(*it).second;
1012 Value const* found =
find(key, key + strlen(key));
1018 Value const* found =
find(key.data(), key.data() + key.length());
1024 return resolveReference(key, key + strlen(key));
1028 return resolveReference(key.data(), key.data() + key.length());
1032 return resolveReference(key.
c_str());
1035 #ifdef JSON_USE_CPPTL 1037 return resolveReference(key.c_str(), key.end_c_str());
1041 Value const* found =
find(key.c_str(), key.end_c_str());
1052 return !found ? defaultValue : *found;
1056 return get(key, key + strlen(key), defaultValue);
1060 return get(key.data(), key.data() + key.length(), defaultValue);
1069 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
1070 ObjectValues::iterator it = value_.map_->find(actualKey);
1071 if (it == value_.map_->end())
1073 *removed = it->second;
1074 value_.map_->erase(it);
1083 return removeMember(key.data(), key.data() + key.length(), removed);
1088 "in Json::Value::removeMember(): requires objectValue");
1105 CZString key(index);
1106 ObjectValues::iterator it = value_.map_->find(key);
1107 if (it == value_.map_->end()) {
1110 *removed = it->second;
1113 for (
ArrayIndex i = index; i < (oldSize - 1); ++i){
1115 (*value_.map_)[keey] = (*
this)[i + 1];
1118 CZString keyLast(oldSize - 1);
1119 ObjectValues::iterator itLast = value_.map_->find(keyLast);
1120 value_.map_->erase(itLast);
1124 #ifdef JSON_USE_CPPTL 1126 const Value& defaultValue)
const {
1127 return get(key.c_str(), key.end_c_str(), defaultValue);
1134 return NULL != value;
1138 return isMember(key, key + strlen(key));
1142 return isMember(key.data(), key.data() + key.length());
1145 #ifdef JSON_USE_CPPTL 1147 return isMember(key.c_str(), key.end_c_str());
1154 "in Json::Value::getMemberNames(), value must be objectValue");
1158 members.reserve(value_.map_->size());
1159 ObjectValues::const_iterator it = value_.map_->begin();
1160 ObjectValues::const_iterator itEnd = value_.map_->end();
1161 for (; it != itEnd; ++it) {
1162 members.push_back(std::string((*it).first.data(),
1163 (*it).first.length()));
1194 double integral_part;
1195 return modf(d, &integral_part) == 0.0;
1209 return value_.real_ >=
minInt && value_.real_ <=
maxInt &&
1222 return value_.uint_ <=
maxUInt;
1224 return value_.real_ >= 0 && value_.real_ <=
maxUInt &&
1233 #if defined(JSON_HAS_INT64) 1243 return value_.real_ >= double(
minInt64) &&
1248 #endif // JSON_HAS_INT64 1253 #if defined(JSON_HAS_INT64) 1256 return value_.int_ >= 0;
1263 return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1268 #endif // JSON_HAS_INT64 1273 #if defined(JSON_HAS_INT64) 1293 if ((len > 0) && (comment[len-1] ==
'\n')) {
1297 comments_[placement].setComment(comment, len);
1301 setComment(comment, strlen(comment), placement);
1305 setComment(comment.c_str(), comment.length(), placement);
1309 return comments_ != 0 && comments_[placement].comment_ != 0;
1314 return comments_[placement].comment_;
1320 return writer.
write(*
this);
1354 return iterator(value_.map_->begin());
1367 return iterator(value_.map_->end());
1381 : key_(), index_(index), kind_(kindIndex) {}
1384 : key_(key), index_(), kind_(kindKey) {}
1387 : key_(key.c_str()), index_(), kind_(kindKey) {}
1407 void Path::makePath(
const std::string& path,
const InArgs& in) {
1408 const char* current = path.c_str();
1409 const char* end = current + path.length();
1410 InArgs::const_iterator itInArg = in.begin();
1411 while (current != end) {
1412 if (*current ==
'[') {
1414 if (*current ==
'%')
1415 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1418 for (; current != end && *current >=
'0' && *current <=
'9'; ++current)
1419 index = index * 10 +
ArrayIndex(*current -
'0');
1420 args_.push_back(index);
1422 if (current == end || *current++ !=
']')
1423 invalidPath(path,
int(current - path.c_str()));
1424 }
else if (*current ==
'%') {
1425 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1427 }
else if (*current ==
'.') {
1430 const char* beginName = current;
1431 while (current != end && !strchr(
"[.", *current))
1433 args_.push_back(std::string(beginName, current));
1438 void Path::addPathInArg(
const std::string& ,
1440 InArgs::const_iterator& itInArg,
1441 PathArgument::Kind kind) {
1442 if (itInArg == in.end()) {
1444 }
else if ((*itInArg)->kind_ != kind) {
1447 args_.push_back(**itInArg);
1451 void Path::invalidPath(
const std::string& ,
int ) {
1456 const Value* node = &root;
1457 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1459 if (arg.kind_ == PathArgument::kindIndex) {
1463 node = &((*node)[arg.index_]);
1464 }
else if (arg.kind_ == PathArgument::kindKey) {
1468 node = &((*node)[arg.key_]);
1469 if (node == &Value::nullRef) {
1479 const Value* node = &root;
1480 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1482 if (arg.kind_ == PathArgument::kindIndex) {
1484 return defaultValue;
1485 node = &((*node)[arg.index_]);
1486 }
else if (arg.kind_ == PathArgument::kindKey) {
1488 return defaultValue;
1489 node = &((*node)[arg.key_]);
1490 if (node == &Value::nullRef)
1491 return defaultValue;
1498 Value* node = &root;
1499 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1501 if (arg.kind_ == PathArgument::kindIndex) {
1505 node = &((*node)[arg.index_]);
1506 }
else if (arg.kind_ == PathArgument::kindKey) {
1510 node = &((*node)[arg.key_]);
const unsigned char & kNullRef
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.
static bool IsIntegral(double d)
int compare(const Value &other) const
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
Value const * find(char const *begin, char const *end) const
Most general and efficient version of isMember()const, get()const, and operator[]const.
std::vector< std::string > Members
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
LargestUInt asLargestUInt() const
array value (ordered list)
#define JSON_ASSERT_MESSAGE(condition, message)
#define ALIGNAS(byte_alignment)
void throwLogicError(std::string const &msg)
used internally
Json::ArrayIndex ArrayIndex
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Members getMemberNames() const
Return a list of the member names.
object value (collection of name/value pairs).
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.
void swapPayload(Value &other)
Swap values but leave comments and source offsets in place.
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.
Lightweight wrapper to tag static string.
Value removeMember(const char *key)
Remove and return the named member.
std::string toStyledString() const
#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)
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)
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
static void decodePrefixedString(bool isPrefixed, char const *prefixed, unsigned *length, char const **value)
static const unsigned char kNull[sizeof(Value)]
static const Value & nullRef
Value & operator[](ArrayIndex index)
Access an array element (zero based index ).
ArrayIndex size() const
Number of values in array or object.
const char * asCString() const
Embedded zeroes could cause you trouble!
bool operator==(const Value &other) const
ValueConstIterator const_iterator
LargestInt asLargestInt() const
bool operator>(const Value &other) const
std::string valueToString(Int value)
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
std::string asString() const
Embedded zeroes are possible.
bool operator>=(const Value &other) const
virtual std::string write(const Value &root)
Serialize a Value in JSON format.
JSON (JavaScript Object Notation).
#define JSON_FAIL_MESSAGE(message)
void swap(Value &other)
Swap everything.
Json::LargestInt LargestInt
static const double maxUInt64AsDouble
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
const char * c_str() const
void throwRuntimeError(std::string const &msg)
used internally
Value get(ArrayIndex index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
const_iterator begin() const
Exception(std::string const &msg)
Value & append(const Value &value)
Append value to array at the end.
Value & operator=(const Value &other)
Deep copy, then swap(other).
static char * duplicateAndPrefixStringValue(const char *value, unsigned int length)
#define JSON_ASSERT_UNREACHABLE
static char * duplicateStringValue(const char *value, size_t length)
Duplicates the specified string value.
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 hasComment(CommentPlacement placement) const
void resize(ArrayIndex size)
Resize the array to size elements.
void clear()
Remove all object members and array elements.
bool operator!=(const Value &other) const
Iterator for object and array value.
bool isMember(const char *key) const
Return true if the object has a member named key.
static void releaseStringValue(char *value)
Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
ValueType
Type of the value held by a Value object.
bool operator<=(const Value &other) const
bool operator!() const
Return isNull()
const Value & resolve(const Value &root) const
bool isConvertibleTo(ValueType other) const
bool operator<(const Value &other) const
Compare payload only, not comments etc.
virtual char const * what() const
Base class for all exceptions we throw.
const_iterator end() const
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.