$extrastylesheet
JsonCpp project page Classes Namespace JsonCpp home page

include/json/value.h
Go to the documentation of this file.
00001 // Copyright 2007-2010 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 #ifndef CPPTL_JSON_H_INCLUDED
00007 #define CPPTL_JSON_H_INCLUDED
00008 
00009 #if !defined(JSON_IS_AMALGAMATION)
00010 #include "forwards.h"
00011 #endif // if !defined(JSON_IS_AMALGAMATION)
00012 #include <string>
00013 #include <vector>
00014 #include <exception>
00015 
00016 #ifndef JSON_USE_CPPTL_SMALLMAP
00017 #include <map>
00018 #else
00019 #include <cpptl/smallmap.h>
00020 #endif
00021 #ifdef JSON_USE_CPPTL
00022 #include <cpptl/forwards.h>
00023 #endif
00024 
00025 //Conditional NORETURN attribute on the throw functions would:
00026 // a) suppress false positives from static code analysis
00027 // b) possibly improve optimization opportunities.
00028 #if !defined(JSONCPP_NORETURN)
00029 #  if defined(_MSC_VER)
00030 #    define JSONCPP_NORETURN __declspec(noreturn)
00031 #  elif defined(__GNUC__)
00032 #    define JSONCPP_NORETURN __attribute__ ((__noreturn__))
00033 #  else
00034 #    define JSONCPP_NORETURN
00035 #  endif
00036 #endif
00037 
00038 // Disable warning C4251: <data member>: <type> needs to have dll-interface to
00039 // be used by...
00040 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00041 #pragma warning(push)
00042 #pragma warning(disable : 4251)
00043 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00044 
00045 #pragma pack(push, 8)
00046 
00049 namespace Json {
00050 
00055 class JSON_API Exception : public std::exception {
00056 public:
00057   Exception(JSONCPP_STRING const& msg);
00058   ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
00059   char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
00060 protected:
00061   JSONCPP_STRING msg_;
00062 };
00063 
00070 class JSON_API RuntimeError : public Exception {
00071 public:
00072   RuntimeError(JSONCPP_STRING const& msg);
00073 };
00074 
00081 class JSON_API LogicError : public Exception {
00082 public:
00083   LogicError(JSONCPP_STRING const& msg);
00084 };
00085 
00087 JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
00089 JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
00090 
00093 enum ValueType {
00094   nullValue = 0, 
00095   intValue,      
00096   uintValue,     
00097   realValue,     
00098   stringValue,   
00099   booleanValue,  
00100   arrayValue,    
00101   objectValue    
00102 };
00103 
00104 enum CommentPlacement {
00105   commentBefore = 0,      
00106   commentAfterOnSameLine, 
00107   commentAfter, 
00108 
00109   numberOfCommentPlacement
00110 };
00111 
00112 //# ifdef JSON_USE_CPPTL
00113 //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
00114 //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
00115 //# endif
00116 
00131 class JSON_API StaticString {
00132 public:
00133   explicit StaticString(const char* czstring) : c_str_(czstring) {}
00134 
00135   operator const char*() const { return c_str_; }
00136 
00137   const char* c_str() const { return c_str_; }
00138 
00139 private:
00140   const char* c_str_;
00141 };
00142 
00177 class JSON_API Value {
00178   friend class ValueIteratorBase;
00179 public:
00180   typedef std::vector<JSONCPP_STRING> Members;
00181   typedef ValueIterator iterator;
00182   typedef ValueConstIterator const_iterator;
00183   typedef Json::UInt UInt;
00184   typedef Json::Int Int;
00185 #if defined(JSON_HAS_INT64)
00186   typedef Json::UInt64 UInt64;
00187   typedef Json::Int64 Int64;
00188 #endif // defined(JSON_HAS_INT64)
00189   typedef Json::LargestInt LargestInt;
00190   typedef Json::LargestUInt LargestUInt;
00191   typedef Json::ArrayIndex ArrayIndex;
00192 
00193   // Required for boost integration, e. g. BOOST_TEST
00194   typedef std::string value_type;
00195 
00196   static const Value& null;  
00197   static const Value& nullRef;  
00198   static Value const& nullSingleton(); 
00199 
00201   static const LargestInt minLargestInt;
00203   static const LargestInt maxLargestInt;
00205   static const LargestUInt maxLargestUInt;
00206 
00208   static const Int minInt;
00210   static const Int maxInt;
00212   static const UInt maxUInt;
00213 
00214 #if defined(JSON_HAS_INT64)
00215 
00216   static const Int64 minInt64;
00218   static const Int64 maxInt64;
00220   static const UInt64 maxUInt64;
00221 #endif // defined(JSON_HAS_INT64)
00222 
00223 private:
00224 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00225   class CZString {
00226   public:
00227     enum DuplicationPolicy {
00228       noDuplication = 0,
00229       duplicate,
00230       duplicateOnCopy
00231     };
00232     CZString(ArrayIndex index);
00233     CZString(char const* str, unsigned length, DuplicationPolicy allocate);
00234     CZString(CZString const& other);
00235 #if JSON_HAS_RVALUE_REFERENCES
00236     CZString(CZString&& other);
00237 #endif
00238     ~CZString();
00239     CZString& operator=(const CZString& other);
00240 
00241 #if JSON_HAS_RVALUE_REFERENCES
00242     CZString& operator=(CZString&& other);
00243 #endif
00244 
00245     bool operator<(CZString const& other) const;
00246     bool operator==(CZString const& other) const;
00247     ArrayIndex index() const;
00248     //const char* c_str() const; ///< \deprecated
00249     char const* data() const;
00250     unsigned length() const;
00251     bool isStaticString() const;
00252 
00253   private:
00254     void swap(CZString& other);
00255 
00256     struct StringStorage {
00257       unsigned policy_: 2;
00258       unsigned length_: 30; // 1GB max
00259     };
00260 
00261     char const* cstr_;  // actually, a prefixed string, unless policy is noDup
00262     union {
00263       ArrayIndex index_;
00264       StringStorage storage_;
00265     };
00266   };
00267 
00268 public:
00269 #ifndef JSON_USE_CPPTL_SMALLMAP
00270   typedef std::map<CZString, Value> ObjectValues;
00271 #else
00272   typedef CppTL::SmallMap<CZString, Value> ObjectValues;
00273 #endif // ifndef JSON_USE_CPPTL_SMALLMAP
00274 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00275 
00276 public:
00292   Value(ValueType type = nullValue);
00293   Value(Int value);
00294   Value(UInt value);
00295 #if defined(JSON_HAS_INT64)
00296   Value(Int64 value);
00297   Value(UInt64 value);
00298 #endif // if defined(JSON_HAS_INT64)
00299   Value(double value);
00300   Value(const char* value); 
00301   Value(const char* begin, const char* end); 
00302 
00317   Value(const StaticString& value);
00318   Value(const JSONCPP_STRING& value); 
00319 #ifdef JSON_USE_CPPTL
00320   Value(const CppTL::ConstString& value);
00321 #endif
00322   Value(bool value);
00324   Value(const Value& other);
00325 #if JSON_HAS_RVALUE_REFERENCES
00326 
00327   Value(Value&& other);
00328 #endif
00329   ~Value();
00330 
00333   Value& operator=(Value other);
00334 
00336   void swap(Value& other);
00338   void swapPayload(Value& other);
00339 
00341   void copy(const Value& other);
00343   void copyPayload(const Value& other);
00344 
00345   ValueType type() const;
00346 
00348   bool operator<(const Value& other) const;
00349   bool operator<=(const Value& other) const;
00350   bool operator>=(const Value& other) const;
00351   bool operator>(const Value& other) const;
00352   bool operator==(const Value& other) const;
00353   bool operator!=(const Value& other) const;
00354   int compare(const Value& other) const;
00355 
00356   const char* asCString() const; 
00357 #if JSONCPP_USING_SECURE_MEMORY
00358   unsigned getCStringLength() const; //Allows you to understand the length of the CString
00359 #endif
00360   JSONCPP_STRING asString() const; 
00361 
00364   bool getString(
00365       char const** begin, char const** end) const;
00366 #ifdef JSON_USE_CPPTL
00367   CppTL::ConstString asConstString() const;
00368 #endif
00369   Int asInt() const;
00370   UInt asUInt() const;
00371 #if defined(JSON_HAS_INT64)
00372   Int64 asInt64() const;
00373   UInt64 asUInt64() const;
00374 #endif // if defined(JSON_HAS_INT64)
00375   LargestInt asLargestInt() const;
00376   LargestUInt asLargestUInt() const;
00377   float asFloat() const;
00378   double asDouble() const;
00379   bool asBool() const;
00380 
00381   bool isNull() const;
00382   bool isBool() const;
00383   bool isInt() const;
00384   bool isInt64() const;
00385   bool isUInt() const;
00386   bool isUInt64() const;
00387   bool isIntegral() const;
00388   bool isDouble() const;
00389   bool isNumeric() const;
00390   bool isString() const;
00391   bool isArray() const;
00392   bool isObject() const;
00393 
00394   bool isConvertibleTo(ValueType other) const;
00395 
00397   ArrayIndex size() const;
00398 
00401   bool empty() const;
00402 
00404   explicit operator bool() const;
00405 
00409   void clear();
00410 
00416   void resize(ArrayIndex size);
00417 
00424   Value& operator[](ArrayIndex index);
00425 
00432   Value& operator[](int index);
00433 
00437   const Value& operator[](ArrayIndex index) const;
00438 
00442   const Value& operator[](int index) const;
00443 
00447   Value get(ArrayIndex index, const Value& defaultValue) const;
00449   bool isValidIndex(ArrayIndex index) const;
00453   Value& append(const Value& value);
00454 
00455 #if JSON_HAS_RVALUE_REFERENCES
00456   Value& append(Value&& value);
00457 #endif
00458 
00462   Value& operator[](const char* key);
00465   const Value& operator[](const char* key) const;
00468   Value& operator[](const JSONCPP_STRING& key);
00472   const Value& operator[](const JSONCPP_STRING& key) const;
00485   Value& operator[](const StaticString& key);
00486 #ifdef JSON_USE_CPPTL
00487 
00488   Value& operator[](const CppTL::ConstString& key);
00491   const Value& operator[](const CppTL::ConstString& key) const;
00492 #endif
00493 
00494 
00495   Value get(const char* key, const Value& defaultValue) const;
00499   Value get(const char* begin, const char* end, const Value& defaultValue) const;
00503   Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
00504 #ifdef JSON_USE_CPPTL
00505 
00506 
00507   Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
00508 #endif
00509 
00510 
00511 
00512   Value const* find(char const* begin, char const* end) const;
00516   Value const* demand(char const* begin, char const* end);
00524   void removeMember(const char* key);
00528   void removeMember(const JSONCPP_STRING& key);
00531   bool removeMember(const char* key, Value* removed);
00538   bool removeMember(JSONCPP_STRING const& key, Value* removed);
00540   bool removeMember(const char* begin, const char* end, Value* removed);
00547   bool removeIndex(ArrayIndex i, Value* removed);
00548 
00551   bool isMember(const char* key) const;
00554   bool isMember(const JSONCPP_STRING& key) const;
00556   bool isMember(const char* begin, const char* end) const;
00557 #ifdef JSON_USE_CPPTL
00558 
00559   bool isMember(const CppTL::ConstString& key) const;
00560 #endif
00561 
00567   Members getMemberNames() const;
00568 
00569   //# ifdef JSON_USE_CPPTL
00570   //      EnumMemberNames enumMemberNames() const;
00571   //      EnumValues enumValues() const;
00572   //# endif
00573 
00575   JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
00576   void setComment(const char* comment, CommentPlacement placement);
00578   void setComment(const char* comment, size_t len, CommentPlacement placement);
00580   void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
00581   bool hasComment(CommentPlacement placement) const;
00583   JSONCPP_STRING getComment(CommentPlacement placement) const;
00584 
00585   JSONCPP_STRING toStyledString() const;
00586 
00587   const_iterator begin() const;
00588   const_iterator end() const;
00589 
00590   iterator begin();
00591   iterator end();
00592 
00593   // Accessors for the [start, limit) range of bytes within the JSON text from
00594   // which this value was parsed, if any.
00595   void setOffsetStart(ptrdiff_t start);
00596   void setOffsetLimit(ptrdiff_t limit);
00597   ptrdiff_t getOffsetStart() const;
00598   ptrdiff_t getOffsetLimit() const;
00599 
00600 private:
00601   void initBasic(ValueType type, bool allocated = false);
00602 
00603   Value& resolveReference(const char* key);
00604   Value& resolveReference(const char* key, const char* end);
00605 
00606   struct CommentInfo {
00607     CommentInfo();
00608     ~CommentInfo();
00609 
00610     void setComment(const char* text, size_t len);
00611 
00612     char* comment_;
00613   };
00614 
00615   // struct MemberNamesTransform
00616   //{
00617   //   typedef const char *result_type;
00618   //   const char *operator()( const CZString &name ) const
00619   //   {
00620   //      return name.c_str();
00621   //   }
00622   //};
00623 
00624   union ValueHolder {
00625     LargestInt int_;
00626     LargestUInt uint_;
00627     double real_;
00628     bool bool_;
00629     char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
00630     ObjectValues* map_;
00631   } value_;
00632   ValueType type_ : 8;
00633   unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
00634                                // If not allocated_, string_ must be null-terminated.
00635   CommentInfo* comments_;
00636 
00637   // [start, limit) byte offsets in the source JSON text from which this Value
00638   // was extracted.
00639   ptrdiff_t start_;
00640   ptrdiff_t limit_;
00641 };
00642 
00646 class JSON_API PathArgument {
00647 public:
00648   friend class Path;
00649 
00650   PathArgument();
00651   PathArgument(ArrayIndex index);
00652   PathArgument(const char* key);
00653   PathArgument(const JSONCPP_STRING& key);
00654 
00655 private:
00656   enum Kind {
00657     kindNone = 0,
00658     kindIndex,
00659     kindKey
00660   };
00661   JSONCPP_STRING key_;
00662   ArrayIndex index_;
00663   Kind kind_;
00664 };
00665 
00677 class JSON_API Path {
00678 public:
00679   Path(const JSONCPP_STRING& path,
00680        const PathArgument& a1 = PathArgument(),
00681        const PathArgument& a2 = PathArgument(),
00682        const PathArgument& a3 = PathArgument(),
00683        const PathArgument& a4 = PathArgument(),
00684        const PathArgument& a5 = PathArgument());
00685 
00686   const Value& resolve(const Value& root) const;
00687   Value resolve(const Value& root, const Value& defaultValue) const;
00690   Value& make(Value& root) const;
00691 
00692 private:
00693   typedef std::vector<const PathArgument*> InArgs;
00694   typedef std::vector<PathArgument> Args;
00695 
00696   void makePath(const JSONCPP_STRING& path, const InArgs& in);
00697   void addPathInArg(const JSONCPP_STRING& path,
00698                     const InArgs& in,
00699                     InArgs::const_iterator& itInArg,
00700                     PathArgument::Kind kind);
00701   void invalidPath(const JSONCPP_STRING& path, int location);
00702 
00703   Args args_;
00704 };
00705 
00709 class JSON_API ValueIteratorBase {
00710 public:
00711   typedef std::bidirectional_iterator_tag iterator_category;
00712   typedef unsigned int size_t;
00713   typedef int difference_type;
00714   typedef ValueIteratorBase SelfType;
00715 
00716   bool operator==(const SelfType& other) const { return isEqual(other); }
00717 
00718   bool operator!=(const SelfType& other) const { return !isEqual(other); }
00719 
00720   difference_type operator-(const SelfType& other) const {
00721     return other.computeDistance(*this);
00722   }
00723 
00726   Value key() const;
00727 
00729   UInt index() const;
00730 
00734   JSONCPP_STRING name() const;
00735 
00739   JSONCPP_DEPRECATED("Use `key = name();` instead.")
00740   char const* memberName() const;
00744   char const* memberName(char const** end) const;
00745 
00746 protected:
00747   Value& deref() const;
00748 
00749   void increment();
00750 
00751   void decrement();
00752 
00753   difference_type computeDistance(const SelfType& other) const;
00754 
00755   bool isEqual(const SelfType& other) const;
00756 
00757   void copy(const SelfType& other);
00758 
00759 private:
00760   Value::ObjectValues::iterator current_;
00761   // Indicates that iterator is for a null value.
00762   bool isNull_;
00763 
00764 public:
00765   // For some reason, BORLAND needs these at the end, rather
00766   // than earlier. No idea why.
00767   ValueIteratorBase();
00768   explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
00769 };
00770 
00774 class JSON_API ValueConstIterator : public ValueIteratorBase {
00775   friend class Value;
00776 
00777 public:
00778   typedef const Value value_type;
00779   //typedef unsigned int size_t;
00780   //typedef int difference_type;
00781   typedef const Value& reference;
00782   typedef const Value* pointer;
00783   typedef ValueConstIterator SelfType;
00784 
00785   ValueConstIterator();
00786   ValueConstIterator(ValueIterator const& other);
00787 
00788 private:
00791   explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
00792 public:
00793   SelfType& operator=(const ValueIteratorBase& other);
00794 
00795   SelfType operator++(int) {
00796     SelfType temp(*this);
00797     ++*this;
00798     return temp;
00799   }
00800 
00801   SelfType operator--(int) {
00802     SelfType temp(*this);
00803     --*this;
00804     return temp;
00805   }
00806 
00807   SelfType& operator--() {
00808     decrement();
00809     return *this;
00810   }
00811 
00812   SelfType& operator++() {
00813     increment();
00814     return *this;
00815   }
00816 
00817   reference operator*() const { return deref(); }
00818 
00819   pointer operator->() const { return &deref(); }
00820 };
00821 
00824 class JSON_API ValueIterator : public ValueIteratorBase {
00825   friend class Value;
00826 
00827 public:
00828   typedef Value value_type;
00829   typedef unsigned int size_t;
00830   typedef int difference_type;
00831   typedef Value& reference;
00832   typedef Value* pointer;
00833   typedef ValueIterator SelfType;
00834 
00835   ValueIterator();
00836   explicit ValueIterator(const ValueConstIterator& other);
00837   ValueIterator(const ValueIterator& other);
00838 
00839 private:
00842   explicit ValueIterator(const Value::ObjectValues::iterator& current);
00843 public:
00844   SelfType& operator=(const SelfType& other);
00845 
00846   SelfType operator++(int) {
00847     SelfType temp(*this);
00848     ++*this;
00849     return temp;
00850   }
00851 
00852   SelfType operator--(int) {
00853     SelfType temp(*this);
00854     --*this;
00855     return temp;
00856   }
00857 
00858   SelfType& operator--() {
00859     decrement();
00860     return *this;
00861   }
00862 
00863   SelfType& operator++() {
00864     increment();
00865     return *this;
00866   }
00867 
00868   reference operator*() const { return deref(); }
00869 
00870   pointer operator->() const { return &deref(); }
00871 };
00872 
00873 } // namespace Json
00874 
00875 
00876 namespace std {
00878 template<>
00879 inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
00880 }
00881 
00882 #pragma pack(pop)
00883 
00884 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00885 #pragma warning(pop)
00886 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00887 
00888 #endif // CPPTL_JSON_H_INCLUDED