JsonCpp project page JsonCpp home page

src/lib_json/json_value.cpp

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