6 #if !defined(JSON_IS_AMALGAMATION)
10 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
12 #endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
13 #endif // if !defined(JSON_IS_AMALGAMATION)
20 #include <cpptl/conststring.h>
24 #define JSON_ASSERT_UNREACHABLE assert(false)
31 #if defined(__ARMEL__)
32 #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)
57 static const unsigned int unknown = (unsigned)-1;
59 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
60 template <
typename T,
typename U>
61 static inline bool InRange(
double d, T min, U max) {
62 return d >= min && d <= max;
64 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
65 static inline double integerToDouble(
Json::UInt64 value) {
66 return static_cast<double>(
Int64(value / 2)) * 2.0 +
Int64(value & 1);
69 template <
typename T>
static inline double integerToDouble(T value) {
70 return static_cast<double>(value);
73 template <
typename T,
typename U>
74 static inline bool InRange(
double d, T min, U max) {
75 return d >= integerToDouble(min) && d <= integerToDouble(max);
77 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
87 unsigned int length =
unknown) {
89 length = (
unsigned int)strlen(value);
96 char* newString =
static_cast<char*
>(malloc(length + 1));
98 "in Json::Value::duplicateStringValue(): "
99 "Failed to allocate string value buffer");
100 memcpy(newString, value, length);
101 newString[length] = 0;
118 #if !defined(JSON_IS_AMALGAMATION)
119 #ifdef JSON_VALUE_USE_INTERNAL_MAP
122 #endif // JSON_VALUE_USE_INTERNAL_MAP
125 #endif // if !defined(JSON_IS_AMALGAMATION)
137 Value::CommentInfo::CommentInfo() : comment_(0) {}
139 Value::CommentInfo::~CommentInfo() {
144 void Value::CommentInfo::setComment(
const char* text) {
149 text[0] ==
'\0' || text[0] ==
'/',
150 "in Json::Value::setComment(): Comments must start with /");
162 #ifndef JSON_VALUE_USE_INTERNAL_MAP
167 Value::CZString::CZString(
ArrayIndex index) : cstr_(0), index_(index) {}
169 Value::CZString::CZString(
const char* cstr, DuplicationPolicy allocate)
173 Value::CZString::CZString(
const CZString& other)
174 : cstr_(other.index_ != noDuplication && other.cstr_ != 0
178 ? static_cast<
ArrayIndex>(other.index_ == noDuplication
179 ? noDuplication : duplicate)
182 Value::CZString::~CZString() {
183 if (cstr_ && index_ == duplicate)
187 void Value::CZString::swap(CZString& other) {
188 std::swap(cstr_, other.cstr_);
189 std::swap(index_, other.index_);
192 Value::CZString& Value::CZString::operator=(CZString other) {
197 bool Value::CZString::operator<(
const CZString& other)
const {
199 return strcmp(cstr_, other.cstr_) < 0;
200 return index_ < other.index_;
203 bool Value::CZString::operator==(
const CZString& other)
const {
205 return strcmp(cstr_, other.cstr_) == 0;
206 return index_ == other.index_;
209 ArrayIndex Value::CZString::index()
const {
return index_; }
211 const char* Value::CZString::c_str()
const {
return cstr_; }
213 bool Value::CZString::isStaticString()
const {
return index_ == noDuplication; }
215 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
244 #ifndef JSON_VALUE_USE_INTERNAL_MAP
247 value_.map_ =
new ObjectValues();
258 value_.bool_ =
false;
272 value_.uint_ = value;
274 #if defined(JSON_HAS_INT64)
281 value_.uint_ = value;
283 #endif // defined(JSON_HAS_INT64)
285 Value::Value(
double value) {
287 value_.real_ = value;
290 Value::Value(
const char* value) {
295 Value::Value(
const char* beginValue,
const char* endValue) {
301 Value::Value(
const std::string& value) {
309 value_.string_ =
const_cast<char*
>(value.
c_str());
312 #ifdef JSON_USE_CPPTL
313 Value::Value(
const CppTL::ConstString& value) {
319 Value::Value(
bool value) {
321 value_.bool_ = value;
325 : type_(other.type_), allocated_(false)
326 #ifdef JSON_VALUE_USE_INTERNAL_MAP
331 comments_(0), start_(other.start_), limit_(other.limit_) {
338 value_ = other.value_;
341 if (other.value_.string_) {
349 #ifndef JSON_VALUE_USE_INTERNAL_MAP
352 value_.map_ =
new ObjectValues(*other.value_.map_);
365 if (other.comments_) {
368 const CommentInfo& otherComment = other.comments_[comment];
369 if (otherComment.comment_)
370 comments_[comment].setComment(otherComment.comment_);
387 #ifndef JSON_VALUE_USE_INTERNAL_MAP
417 std::swap(value_, other.value_);
418 int temp2 = allocated_;
419 allocated_ = other.allocated_;
420 other.allocated_ = temp2;
421 std::swap(start_, other.start_);
422 std::swap(limit_, other.limit_);
436 int typeDelta = type_ - other.type_;
438 return typeDelta < 0 ?
true :
false;
443 return value_.int_ < other.value_.int_;
445 return value_.uint_ < other.value_.uint_;
447 return value_.real_ < other.value_.real_;
449 return value_.bool_ < other.value_.bool_;
451 return (value_.string_ == 0 && other.value_.string_) ||
452 (other.value_.string_ && value_.string_ &&
453 strcmp(value_.string_, other.value_.string_) < 0);
454 #ifndef JSON_VALUE_USE_INTERNAL_MAP
457 int delta = int(value_.map_->size() - other.value_.map_->size());
460 return (*value_.map_) < (*other.value_.map_);
464 return value_.array_->compare(*(other.value_.array_)) < 0;
466 return value_.map_->compare(*(other.value_.map_)) < 0;
485 int temp = other.type_;
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_;
500 return (value_.string_ == other.value_.string_) ||
501 (other.value_.string_ && value_.string_ &&
502 strcmp(value_.string_, other.value_.string_) == 0);
503 #ifndef JSON_VALUE_USE_INTERNAL_MAP
506 return value_.map_->size() == other.value_.map_->size() &&
507 (*value_.map_) == (*other.value_.map_);
510 return value_.array_->compare(*(other.value_.array_)) == 0;
512 return value_.map_->compare(*(other.value_.map_)) == 0;
524 "in Json::Value::asCString(): requires stringValue");
525 return value_.string_;
533 return value_.string_ ? value_.string_ :
"";
535 return value_.bool_ ?
"true" :
"false";
547 #ifdef JSON_USE_CPPTL
548 CppTL::ConstString Value::asConstString()
const {
549 return CppTL::ConstString(
asString().c_str());
557 return Int(value_.int_);
560 return Int(value_.uint_);
563 "double out of Int range");
564 return Int(value_.real_);
568 return value_.bool_ ? 1 : 0;
579 return UInt(value_.int_);
582 return UInt(value_.uint_);
585 "double out of UInt range");
586 return UInt(value_.real_);
590 return value_.bool_ ? 1 : 0;
597 #if defined(JSON_HAS_INT64)
602 return Int64(value_.int_);
605 return Int64(value_.uint_);
608 "double out of Int64 range");
609 return Int64(value_.real_);
613 return value_.bool_ ? 1 : 0;
624 return UInt64(value_.int_);
626 return UInt64(value_.uint_);
629 "double out of UInt64 range");
630 return UInt64(value_.real_);
634 return value_.bool_ ? 1 : 0;
640 #endif // if defined(JSON_HAS_INT64)
643 #if defined(JSON_NO_INT64)
651 #if defined(JSON_NO_INT64)
661 return static_cast<double>(value_.int_);
663 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
664 return static_cast<double>(value_.uint_);
665 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
666 return integerToDouble(value_.uint_);
667 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
673 return value_.bool_ ? 1.0 : 0.0;
683 return static_cast<float>(value_.int_);
685 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
686 return static_cast<float>(value_.uint_);
687 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
688 return integerToDouble(value_.uint_);
689 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
691 return static_cast<float>(value_.real_);
695 return value_.bool_ ? 1.0f : 0.0f;
709 return value_.int_ ?
true :
false;
711 return value_.uint_ ?
true :
false;
713 return value_.real_ ?
true :
false;
726 (type_ ==
arrayValue && value_.map_->size() == 0) ||
727 (type_ ==
objectValue && value_.map_->size() == 0) ||
763 #ifndef JSON_VALUE_USE_INTERNAL_MAP
765 if (!value_.map_->empty()) {
766 ObjectValues::const_iterator itLast = value_.map_->end();
768 return (*itLast).first.index() + 1;
775 return Int(value_.array_->size());
777 return Int(value_.map_->size());
796 "in Json::Value::clear(): requires complex value");
800 #ifndef JSON_VALUE_USE_INTERNAL_MAP
803 value_.map_->clear();
807 value_.array_->clear();
810 value_.map_->clear();
820 "in Json::Value::resize(): requires arrayValue");
823 #ifndef JSON_VALUE_USE_INTERNAL_MAP
827 else if (newSize > oldSize)
828 (*this)[newSize - 1];
830 for (
ArrayIndex index = newSize; index < oldSize; ++index) {
831 value_.map_->erase(index);
833 assert(
size() == newSize);
836 value_.array_->resize(newSize);
843 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
846 #ifndef JSON_VALUE_USE_INTERNAL_MAP
848 ObjectValues::iterator it = value_.map_->lower_bound(key);
849 if (it != value_.map_->end() && (*it).first == key)
852 ObjectValues::value_type defaultValue(key,
null);
853 it = value_.map_->insert(it, defaultValue);
856 return value_.array_->resolveReference(index);
863 "in Json::Value::operator[](int index): index cannot be negative");
870 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
873 #ifndef JSON_VALUE_USE_INTERNAL_MAP
875 ObjectValues::const_iterator it = value_.map_->find(key);
876 if (it == value_.map_->end())
880 Value* value = value_.array_->find(index);
881 return value ? *value :
null;
888 "in Json::Value::operator[](int index) const: index cannot be negative");
893 return resolveReference(key,
false);
896 void Value::initBasic(
ValueType type,
bool allocated) {
898 allocated_ = allocated;
899 #ifdef JSON_VALUE_USE_INTERNAL_MAP
907 Value& Value::resolveReference(
const char* key,
bool isStatic) {
910 "in Json::Value::resolveReference(): requires objectValue");
913 #ifndef JSON_VALUE_USE_INTERNAL_MAP
915 key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
916 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
917 if (it != value_.map_->end() && (*it).first == actualKey)
920 ObjectValues::value_type defaultValue(actualKey,
null);
921 it = value_.map_->insert(it, defaultValue);
922 Value& value = (*it).second;
925 return value_.map_->resolveReference(key, isStatic);
930 const Value* value = &((*this)[index]);
931 return value == &
null ? defaultValue : *value;
939 "in Json::Value::operator[](char const*)const: requires objectValue");
942 #ifndef JSON_VALUE_USE_INTERNAL_MAP
943 CZString actualKey(key, CZString::noDuplication);
944 ObjectValues::const_iterator it = value_.map_->find(actualKey);
945 if (it == value_.map_->end())
949 const Value* value = value_.map_->find(key);
950 return value ? *value :
null;
955 return (*
this)[key.c_str()];
959 return (*
this)[key.c_str()];
963 return resolveReference(key,
true);
966 #ifdef JSON_USE_CPPTL
968 return (*
this)[key.c_str()];
972 return (*
this)[key.c_str()];
979 const Value* value = &((*this)[key]);
980 return value == &
null ? defaultValue : *value;
984 return get(key.c_str(), defaultValue);
989 "in Json::Value::removeMember(): requires objectValue");
992 #ifndef JSON_VALUE_USE_INTERNAL_MAP
993 CZString actualKey(key, CZString::noDuplication);
994 ObjectValues::iterator it = value_.map_->find(actualKey);
995 if (it == value_.map_->end())
997 Value old(it->second);
998 value_.map_->erase(it);
1001 Value* value = value_.map_->find(key);
1004 value_.map_.remove(key);
1016 #ifdef JSON_USE_CPPTL
1018 const Value& defaultValue)
const {
1019 return get(key.c_str(), defaultValue);
1024 const Value* value = &((*this)[key]);
1025 return value != &
null;
1032 #ifdef JSON_USE_CPPTL
1041 "in Json::Value::getMemberNames(), value must be objectValue");
1045 members.reserve(value_.map_->size());
1046 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1047 ObjectValues::const_iterator it = value_.map_->begin();
1048 ObjectValues::const_iterator itEnd = value_.map_->end();
1049 for (; it != itEnd; ++it)
1050 members.push_back(std::string((*it).first.c_str()));
1052 ValueInternalMap::IteratorState it;
1053 ValueInternalMap::IteratorState itEnd;
1054 value_.map_->makeBeginIterator(it);
1055 value_.map_->makeEndIterator(itEnd);
1056 for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
1057 members.push_back(std::string(ValueInternalMap::key(it)));
1088 double integral_part;
1089 return modf(d, &integral_part) == 0.0;
1103 return value_.real_ >=
minInt && value_.real_ <=
maxInt &&
1116 return value_.uint_ <=
maxUInt;
1118 return value_.real_ >= 0 && value_.real_ <=
maxUInt &&
1127 #if defined(JSON_HAS_INT64)
1137 return value_.real_ >= double(
minInt64) &&
1142 #endif // JSON_HAS_INT64
1147 #if defined(JSON_HAS_INT64)
1150 return value_.int_ >= 0;
1162 #endif // JSON_HAS_INT64
1167 #if defined(JSON_HAS_INT64)
1187 comments_[placement].setComment(comment);
1195 return comments_ != 0 && comments_[placement].comment_ != 0;
1200 return comments_[placement].comment_;
1214 return writer.
write(*
this);
1219 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1221 if (value_.array_) {
1222 ValueInternalArray::IteratorState it;
1223 value_.array_->makeBeginIterator(it);
1229 ValueInternalMap::IteratorState it;
1230 value_.map_->makeBeginIterator(it);
1249 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1251 if (value_.array_) {
1252 ValueInternalArray::IteratorState it;
1253 value_.array_->makeEndIterator(it);
1259 ValueInternalMap::IteratorState it;
1260 value_.map_->makeEndIterator(it);
1279 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1281 if (value_.array_) {
1282 ValueInternalArray::IteratorState it;
1283 value_.array_->makeBeginIterator(it);
1289 ValueInternalMap::IteratorState it;
1290 value_.map_->makeBeginIterator(it);
1298 return iterator(value_.map_->begin());
1309 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1311 if (value_.array_) {
1312 ValueInternalArray::IteratorState it;
1313 value_.array_->makeEndIterator(it);
1319 ValueInternalMap::IteratorState it;
1320 value_.map_->makeEndIterator(it);
1328 return iterator(value_.map_->end());
1343 : key_(), index_(index), kind_(kindIndex) {}
1346 : key_(key), index_(), kind_(kindKey) {}
1349 : key_(key.c_str()), index_(), kind_(kindKey) {}
1369 void Path::makePath(
const std::string& path,
const InArgs&
in) {
1370 const char* current = path.c_str();
1371 const char* end = current + path.length();
1372 InArgs::const_iterator itInArg = in.begin();
1373 while (current != end) {
1374 if (*current ==
'[') {
1376 if (*current ==
'%')
1377 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1380 for (; current != end && *current >=
'0' && *current <=
'9'; ++current)
1381 index = index * 10 +
ArrayIndex(*current -
'0');
1382 args_.push_back(index);
1384 if (current == end || *current++ !=
']')
1385 invalidPath(path,
int(current - path.c_str()));
1386 }
else if (*current ==
'%') {
1387 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1389 }
else if (*current ==
'.') {
1392 const char* beginName = current;
1393 while (current != end && !strchr(
"[.", *current))
1395 args_.push_back(std::string(beginName, current));
1400 void Path::addPathInArg(
const std::string& ,
1402 InArgs::const_iterator& itInArg,
1403 PathArgument::Kind kind) {
1404 if (itInArg == in.end()) {
1406 }
else if ((*itInArg)->kind_ != kind) {
1409 args_.push_back(**itInArg);
1413 void Path::invalidPath(
const std::string& ,
int ) {
1418 const Value* node = &root;
1419 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1421 if (arg.kind_ == PathArgument::kindIndex) {
1425 node = &((*node)[arg.index_]);
1426 }
else if (arg.kind_ == PathArgument::kindKey) {
1430 node = &((*node)[arg.key_]);
1441 const Value* node = &root;
1442 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1444 if (arg.kind_ == PathArgument::kindIndex) {
1446 return defaultValue;
1447 node = &((*node)[arg.index_]);
1448 }
else if (arg.kind_ == PathArgument::kindKey) {
1450 return defaultValue;
1451 node = &((*node)[arg.key_]);
1453 return defaultValue;
1460 Value* node = &root;
1461 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1463 if (arg.kind_ == PathArgument::kindIndex) {
1467 node = &((*node)[arg.index_]);
1468 }
else if (arg.kind_ == PathArgument::kindKey) {
1472 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
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
static const Value & null
std::vector< std::string > Members
array value (ordered list)
static char * duplicateStringValue(const char *value, unsigned int length=unknown)
Duplicates the specified string value.
LargestUInt asLargestUInt() const
#define JSON_ASSERT_MESSAGE(condition, message)
#define ALIGNAS(byte_alignment)
bool operator<(const Value &other) const
Json::ArrayIndex ArrayIndex
int compare(const Value &other) const
object value (collection of name/value pairs).
void setOffsetStart(size_t start)
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)
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
Json::LargestUInt LargestUInt
Value & operator=(Value other)
static ValueArrayAllocator *& arrayAllocator()
virtual ValueInternalMap * newMap()=0
const iterator for object and array value.
virtual void destructArray(ValueInternalArray *array)=0
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)
Comments must be //... or /* ... */.
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.
virtual ValueInternalArray * newArray()=0
bool isMember(const char *key) const
Return true if the object has a member named key.
virtual ValueInternalArray * newArrayCopy(const ValueInternalArray &other)=0
static const unsigned char kNull[sizeof(Value)]
Value & operator[](ArrayIndex index)
Access an array element (zero based index ).
size_t getOffsetLimit() const
ValueConstIterator const_iterator
std::string valueToString(Int value)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
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 values.
Json::LargestInt LargestInt
const char * c_str() const
static const double maxUInt64AsDouble
const char * asCString() const
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
static const unsigned int unknown
Unknown size marker.
bool operator>(const Value &other) const
static ValueMapAllocator *& mapAllocator()
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
#define JSON_ASSERT_UNREACHABLE
bool isConvertibleTo(ValueType other) const
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.
bool operator!() const
Return isNull()
LargestInt asLargestInt() const
virtual ValueInternalMap * newMapCopy(const ValueInternalMap &other)=0
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
virtual void destructMap(ValueInternalMap *map)=0
static void releaseStringValue(char *value)
Free the string duplicated by duplicateStringValue().
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
const_iterator begin() const
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
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.