json test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers json_value.cpp Source File

json_value.cpp

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