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