涂 桂旺
/
mbed-os-example-cj
json test
Embed:
(wiki syntax)
Show/hide line numbers
json_value.cpp
00001 // Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors 00002 // Distributed under MIT license, or public domain if desired and 00003 // recognized in your jurisdiction. 00004 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 00005 00006 #if !defined(JSON_IS_AMALGAMATION) 00007 #include <json/assertions.h> 00008 #include <json/value.h> 00009 #include <json/writer.h> 00010 #endif // if !defined(JSON_IS_AMALGAMATION) 00011 #include <math.h> 00012 #include <sstream> 00013 #include <utility> 00014 #include <cstring> 00015 #include <cassert> 00016 #ifdef JSON_USE_CPPTL 00017 #include <cpptl/conststring.h> 00018 #endif 00019 #include <cstddef> // size_t 00020 #include <algorithm> // min() 00021 00022 #define JSON_ASSERT_UNREACHABLE assert(false) 00023 using namespace std; 00024 namespace Json { 00025 00026 // This is a walkaround to avoid the static initialization of Value::null. 00027 // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of 00028 // 8 (instead of 4) as a bit of future-proofing. 00029 #if defined(__ARMEL__) 00030 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) 00031 #else 00032 #define ALIGNAS(byte_alignment) 00033 #endif 00034 //static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; 00035 //const unsigned char& kNullRef = kNull[0]; 00036 //const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); 00037 //const Value& Value::nullRef = null; 00038 00039 // static 00040 Value const& Value::nullSingleton() 00041 { 00042 static Value const nullStatic; 00043 return nullStatic; 00044 } 00045 00046 // for backwards compatibility, we'll leave these global references around, but DO NOT 00047 // use them in JSONCPP library code any more! 00048 Value const& Value::null = Value::nullSingleton(); 00049 Value const& Value::nullRef = Value::nullSingleton(); 00050 00051 const Int Value::minInt = Int(~(UInt(-1) / 2)); 00052 const Int Value::maxInt = Int(UInt(-1) / 2); 00053 const UInt Value::maxUInt = UInt(-1); 00054 #if defined(JSON_HAS_INT64) 00055 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); 00056 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); 00057 const UInt64 Value::maxUInt64 = UInt64(-1); 00058 // The constant is hard-coded because some compiler have trouble 00059 // converting Value::maxUInt64 to a double correctly (AIX/xlC). 00060 // Assumes that UInt64 is a 64 bits integer. 00061 static const double maxUInt64AsDouble = 18446744073709551615.0; 00062 #endif // defined(JSON_HAS_INT64) 00063 const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); 00064 const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); 00065 const LargestUInt Value::maxLargestUInt = LargestUInt(-1); 00066 00067 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00068 template <typename T, typename U> 00069 static inline bool InRange(double d, T min, U max) { 00070 // The casts can lose precision, but we are looking only for 00071 // an approximate range. Might fail on edge cases though. ~cdunn 00072 //return d >= static_cast<double>(min) && d <= static_cast<double>(max); 00073 return d >= min && d <= max; 00074 } 00075 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00076 static inline double integerToDouble(Json::UInt64 value) { 00077 return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1)); 00078 } 00079 00080 template <typename T> static inline double integerToDouble(T value) { 00081 return static_cast<double>(value); 00082 } 00083 00084 template <typename T, typename U> 00085 static inline bool InRange(double d, T min, U max) { 00086 return d >= integerToDouble(min) && d <= integerToDouble(max); 00087 } 00088 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00089 00090 /** Duplicates the specified string value. 00091 * @param value Pointer to the string to duplicate. Must be zero-terminated if 00092 * length is "unknown". 00093 * @param length Length of the value. if equals to unknown, then it will be 00094 * computed using strlen(value). 00095 * @return Pointer on the duplicate instance of string. 00096 */ 00097 static inline char* duplicateStringValue(const char* value, 00098 size_t length) 00099 { 00100 // Avoid an integer overflow in the call to malloc below by limiting length 00101 // to a sane value. 00102 if (length >= static_cast<size_t>(Value::maxInt)) 00103 length = Value::maxInt - 1; 00104 00105 char* newString = static_cast<char*>(malloc(length + 1)); 00106 if (newString == NULL) { 00107 throwRuntimeError( 00108 "in Json::Value::duplicateStringValue(): " 00109 "Failed to allocate string value buffer"); 00110 } 00111 memcpy(newString, value, length); 00112 newString[length] = 0; 00113 return newString; 00114 } 00115 00116 /* Record the length as a prefix. 00117 */ 00118 static inline char* duplicateAndPrefixStringValue( 00119 const char* value, 00120 unsigned int length) 00121 { 00122 // Avoid an integer overflow in the call to malloc below by limiting length 00123 // to a sane value. 00124 JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U, 00125 "in Json::Value::duplicateAndPrefixStringValue(): " 00126 "length too big for prefixing"); 00127 unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U; 00128 char* newString = static_cast<char*>(malloc(actualLength)); 00129 if (newString == 0) { 00130 throwRuntimeError( 00131 "in Json::Value::duplicateAndPrefixStringValue(): " 00132 "Failed to allocate string value buffer"); 00133 } 00134 *reinterpret_cast<unsigned*>(newString) = length; 00135 memcpy(newString + sizeof(unsigned), value, length); 00136 newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later 00137 return newString; 00138 } 00139 inline static void decodePrefixedString( 00140 bool isPrefixed, char const* prefixed, 00141 unsigned* length, char const** value) 00142 { 00143 if (!isPrefixed) { 00144 *length = static_cast<unsigned>(strlen(prefixed)); 00145 *value = prefixed; 00146 } else { 00147 *length = *reinterpret_cast<unsigned const*>(prefixed); 00148 *value = prefixed + sizeof(unsigned); 00149 } 00150 } 00151 /** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). 00152 */ 00153 #if JSONCPP_USING_SECURE_MEMORY 00154 static inline void releasePrefixedStringValue(char* value) { 00155 unsigned length = 0; 00156 char const* valueDecoded; 00157 decodePrefixedString(true, value, &length, &valueDecoded); 00158 size_t const size = sizeof(unsigned) + length + 1U; 00159 memset(value, 0, size); 00160 free(value); 00161 } 00162 static inline void releaseStringValue(char* value, unsigned length) { 00163 // length==0 => we allocated the strings memory 00164 size_t size = (length==0) ? strlen(value) : length; 00165 memset(value, 0, size); 00166 free(value); 00167 } 00168 #else // !JSONCPP_USING_SECURE_MEMORY 00169 static inline void releasePrefixedStringValue(char* value) { 00170 free(value); 00171 } 00172 static inline void releaseStringValue(char* value, unsigned) { 00173 free(value); 00174 } 00175 #endif // JSONCPP_USING_SECURE_MEMORY 00176 00177 } // namespace Json 00178 00179 // ////////////////////////////////////////////////////////////////// 00180 // ////////////////////////////////////////////////////////////////// 00181 // ////////////////////////////////////////////////////////////////// 00182 // ValueInternals... 00183 // ////////////////////////////////////////////////////////////////// 00184 // ////////////////////////////////////////////////////////////////// 00185 // ////////////////////////////////////////////////////////////////// 00186 #if !defined(JSON_IS_AMALGAMATION) 00187 00188 #include "json_valueiterator.inl" 00189 #endif // if !defined(JSON_IS_AMALGAMATION) 00190 00191 namespace Json { 00192 00193 Exception::Exception(JSONCPP_STRING const& msg) 00194 : msg_(msg) 00195 {} 00196 Exception::~Exception() JSONCPP_NOEXCEPT 00197 {} 00198 char const* Exception::what() const JSONCPP_NOEXCEPT 00199 { 00200 return msg_.c_str(); 00201 } 00202 RuntimeError::RuntimeError(JSONCPP_STRING const& msg) 00203 : Exception(msg) 00204 {} 00205 LogicError::LogicError(JSONCPP_STRING const& msg) 00206 : Exception(msg) 00207 {} 00208 JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) 00209 { 00210 //throw RuntimeError(msg); 00211 } 00212 JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) 00213 { 00214 //throw LogicError(msg); 00215 } 00216 00217 // ////////////////////////////////////////////////////////////////// 00218 // ////////////////////////////////////////////////////////////////// 00219 // ////////////////////////////////////////////////////////////////// 00220 // class Value::CommentInfo 00221 // ////////////////////////////////////////////////////////////////// 00222 // ////////////////////////////////////////////////////////////////// 00223 // ////////////////////////////////////////////////////////////////// 00224 00225 Value::CommentInfo::CommentInfo() : comment_(0) 00226 {} 00227 00228 Value::CommentInfo::~CommentInfo() { 00229 if (comment_) 00230 releaseStringValue(comment_, 0u); 00231 } 00232 00233 void Value::CommentInfo::setComment(const char* text, size_t len) { 00234 if (comment_) { 00235 releaseStringValue(comment_, 0u); 00236 comment_ = 0; 00237 } 00238 JSON_ASSERT(text != 0); 00239 JSON_ASSERT_MESSAGE( 00240 text[0] == '\0' || text[0] == '/', 00241 "in Json::Value::setComment(): Comments must start with /"); 00242 // It seems that /**/ style comments are acceptable as well. 00243 comment_ = duplicateStringValue(text, len); 00244 } 00245 00246 // ////////////////////////////////////////////////////////////////// 00247 // ////////////////////////////////////////////////////////////////// 00248 // ////////////////////////////////////////////////////////////////// 00249 // class Value::CZString 00250 // ////////////////////////////////////////////////////////////////// 00251 // ////////////////////////////////////////////////////////////////// 00252 // ////////////////////////////////////////////////////////////////// 00253 00254 // Notes: policy_ indicates if the string was allocated when 00255 // a string is stored. 00256 00257 Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {} 00258 00259 Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate) 00260 : cstr_(str) { 00261 // allocate != duplicate 00262 storage_.policy_ = allocate & 0x3; 00263 storage_.length_ = ulength & 0x3FFFFFFF; 00264 } 00265 00266 Value::CZString::CZString(const CZString& other) { 00267 cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 00268 ? duplicateStringValue(other.cstr_, other.storage_.length_) 00269 : other.cstr_); 00270 storage_.policy_ = static_cast<unsigned>(other.cstr_ 00271 ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication 00272 ? noDuplication : duplicate) 00273 : static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U; 00274 storage_.length_ = other.storage_.length_; 00275 } 00276 00277 #if JSON_HAS_RVALUE_REFERENCES 00278 Value::CZString::CZString(CZString&& other) 00279 : cstr_(other.cstr_), index_(other.index_) { 00280 other.cstr_ = nullptr; 00281 } 00282 #endif 00283 00284 Value::CZString::~CZString() { 00285 if (cstr_ && storage_.policy_ == duplicate) { 00286 releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary 00287 } 00288 } 00289 00290 void Value::CZString::swap(CZString& other) { 00291 std::swap(cstr_, other.cstr_); 00292 std::swap(index_, other.index_); 00293 } 00294 00295 Value::CZString& Value::CZString::operator=(const CZString& other) { 00296 cstr_ = other.cstr_; 00297 index_ = other.index_; 00298 return *this; 00299 } 00300 00301 #if JSON_HAS_RVALUE_REFERENCES 00302 Value::CZString& Value::CZString::operator=(CZString&& other) { 00303 cstr_ = other.cstr_; 00304 index_ = other.index_; 00305 other.cstr_ = nullptr; 00306 return *this; 00307 } 00308 #endif 00309 00310 bool Value::CZString::operator<(const CZString& other) const { 00311 if (!cstr_) return index_ < other.index_; 00312 //return strcmp(cstr_, other.cstr_) < 0; 00313 // Assume both are strings. 00314 unsigned this_len = this->storage_.length_; 00315 unsigned other_len = other.storage_.length_; 00316 unsigned min_len = std::min<unsigned>(this_len, other_len); 00317 JSON_ASSERT(this->cstr_ && other.cstr_); 00318 int comp = memcmp(this->cstr_, other.cstr_, min_len); 00319 if (comp < 0) return true; 00320 if (comp > 0) return false; 00321 return (this_len < other_len); 00322 } 00323 00324 bool Value::CZString::operator==(const CZString& other) const { 00325 if (!cstr_) return index_ == other.index_; 00326 //return strcmp(cstr_, other.cstr_) == 0; 00327 // Assume both are strings. 00328 unsigned this_len = this->storage_.length_; 00329 unsigned other_len = other.storage_.length_; 00330 if (this_len != other_len) return false; 00331 JSON_ASSERT(this->cstr_ && other.cstr_); 00332 int comp = memcmp(this->cstr_, other.cstr_, this_len); 00333 return comp == 0; 00334 } 00335 00336 ArrayIndex Value::CZString::index() const { return index_; } 00337 00338 //const char* Value::CZString::c_str() const { return cstr_; } 00339 const char* Value::CZString::data() const { return cstr_; } 00340 unsigned Value::CZString::length() const { return storage_.length_; } 00341 bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } 00342 00343 // ////////////////////////////////////////////////////////////////// 00344 // ////////////////////////////////////////////////////////////////// 00345 // ////////////////////////////////////////////////////////////////// 00346 // class Value::Value 00347 // ////////////////////////////////////////////////////////////////// 00348 // ////////////////////////////////////////////////////////////////// 00349 // ////////////////////////////////////////////////////////////////// 00350 00351 /*! \internal Default constructor initialization must be equivalent to: 00352 * memset( this, 0, sizeof(Value) ) 00353 * This optimization is used in ValueInternalMap fast allocator. 00354 */ 00355 Value::Value(ValueType vtype) { 00356 static char const emptyString[] = ""; 00357 initBasic(vtype); 00358 switch (vtype) { 00359 case nullValue: 00360 break; 00361 case intValue: 00362 case uintValue: 00363 value_.int_ = 0; 00364 break; 00365 case realValue: 00366 value_.real_ = 0.0; 00367 break; 00368 case stringValue: 00369 // allocated_ == false, so this is safe. 00370 value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString)); 00371 break; 00372 case arrayValue: 00373 case objectValue: 00374 value_.map_ = new ObjectValues(); 00375 break; 00376 case booleanValue: 00377 value_.bool_ = false; 00378 break; 00379 default: 00380 JSON_ASSERT_UNREACHABLE; 00381 } 00382 } 00383 00384 Value::Value(Int value) { 00385 initBasic(intValue); 00386 value_.int_ = value; 00387 } 00388 00389 Value::Value(UInt value) { 00390 initBasic(uintValue); 00391 value_.uint_ = value; 00392 } 00393 #if defined(JSON_HAS_INT64) 00394 Value::Value(Int64 value) { 00395 initBasic(intValue); 00396 value_.int_ = value; 00397 } 00398 Value::Value(UInt64 value) { 00399 initBasic(uintValue); 00400 value_.uint_ = value; 00401 } 00402 #endif // defined(JSON_HAS_INT64) 00403 00404 Value::Value(double value) { 00405 initBasic(realValue); 00406 value_.real_ = value; 00407 } 00408 00409 Value::Value(const char* value) { 00410 initBasic(stringValue, true); 00411 JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); 00412 value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value))); 00413 } 00414 00415 Value::Value(const char* beginValue, const char* endValue) { 00416 initBasic(stringValue, true); 00417 value_.string_ = 00418 duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue)); 00419 } 00420 00421 Value::Value(const JSONCPP_STRING& value) { 00422 initBasic(stringValue, true); 00423 value_.string_ = 00424 duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length())); 00425 } 00426 00427 Value::Value(const StaticString& value) { 00428 initBasic(stringValue); 00429 value_.string_ = const_cast<char*>(value.c_str()); 00430 } 00431 00432 #ifdef JSON_USE_CPPTL 00433 Value::Value(const CppTL::ConstString& value) { 00434 initBasic(stringValue, true); 00435 value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length())); 00436 } 00437 #endif 00438 00439 Value::Value(bool value) { 00440 initBasic(booleanValue); 00441 value_.bool_ = value; 00442 } 00443 00444 Value::Value(Value const& other) 00445 : type_(other.type_), allocated_(false) 00446 , 00447 comments_(0), start_(other.start_), limit_(other.limit_) 00448 { 00449 switch (type_) { 00450 case nullValue: 00451 case intValue: 00452 case uintValue: 00453 case realValue: 00454 case booleanValue: 00455 value_ = other.value_; 00456 break; 00457 case stringValue: 00458 if (other.value_.string_ && other.allocated_) { 00459 unsigned len; 00460 char const* str; 00461 decodePrefixedString(other.allocated_, other.value_.string_, 00462 &len, &str); 00463 value_.string_ = duplicateAndPrefixStringValue(str, len); 00464 allocated_ = true; 00465 } else { 00466 value_.string_ = other.value_.string_; 00467 allocated_ = false; 00468 } 00469 break; 00470 case arrayValue: 00471 case objectValue: 00472 value_.map_ = new ObjectValues(*other.value_.map_); 00473 break; 00474 default: 00475 JSON_ASSERT_UNREACHABLE; 00476 } 00477 if (other.comments_) { 00478 comments_ = new CommentInfo[numberOfCommentPlacement]; 00479 for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { 00480 const CommentInfo& otherComment = other.comments_[comment]; 00481 if (otherComment.comment_) 00482 comments_[comment].setComment( 00483 otherComment.comment_, strlen(otherComment.comment_)); 00484 } 00485 } 00486 } 00487 00488 #if JSON_HAS_RVALUE_REFERENCES 00489 // Move constructor 00490 Value::Value(Value&& other) { 00491 initBasic(nullValue); 00492 swap(other); 00493 } 00494 #endif 00495 00496 Value::~Value() { 00497 switch (type_) { 00498 case nullValue: 00499 case intValue: 00500 case uintValue: 00501 case realValue: 00502 case booleanValue: 00503 break; 00504 case stringValue: 00505 if (allocated_) 00506 releasePrefixedStringValue(value_.string_); 00507 break; 00508 case arrayValue: 00509 case objectValue: 00510 delete value_.map_; 00511 break; 00512 default: 00513 JSON_ASSERT_UNREACHABLE; 00514 } 00515 00516 delete[] comments_; 00517 00518 value_.uint_ = 0; 00519 } 00520 00521 Value& Value::operator=(Value other) { 00522 swap(other); 00523 return *this; 00524 } 00525 00526 void Value::swapPayload(Value& other) { 00527 ValueType temp = type_; 00528 type_ = other.type_; 00529 other.type_ = temp; 00530 std::swap(value_, other.value_); 00531 int temp2 = allocated_; 00532 allocated_ = other.allocated_; 00533 other.allocated_ = temp2 & 0x1; 00534 } 00535 00536 void Value::copyPayload(const Value& other) { 00537 type_ = other.type_; 00538 value_ = other.value_; 00539 allocated_ = other.allocated_; 00540 } 00541 00542 void Value::swap(Value& other) { 00543 swapPayload(other); 00544 std::swap(comments_, other.comments_); 00545 std::swap(start_, other.start_); 00546 std::swap(limit_, other.limit_); 00547 } 00548 00549 void Value::copy(const Value& other) { 00550 copyPayload(other); 00551 comments_ = other.comments_; 00552 start_ = other.start_; 00553 limit_ = other.limit_; 00554 } 00555 00556 ValueType Value::type() const { return type_; } 00557 00558 int Value::compare(const Value& other) const { 00559 if (*this < other) 00560 return -1; 00561 if (*this > other) 00562 return 1; 00563 return 0; 00564 } 00565 00566 bool Value::operator<(const Value& other) const { 00567 int typeDelta = type_ - other.type_; 00568 if (typeDelta) 00569 return typeDelta < 0 ? true : false; 00570 switch (type_) { 00571 case nullValue: 00572 return false; 00573 case intValue: 00574 return value_.int_ < other.value_.int_; 00575 case uintValue: 00576 return value_.uint_ < other.value_.uint_; 00577 case realValue: 00578 return value_.real_ < other.value_.real_; 00579 case booleanValue: 00580 return value_.bool_ < other.value_.bool_; 00581 case stringValue: 00582 { 00583 if ((value_.string_ == 0) || (other.value_.string_ == 0)) { 00584 if (other.value_.string_) return true; 00585 else return false; 00586 } 00587 unsigned this_len; 00588 unsigned other_len; 00589 char const* this_str; 00590 char const* other_str; 00591 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); 00592 decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); 00593 unsigned min_len = std::min<unsigned>(this_len, other_len); 00594 JSON_ASSERT(this_str && other_str); 00595 int comp = memcmp(this_str, other_str, min_len); 00596 if (comp < 0) return true; 00597 if (comp > 0) return false; 00598 return (this_len < other_len); 00599 } 00600 case arrayValue: 00601 case objectValue: { 00602 int delta = int(value_.map_->size() - other.value_.map_->size()); 00603 if (delta) 00604 return delta < 0; 00605 return (*value_.map_) < (*other.value_.map_); 00606 } 00607 default: 00608 JSON_ASSERT_UNREACHABLE; 00609 } 00610 return false; // unreachable 00611 } 00612 00613 bool Value::operator<=(const Value& other) const { return !(other < *this); } 00614 00615 bool Value::operator>=(const Value& other) const { return !(*this < other); } 00616 00617 bool Value::operator>(const Value& other) const { return other < *this; } 00618 00619 bool Value::operator==(const Value& other) const { 00620 // if ( type_ != other.type_ ) 00621 // GCC 2.95.3 says: 00622 // attempt to take address of bit-field structure member `Json::Value::type_' 00623 // Beats me, but a temp solves the problem. 00624 int temp = other.type_; 00625 if (type_ != temp) 00626 return false; 00627 switch (type_) { 00628 case nullValue: 00629 return true; 00630 case intValue: 00631 return value_.int_ == other.value_.int_; 00632 case uintValue: 00633 return value_.uint_ == other.value_.uint_; 00634 case realValue: 00635 return value_.real_ == other.value_.real_; 00636 case booleanValue: 00637 return value_.bool_ == other.value_.bool_; 00638 case stringValue: 00639 { 00640 if ((value_.string_ == 0) || (other.value_.string_ == 0)) { 00641 return (value_.string_ == other.value_.string_); 00642 } 00643 unsigned this_len; 00644 unsigned other_len; 00645 char const* this_str; 00646 char const* other_str; 00647 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); 00648 decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); 00649 if (this_len != other_len) return false; 00650 JSON_ASSERT(this_str && other_str); 00651 int comp = memcmp(this_str, other_str, this_len); 00652 return comp == 0; 00653 } 00654 case arrayValue: 00655 case objectValue: 00656 return value_.map_->size() == other.value_.map_->size() && 00657 (*value_.map_) == (*other.value_.map_); 00658 default: 00659 JSON_ASSERT_UNREACHABLE; 00660 } 00661 return false; // unreachable 00662 } 00663 00664 bool Value::operator!=(const Value& other) const { return !(*this == other); } 00665 00666 const char* Value::asCString() const { 00667 JSON_ASSERT_MESSAGE(type_ == stringValue, 00668 "in Json::Value::asCString(): requires stringValue"); 00669 if (value_.string_ == 0) return 0; 00670 unsigned this_len; 00671 char const* this_str; 00672 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); 00673 return this_str; 00674 } 00675 00676 #if JSONCPP_USING_SECURE_MEMORY 00677 unsigned Value::getCStringLength() const { 00678 JSON_ASSERT_MESSAGE(type_ == stringValue, 00679 "in Json::Value::asCString(): requires stringValue"); 00680 if (value_.string_ == 0) return 0; 00681 unsigned this_len; 00682 char const* this_str; 00683 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); 00684 return this_len; 00685 } 00686 #endif 00687 00688 bool Value::getString(char const** str, char const** cend) const { 00689 if (type_ != stringValue) return false; 00690 if (value_.string_ == 0) return false; 00691 unsigned length; 00692 decodePrefixedString(this->allocated_, this->value_.string_, &length, str); 00693 *cend = *str + length; 00694 return true; 00695 } 00696 00697 JSONCPP_STRING Value::asString() const { 00698 switch (type_) { 00699 case nullValue: 00700 return ""; 00701 case stringValue: 00702 { 00703 if (value_.string_ == 0) return ""; 00704 unsigned this_len; 00705 char const* this_str; 00706 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); 00707 return JSONCPP_STRING(this_str, this_len); 00708 } 00709 case booleanValue: 00710 return value_.bool_ ? "true" : "false"; 00711 case intValue: 00712 return valueToString(value_.int_); 00713 case uintValue: 00714 return valueToString(value_.uint_); 00715 case realValue: 00716 return valueToString(value_.real_); 00717 default: 00718 JSON_FAIL_MESSAGE("Type is not convertible to string"); 00719 } 00720 } 00721 00722 #ifdef JSON_USE_CPPTL 00723 CppTL::ConstString Value::asConstString() const { 00724 unsigned len; 00725 char const* str; 00726 decodePrefixedString(allocated_, value_.string_, 00727 &len, &str); 00728 return CppTL::ConstString(str, len); 00729 } 00730 #endif 00731 00732 Value::Int Value::asInt() const { 00733 switch (type_) { 00734 case intValue: 00735 JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); 00736 return Int(value_.int_); 00737 case uintValue: 00738 JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); 00739 return Int(value_.uint_); 00740 case realValue: 00741 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), 00742 "double out of Int range"); 00743 return Int(value_.real_); 00744 case nullValue: 00745 return 0; 00746 case booleanValue: 00747 return value_.bool_ ? 1 : 0; 00748 default: 00749 break; 00750 } 00751 JSON_FAIL_MESSAGE("Value is not convertible to Int."); 00752 } 00753 00754 Value::UInt Value::asUInt() const { 00755 switch (type_) { 00756 case intValue: 00757 JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); 00758 return UInt(value_.int_); 00759 case uintValue: 00760 JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); 00761 return UInt(value_.uint_); 00762 case realValue: 00763 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), 00764 "double out of UInt range"); 00765 return UInt(value_.real_); 00766 case nullValue: 00767 return 0; 00768 case booleanValue: 00769 return value_.bool_ ? 1 : 0; 00770 default: 00771 break; 00772 } 00773 JSON_FAIL_MESSAGE("Value is not convertible to UInt."); 00774 } 00775 00776 #if defined(JSON_HAS_INT64) 00777 00778 Value::Int64 Value::asInt64() const { 00779 switch (type_) { 00780 case intValue: 00781 return Int64(value_.int_); 00782 case uintValue: 00783 JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); 00784 return Int64(value_.uint_); 00785 case realValue: 00786 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), 00787 "double out of Int64 range"); 00788 return Int64(value_.real_); 00789 case nullValue: 00790 return 0; 00791 case booleanValue: 00792 return value_.bool_ ? 1 : 0; 00793 default: 00794 break; 00795 } 00796 JSON_FAIL_MESSAGE("Value is not convertible to Int64."); 00797 } 00798 00799 Value::UInt64 Value::asUInt64() const { 00800 switch (type_) { 00801 case intValue: 00802 JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); 00803 return UInt64(value_.int_); 00804 case uintValue: 00805 return UInt64(value_.uint_); 00806 case realValue: 00807 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), 00808 "double out of UInt64 range"); 00809 return UInt64(value_.real_); 00810 case nullValue: 00811 return 0; 00812 case booleanValue: 00813 return value_.bool_ ? 1 : 0; 00814 default: 00815 break; 00816 } 00817 JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); 00818 } 00819 #endif // if defined(JSON_HAS_INT64) 00820 00821 LargestInt Value::asLargestInt() const { 00822 #if defined(JSON_NO_INT64) 00823 return asInt(); 00824 #else 00825 return asInt64(); 00826 #endif 00827 } 00828 00829 LargestUInt Value::asLargestUInt() const { 00830 #if defined(JSON_NO_INT64) 00831 return asUInt(); 00832 #else 00833 return asUInt64(); 00834 #endif 00835 } 00836 00837 double Value::asDouble() const { 00838 switch (type_) { 00839 case intValue: 00840 return static_cast<double>(value_.int_); 00841 case uintValue: 00842 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00843 return static_cast<double>(value_.uint_); 00844 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00845 return integerToDouble(value_.uint_); 00846 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00847 case realValue: 00848 return value_.real_; 00849 case nullValue: 00850 return 0.0; 00851 case booleanValue: 00852 return value_.bool_ ? 1.0 : 0.0; 00853 default: 00854 break; 00855 } 00856 JSON_FAIL_MESSAGE("Value is not convertible to double."); 00857 } 00858 00859 float Value::asFloat() const { 00860 switch (type_) { 00861 case intValue: 00862 return static_cast<float>(value_.int_); 00863 case uintValue: 00864 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00865 return static_cast<float>(value_.uint_); 00866 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00867 // This can fail (silently?) if the value is bigger than MAX_FLOAT. 00868 return static_cast<float>(integerToDouble(value_.uint_)); 00869 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 00870 case realValue: 00871 return static_cast<float>(value_.real_); 00872 case nullValue: 00873 return 0.0; 00874 case booleanValue: 00875 return value_.bool_ ? 1.0f : 0.0f; 00876 default: 00877 break; 00878 } 00879 JSON_FAIL_MESSAGE("Value is not convertible to float."); 00880 } 00881 00882 bool Value::asBool() const { 00883 switch (type_) { 00884 case booleanValue: 00885 return value_.bool_; 00886 case nullValue: 00887 return false; 00888 case intValue: 00889 return value_.int_ ? true : false; 00890 case uintValue: 00891 return value_.uint_ ? true : false; 00892 case realValue: 00893 // This is kind of strange. Not recommended. 00894 return (value_.real_ != 0.0) ? true : false; 00895 default: 00896 break; 00897 } 00898 JSON_FAIL_MESSAGE("Value is not convertible to bool."); 00899 } 00900 00901 bool Value::isConvertibleTo(ValueType other) const { 00902 switch (other) { 00903 case nullValue: 00904 return (isNumeric() && asDouble() == 0.0) || 00905 (type_ == booleanValue && value_.bool_ == false) || 00906 (type_ == stringValue && asString().empty()) || 00907 (type_ == arrayValue && value_.map_->size() == 0) || 00908 (type_ == objectValue && value_.map_->size() == 0) || 00909 type_ == nullValue; 00910 case intValue: 00911 return isInt() || 00912 (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || 00913 type_ == booleanValue || type_ == nullValue; 00914 case uintValue: 00915 return isUInt() || 00916 (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || 00917 type_ == booleanValue || type_ == nullValue; 00918 case realValue: 00919 return isNumeric() || type_ == booleanValue || type_ == nullValue; 00920 case booleanValue: 00921 return isNumeric() || type_ == booleanValue || type_ == nullValue; 00922 case stringValue: 00923 return isNumeric() || type_ == booleanValue || type_ == stringValue || 00924 type_ == nullValue; 00925 case arrayValue: 00926 return type_ == arrayValue || type_ == nullValue; 00927 case objectValue: 00928 return type_ == objectValue || type_ == nullValue; 00929 } 00930 JSON_ASSERT_UNREACHABLE; 00931 return false; 00932 } 00933 00934 /// Number of values in array or object 00935 ArrayIndex Value::size() const { 00936 switch (type_) { 00937 case nullValue: 00938 case intValue: 00939 case uintValue: 00940 case realValue: 00941 case booleanValue: 00942 case stringValue: 00943 return 0; 00944 case arrayValue: // size of the array is highest index + 1 00945 if (!value_.map_->empty()) { 00946 ObjectValues::const_iterator itLast = value_.map_->end(); 00947 --itLast; 00948 return (*itLast).first.index() + 1; 00949 } 00950 return 0; 00951 case objectValue: 00952 return ArrayIndex(value_.map_->size()); 00953 } 00954 JSON_ASSERT_UNREACHABLE; 00955 return 0; // unreachable; 00956 } 00957 00958 bool Value::empty() const { 00959 if (isNull() || isArray() || isObject()) 00960 return size() == 0u; 00961 else 00962 return false; 00963 } 00964 00965 Value::operator bool() const { return ! isNull(); } 00966 00967 void Value::clear() { 00968 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || 00969 type_ == objectValue, 00970 "in Json::Value::clear(): requires complex value"); 00971 start_ = 0; 00972 limit_ = 0; 00973 switch (type_) { 00974 case arrayValue: 00975 case objectValue: 00976 value_.map_->clear(); 00977 break; 00978 default: 00979 break; 00980 } 00981 } 00982 00983 void Value::resize(ArrayIndex newSize) { 00984 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, 00985 "in Json::Value::resize(): requires arrayValue"); 00986 if (type_ == nullValue) 00987 *this = Value(arrayValue); 00988 ArrayIndex oldSize = size(); 00989 if (newSize == 0) 00990 clear(); 00991 else if (newSize > oldSize) 00992 (*this)[newSize - 1]; 00993 else { 00994 for (ArrayIndex index = newSize; index < oldSize; ++index) { 00995 value_.map_->erase(index); 00996 } 00997 JSON_ASSERT(size() == newSize); 00998 } 00999 } 01000 01001 Value& Value::operator[](ArrayIndex index) { 01002 JSON_ASSERT_MESSAGE( 01003 type_ == nullValue || type_ == arrayValue, 01004 "in Json::Value::operator[](ArrayIndex): requires arrayValue"); 01005 if (type_ == nullValue) 01006 *this = Value(arrayValue); 01007 CZString key(index); 01008 ObjectValues::iterator it = value_.map_->lower_bound(key); 01009 if (it != value_.map_->end() && (*it).first == key) 01010 return (*it).second; 01011 01012 ObjectValues::value_type defaultValue(key, nullSingleton()); 01013 it = value_.map_->insert(it, defaultValue); 01014 return (*it).second; 01015 } 01016 01017 Value& Value::operator[](int index) { 01018 JSON_ASSERT_MESSAGE( 01019 index >= 0, 01020 "in Json::Value::operator[](int index): index cannot be negative"); 01021 return (*this)[ArrayIndex(index)]; 01022 } 01023 01024 const Value& Value::operator[](ArrayIndex index) const { 01025 JSON_ASSERT_MESSAGE( 01026 type_ == nullValue || type_ == arrayValue, 01027 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); 01028 if (type_ == nullValue) 01029 return nullSingleton(); 01030 CZString key(index); 01031 ObjectValues::const_iterator it = value_.map_->find(key); 01032 if (it == value_.map_->end()) 01033 return nullSingleton(); 01034 return (*it).second; 01035 } 01036 01037 const Value& Value::operator[](int index) const { 01038 JSON_ASSERT_MESSAGE( 01039 index >= 0, 01040 "in Json::Value::operator[](int index) const: index cannot be negative"); 01041 return (*this)[ArrayIndex(index)]; 01042 } 01043 01044 void Value::initBasic(ValueType vtype, bool allocated) { 01045 type_ = vtype; 01046 allocated_ = allocated; 01047 comments_ = 0; 01048 start_ = 0; 01049 limit_ = 0; 01050 } 01051 01052 // Access an object value by name, create a null member if it does not exist. 01053 // @pre Type of '*this' is object or null. 01054 // @param key is null-terminated. 01055 Value& Value::resolveReference(const char* key) { 01056 JSON_ASSERT_MESSAGE( 01057 type_ == nullValue || type_ == objectValue, 01058 "in Json::Value::resolveReference(): requires objectValue"); 01059 if (type_ == nullValue) 01060 *this = Value(objectValue); 01061 CZString actualKey( 01062 key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE! 01063 ObjectValues::iterator it = value_.map_->lower_bound(actualKey); 01064 if (it != value_.map_->end() && (*it).first == actualKey) 01065 return (*it).second; 01066 01067 ObjectValues::value_type defaultValue(actualKey, nullSingleton()); 01068 it = value_.map_->insert(it, defaultValue); 01069 Value& value = (*it).second; 01070 return value; 01071 } 01072 01073 // @param key is not null-terminated. 01074 Value& Value::resolveReference(char const* key, char const* cend) 01075 { 01076 JSON_ASSERT_MESSAGE( 01077 type_ == nullValue || type_ == objectValue, 01078 "in Json::Value::resolveReference(key, end): requires objectValue"); 01079 if (type_ == nullValue) 01080 *this = Value(objectValue); 01081 CZString actualKey( 01082 key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy); 01083 ObjectValues::iterator it = value_.map_->lower_bound(actualKey); 01084 if (it != value_.map_->end() && (*it).first == actualKey) 01085 return (*it).second; 01086 01087 ObjectValues::value_type defaultValue(actualKey, nullSingleton()); 01088 it = value_.map_->insert(it, defaultValue); 01089 Value& value = (*it).second; 01090 return value; 01091 } 01092 01093 Value Value::get(ArrayIndex index, const Value& defaultValue) const { 01094 const Value* value = &((*this)[index]); 01095 return value == &nullSingleton() ? defaultValue : *value; 01096 } 01097 01098 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } 01099 01100 Value const* Value::find(char const* key, char const* cend) const 01101 { 01102 JSON_ASSERT_MESSAGE( 01103 type_ == nullValue || type_ == objectValue, 01104 "in Json::Value::find(key, end, found): requires objectValue or nullValue"); 01105 if (type_ == nullValue) return NULL; 01106 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); 01107 ObjectValues::const_iterator it = value_.map_->find(actualKey); 01108 if (it == value_.map_->end()) return NULL; 01109 return &(*it).second; 01110 } 01111 const Value& Value::operator[](const char* key) const 01112 { 01113 Value const* found = find(key, key + strlen(key)); 01114 if (!found) return nullSingleton(); 01115 return *found; 01116 } 01117 Value const& Value::operator[](JSONCPP_STRING const& key) const 01118 { 01119 Value const* found = find(key.data(), key.data() + key.length()); 01120 if (!found) return nullSingleton(); 01121 return *found; 01122 } 01123 01124 Value& Value::operator[](const char* key) { 01125 return resolveReference(key, key + strlen(key)); 01126 } 01127 01128 Value& Value::operator[](const JSONCPP_STRING& key) { 01129 return resolveReference(key.data(), key.data() + key.length()); 01130 } 01131 01132 Value& Value::operator[](const StaticString& key) { 01133 return resolveReference(key.c_str()); 01134 } 01135 01136 #ifdef JSON_USE_CPPTL 01137 Value& Value::operator[](const CppTL::ConstString& key) { 01138 return resolveReference(key.c_str(), key.end_c_str()); 01139 } 01140 Value const& Value::operator[](CppTL::ConstString const& key) const 01141 { 01142 Value const* found = find(key.c_str(), key.end_c_str()); 01143 if (!found) return nullSingleton(); 01144 return *found; 01145 } 01146 #endif 01147 01148 Value& Value::append(const Value& value) { return (*this)[size()] = value; } 01149 01150 #if JSON_HAS_RVALUE_REFERENCES 01151 Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); } 01152 #endif 01153 01154 Value Value::get(char const* key, char const* cend, Value const& defaultValue) const 01155 { 01156 Value const* found = find(key, cend); 01157 return !found ? defaultValue : *found; 01158 } 01159 Value Value::get(char const* key, Value const& defaultValue) const 01160 { 01161 return get(key, key + strlen(key), defaultValue); 01162 } 01163 Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const 01164 { 01165 return get(key.data(), key.data() + key.length(), defaultValue); 01166 } 01167 01168 01169 bool Value::removeMember(const char* key, const char* cend, Value* removed) 01170 { 01171 if (type_ != objectValue) { 01172 return false; 01173 } 01174 CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); 01175 ObjectValues::iterator it = value_.map_->find(actualKey); 01176 if (it == value_.map_->end()) 01177 return false; 01178 *removed = it->second; 01179 value_.map_->erase(it); 01180 return true; 01181 } 01182 bool Value::removeMember(const char* key, Value* removed) 01183 { 01184 return removeMember(key, key + strlen(key), removed); 01185 } 01186 bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) 01187 { 01188 return removeMember(key.data(), key.data() + key.length(), removed); 01189 } 01190 void Value::removeMember(const char* key) 01191 { 01192 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, 01193 "in Json::Value::removeMember(): requires objectValue"); 01194 if (type_ == nullValue) 01195 return; 01196 01197 CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); 01198 value_.map_->erase(actualKey); 01199 } 01200 void Value::removeMember(const JSONCPP_STRING& key) 01201 { 01202 removeMember(key.c_str()); 01203 } 01204 01205 bool Value::removeIndex(ArrayIndex index, Value* removed) { 01206 if (type_ != arrayValue) { 01207 return false; 01208 } 01209 CZString key(index); 01210 ObjectValues::iterator it = value_.map_->find(key); 01211 if (it == value_.map_->end()) { 01212 return false; 01213 } 01214 *removed = it->second; 01215 ArrayIndex oldSize = size(); 01216 // shift left all items left, into the place of the "removed" 01217 for (ArrayIndex i = index; i < (oldSize - 1); ++i){ 01218 CZString keey(i); 01219 (*value_.map_)[keey] = (*this)[i + 1]; 01220 } 01221 // erase the last one ("leftover") 01222 CZString keyLast(oldSize - 1); 01223 ObjectValues::iterator itLast = value_.map_->find(keyLast); 01224 value_.map_->erase(itLast); 01225 return true; 01226 } 01227 01228 #ifdef JSON_USE_CPPTL 01229 Value Value::get(const CppTL::ConstString& key, 01230 const Value& defaultValue) const { 01231 return get(key.c_str(), key.end_c_str(), defaultValue); 01232 } 01233 #endif 01234 01235 bool Value::isMember(char const* key, char const* cend) const 01236 { 01237 Value const* value = find(key, cend); 01238 return NULL != value; 01239 } 01240 bool Value::isMember(char const* key) const 01241 { 01242 return isMember(key, key + strlen(key)); 01243 } 01244 bool Value::isMember(JSONCPP_STRING const& key) const 01245 { 01246 return isMember(key.data(), key.data() + key.length()); 01247 } 01248 01249 #ifdef JSON_USE_CPPTL 01250 bool Value::isMember(const CppTL::ConstString& key) const { 01251 return isMember(key.c_str(), key.end_c_str()); 01252 } 01253 #endif 01254 01255 Value::Members Value::getMemberNames() const { 01256 JSON_ASSERT_MESSAGE( 01257 type_ == nullValue || type_ == objectValue, 01258 "in Json::Value::getMemberNames(), value must be objectValue"); 01259 if (type_ == nullValue) 01260 return Value::Members(); 01261 Members members; 01262 members.reserve(value_.map_->size()); 01263 ObjectValues::const_iterator it = value_.map_->begin(); 01264 ObjectValues::const_iterator itEnd = value_.map_->end(); 01265 for (; it != itEnd; ++it) { 01266 members.push_back(JSONCPP_STRING((*it).first.data(), 01267 (*it).first.length())); 01268 } 01269 return members; 01270 } 01271 // 01272 //# ifdef JSON_USE_CPPTL 01273 // EnumMemberNames 01274 // Value::enumMemberNames() const 01275 //{ 01276 // if ( type_ == objectValue ) 01277 // { 01278 // return CppTL::Enum::any( CppTL::Enum::transform( 01279 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), 01280 // MemberNamesTransform() ) ); 01281 // } 01282 // return EnumMemberNames(); 01283 //} 01284 // 01285 // 01286 // EnumValues 01287 // Value::enumValues() const 01288 //{ 01289 // if ( type_ == objectValue || type_ == arrayValue ) 01290 // return CppTL::Enum::anyValues( *(value_.map_), 01291 // CppTL::Type<const Value &>() ); 01292 // return EnumValues(); 01293 //} 01294 // 01295 //# endif 01296 01297 static bool IsIntegral(double d) { 01298 double integral_part; 01299 return modf(d, &integral_part) == 0.0; 01300 } 01301 01302 bool Value::isNull() const { return type_ == nullValue; } 01303 01304 bool Value::isBool() const { return type_ == booleanValue; } 01305 01306 bool Value::isInt() const { 01307 switch (type_) { 01308 case intValue: 01309 #if defined(JSON_HAS_INT64) 01310 return value_.int_ >= minInt && value_.int_ <= maxInt; 01311 #else 01312 return true; 01313 #endif 01314 case uintValue: 01315 return value_.uint_ <= UInt(maxInt); 01316 case realValue: 01317 return value_.real_ >= minInt && value_.real_ <= maxInt && 01318 IsIntegral(value_.real_); 01319 default: 01320 break; 01321 } 01322 return false; 01323 } 01324 01325 bool Value::isUInt() const { 01326 switch (type_) { 01327 case intValue: 01328 #if defined(JSON_HAS_INT64) 01329 return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); 01330 #else 01331 return value_.int_ >= 0; 01332 #endif 01333 case uintValue: 01334 #if defined(JSON_HAS_INT64) 01335 return value_.uint_ <= maxUInt; 01336 #else 01337 return true; 01338 #endif 01339 case realValue: 01340 return value_.real_ >= 0 && value_.real_ <= maxUInt && 01341 IsIntegral(value_.real_); 01342 default: 01343 break; 01344 } 01345 return false; 01346 } 01347 01348 bool Value::isInt64() const { 01349 #if defined(JSON_HAS_INT64) 01350 switch (type_) { 01351 case intValue: 01352 return true; 01353 case uintValue: 01354 return value_.uint_ <= UInt64(maxInt64); 01355 case realValue: 01356 // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a 01357 // double, so double(maxInt64) will be rounded up to 2^63. Therefore we 01358 // require the value to be strictly less than the limit. 01359 return value_.real_ >= double(minInt64) && 01360 value_.real_ < double(maxInt64) && IsIntegral(value_.real_); 01361 default: 01362 break; 01363 } 01364 #endif // JSON_HAS_INT64 01365 return false; 01366 } 01367 01368 bool Value::isUInt64() const { 01369 #if defined(JSON_HAS_INT64) 01370 switch (type_) { 01371 case intValue: 01372 return value_.int_ >= 0; 01373 case uintValue: 01374 return true; 01375 case realValue: 01376 // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a 01377 // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we 01378 // require the value to be strictly less than the limit. 01379 return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && 01380 IsIntegral(value_.real_); 01381 default: 01382 break; 01383 } 01384 #endif // JSON_HAS_INT64 01385 return false; 01386 } 01387 01388 bool Value::isIntegral() const { 01389 switch (type_) { 01390 case intValue: 01391 case uintValue: 01392 return true; 01393 case realValue: 01394 #if defined(JSON_HAS_INT64) 01395 // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a 01396 // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we 01397 // require the value to be strictly less than the limit. 01398 return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); 01399 #else 01400 return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_); 01401 #endif // JSON_HAS_INT64 01402 default: 01403 break; 01404 } 01405 return false; 01406 } 01407 01408 bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; } 01409 01410 bool Value::isNumeric() const { return isDouble(); } 01411 01412 bool Value::isString() const { return type_ == stringValue; } 01413 01414 bool Value::isArray() const { return type_ == arrayValue; } 01415 01416 bool Value::isObject() const { return type_ == objectValue; } 01417 01418 void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { 01419 if (!comments_) 01420 comments_ = new CommentInfo[numberOfCommentPlacement]; 01421 if ((len > 0) && (comment[len-1] == '\n')) { 01422 // Always discard trailing newline, to aid indentation. 01423 len -= 1; 01424 } 01425 comments_[placement].setComment(comment, len); 01426 } 01427 01428 void Value::setComment(const char* comment, CommentPlacement placement) { 01429 setComment(comment, strlen(comment), placement); 01430 } 01431 01432 void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) { 01433 setComment(comment.c_str(), comment.length(), placement); 01434 } 01435 01436 bool Value::hasComment(CommentPlacement placement) const { 01437 return comments_ != 0 && comments_[placement].comment_ != 0; 01438 } 01439 01440 JSONCPP_STRING Value::getComment(CommentPlacement placement) const { 01441 if (hasComment(placement)) 01442 return comments_[placement].comment_; 01443 return ""; 01444 } 01445 01446 void Value::setOffsetStart(ptrdiff_t start) { start_ = start; } 01447 01448 void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; } 01449 01450 ptrdiff_t Value::getOffsetStart() const { return start_; } 01451 01452 ptrdiff_t Value::getOffsetLimit() const { return limit_; } 01453 01454 JSONCPP_STRING Value::toStyledString() const { 01455 StreamWriterBuilder builder; 01456 01457 JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : ""; 01458 out += Json::writeString(builder, *this); 01459 out += "\n"; 01460 01461 return out; 01462 } 01463 01464 Value::const_iterator Value::begin() const { 01465 switch (type_) { 01466 case arrayValue: 01467 case objectValue: 01468 if (value_.map_) 01469 return const_iterator(value_.map_->begin()); 01470 break; 01471 default: 01472 break; 01473 } 01474 return const_iterator(); 01475 } 01476 01477 Value::const_iterator Value::end() const { 01478 switch (type_) { 01479 case arrayValue: 01480 case objectValue: 01481 if (value_.map_) 01482 return const_iterator(value_.map_->end()); 01483 break; 01484 default: 01485 break; 01486 } 01487 return const_iterator(); 01488 } 01489 01490 Value::iterator Value::begin() { 01491 switch (type_) { 01492 case arrayValue: 01493 case objectValue: 01494 if (value_.map_) 01495 return iterator(value_.map_->begin()); 01496 break; 01497 default: 01498 break; 01499 } 01500 return iterator(); 01501 } 01502 01503 Value::iterator Value::end() { 01504 switch (type_) { 01505 case arrayValue: 01506 case objectValue: 01507 if (value_.map_) 01508 return iterator(value_.map_->end()); 01509 break; 01510 default: 01511 break; 01512 } 01513 return iterator(); 01514 } 01515 01516 // class PathArgument 01517 // ////////////////////////////////////////////////////////////////// 01518 01519 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} 01520 01521 PathArgument::PathArgument(ArrayIndex index) 01522 : key_(), index_(index), kind_(kindIndex) {} 01523 01524 PathArgument::PathArgument(const char* key) 01525 : key_(key), index_(), kind_(kindKey) {} 01526 01527 PathArgument::PathArgument(const JSONCPP_STRING& key) 01528 : key_(key.c_str()), index_(), kind_(kindKey) {} 01529 01530 // class Path 01531 // ////////////////////////////////////////////////////////////////// 01532 01533 Path::Path(const JSONCPP_STRING& path, 01534 const PathArgument& a1, 01535 const PathArgument& a2, 01536 const PathArgument& a3, 01537 const PathArgument& a4, 01538 const PathArgument& a5) { 01539 InArgs in; 01540 in.reserve(5); 01541 in.push_back(&a1); 01542 in.push_back(&a2); 01543 in.push_back(&a3); 01544 in.push_back(&a4); 01545 in.push_back(&a5); 01546 makePath(path, in); 01547 } 01548 01549 void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { 01550 const char* current = path.c_str(); 01551 const char* end = current + path.length(); 01552 InArgs::const_iterator itInArg = in.begin(); 01553 while (current != end) { 01554 if (*current == '[') { 01555 ++current; 01556 if (*current == '%') 01557 addPathInArg(path, in, itInArg, PathArgument::kindIndex); 01558 else { 01559 ArrayIndex index = 0; 01560 for (; current != end && *current >= '0' && *current <= '9'; ++current) 01561 index = index * 10 + ArrayIndex(*current - '0'); 01562 args_.push_back(index); 01563 } 01564 if (current == end || *++current != ']') 01565 invalidPath(path, int(current - path.c_str())); 01566 } else if (*current == '%') { 01567 addPathInArg(path, in, itInArg, PathArgument::kindKey); 01568 ++current; 01569 } else if (*current == '.' || *current == ']') { 01570 ++current; 01571 } else { 01572 const char* beginName = current; 01573 while (current != end && !strchr("[.", *current)) 01574 ++current; 01575 args_.push_back(JSONCPP_STRING(beginName, current)); 01576 } 01577 } 01578 } 01579 01580 void Path::addPathInArg(const JSONCPP_STRING& /*path*/, 01581 const InArgs& in, 01582 InArgs::const_iterator& itInArg, 01583 PathArgument::Kind kind) { 01584 if (itInArg == in.end()) { 01585 // Error: missing argument %d 01586 } else if ((*itInArg)->kind_ != kind) { 01587 // Error: bad argument type 01588 } else { 01589 args_.push_back(**itInArg++); 01590 } 01591 } 01592 01593 void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) { 01594 // Error: invalid path. 01595 } 01596 01597 const Value& Path::resolve(const Value& root) const { 01598 const Value* node = &root; 01599 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { 01600 const PathArgument& arg = *it; 01601 if (arg.kind_ == PathArgument::kindIndex) { 01602 if (!node->isArray() || !node->isValidIndex(arg.index_)) { 01603 // Error: unable to resolve path (array value expected at position... 01604 return Value::null; 01605 } 01606 node = &((*node)[arg.index_]); 01607 } else if (arg.kind_ == PathArgument::kindKey) { 01608 if (!node->isObject()) { 01609 // Error: unable to resolve path (object value expected at position...) 01610 return Value::null; 01611 } 01612 node = &((*node)[arg.key_]); 01613 if (node == &Value::nullSingleton()) { 01614 // Error: unable to resolve path (object has no member named '' at 01615 // position...) 01616 return Value::null; 01617 } 01618 } 01619 } 01620 return *node; 01621 } 01622 01623 Value Path::resolve(const Value& root, const Value& defaultValue) const { 01624 const Value* node = &root; 01625 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { 01626 const PathArgument& arg = *it; 01627 if (arg.kind_ == PathArgument::kindIndex) { 01628 if (!node->isArray() || !node->isValidIndex(arg.index_)) 01629 return defaultValue; 01630 node = &((*node)[arg.index_]); 01631 } else if (arg.kind_ == PathArgument::kindKey) { 01632 if (!node->isObject()) 01633 return defaultValue; 01634 node = &((*node)[arg.key_]); 01635 if (node == &Value::nullSingleton()) 01636 return defaultValue; 01637 } 01638 } 01639 return *node; 01640 } 01641 01642 Value& Path::make(Value& root) const { 01643 Value* node = &root; 01644 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { 01645 const PathArgument& arg = *it; 01646 if (arg.kind_ == PathArgument::kindIndex) { 01647 if (!node->isArray()) { 01648 // Error: node is not an array at position ... 01649 } 01650 node = &((*node)[arg.index_]); 01651 } else if (arg.kind_ == PathArgument::kindKey) { 01652 if (!node->isObject()) { 01653 // Error: node is not an object at position... 01654 } 01655 node = &((*node)[arg.key_]); 01656 } 01657 } 01658 return *node; 01659 } 01660 01661 } // namespace Json
Generated on Tue Jul 12 2022 21:24:54 by 1.7.2