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