JsonCpp project page JsonCpp home page

include/json/value.h
Go to the documentation of this file.
00001 // Copyright 2007-2010 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 #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 
00047 namespace Json {
00048 
00053 class JSON_API Exception : public std::exception {
00054 public:
00055   Exception(JSONCPP_STRING const& msg);
00056   ~Exception() throw() JSONCPP_OVERRIDE;
00057   char const* what() const throw() JSONCPP_OVERRIDE;
00058 protected:
00059   JSONCPP_STRING msg_;
00060 };
00061 
00068 class JSON_API RuntimeError : public Exception {
00069 public:
00070   RuntimeError(JSONCPP_STRING const& msg);
00071 };
00072 
00079 class JSON_API LogicError : public Exception {
00080 public:
00081   LogicError(JSONCPP_STRING const& msg);
00082 };
00083 
00085 JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
00087 JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
00088 
00091 enum ValueType {
00092   nullValue = 0, 
00093   intValue,      
00094   uintValue,     
00095   realValue,     
00096   stringValue,   
00097   booleanValue,  
00098   arrayValue,    
00099   objectValue    
00100 };
00101 
00102 enum CommentPlacement {
00103   commentBefore = 0,      
00104   commentAfterOnSameLine, 
00105   commentAfter, 
00106 
00107   numberOfCommentPlacement
00108 };
00109 
00110 //# ifdef JSON_USE_CPPTL
00111 //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
00112 //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
00113 //# endif
00114 
00129 class JSON_API StaticString {
00130 public:
00131   explicit StaticString(const char* czstring) : c_str_(czstring) {}
00132 
00133   operator const char*() const { return c_str_; }
00134 
00135   const char* c_str() const { return c_str_; }
00136 
00137 private:
00138   const char* c_str_;
00139 };
00140 
00175 class JSON_API Value {
00176   friend class ValueIteratorBase;
00177 public:
00178   typedef std::vector<JSONCPP_STRING> Members;
00179   typedef ValueIterator iterator;
00180   typedef ValueConstIterator const_iterator;
00181   typedef Json::UInt UInt;
00182   typedef Json::Int Int;
00183 #if defined(JSON_HAS_INT64)
00184   typedef Json::UInt64 UInt64;
00185   typedef Json::Int64 Int64;
00186 #endif // defined(JSON_HAS_INT64)
00187   typedef Json::LargestInt LargestInt;
00188   typedef Json::LargestUInt LargestUInt;
00189   typedef Json::ArrayIndex ArrayIndex;
00190 
00191   static const Value& null;  
00192   static const Value& nullRef;  
00193 
00194   static const LargestInt minLargestInt;
00196   static const LargestInt maxLargestInt;
00198   static const LargestUInt maxLargestUInt;
00199 
00201   static const Int minInt;
00203   static const Int maxInt;
00205   static const UInt maxUInt;
00206 
00207 #if defined(JSON_HAS_INT64)
00208 
00209   static const Int64 minInt64;
00211   static const Int64 maxInt64;
00213   static const UInt64 maxUInt64;
00214 #endif // defined(JSON_HAS_INT64)
00215 
00216 private:
00217 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00218   class CZString {
00219   public:
00220     enum DuplicationPolicy {
00221       noDuplication = 0,
00222       duplicate,
00223       duplicateOnCopy
00224     };
00225     CZString(ArrayIndex index);
00226     CZString(char const* str, unsigned length, DuplicationPolicy allocate);
00227     CZString(CZString const& other);
00228 #if JSON_HAS_RVALUE_REFERENCES
00229     CZString(CZString&& other);
00230 #endif
00231     ~CZString();
00232     CZString& operator=(CZString other);
00233     bool operator<(CZString const& other) const;
00234     bool operator==(CZString const& other) const;
00235     ArrayIndex index() const;
00236     //const char* c_str() const; ///< \deprecated
00237     char const* data() const;
00238     unsigned length() const;
00239     bool isStaticString() const;
00240 
00241   private:
00242     void swap(CZString& other);
00243 
00244     struct StringStorage {
00245       unsigned policy_: 2;
00246       unsigned length_: 30; // 1GB max
00247     };
00248 
00249     char const* cstr_;  // actually, a prefixed string, unless policy is noDup
00250     union {
00251       ArrayIndex index_;
00252       StringStorage storage_;
00253     };
00254   };
00255 
00256 public:
00257 #ifndef JSON_USE_CPPTL_SMALLMAP
00258   typedef std::map<CZString, Value> ObjectValues;
00259 #else
00260   typedef CppTL::SmallMap<CZString, Value> ObjectValues;
00261 #endif // ifndef JSON_USE_CPPTL_SMALLMAP
00262 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00263 
00264 public:
00280   Value(ValueType type = nullValue);
00281   Value(Int value);
00282   Value(UInt value);
00283 #if defined(JSON_HAS_INT64)
00284   Value(Int64 value);
00285   Value(UInt64 value);
00286 #endif // if defined(JSON_HAS_INT64)
00287   Value(double value);
00288   Value(const char* value); 
00289   Value(const char* begin, const char* end); 
00290 
00305   Value(const StaticString& value);
00306   Value(const JSONCPP_STRING& value); 
00307 #ifdef JSON_USE_CPPTL
00308   Value(const CppTL::ConstString& value);
00309 #endif
00310   Value(bool value);
00312   Value(const Value& other);
00313 #if JSON_HAS_RVALUE_REFERENCES
00314 
00315   Value(Value&& other);
00316 #endif
00317   ~Value();
00318 
00321   Value& operator=(Value other);
00323   void swap(Value& other);
00325   void swapPayload(Value& other);
00326 
00327   ValueType type() const;
00328 
00330   bool operator<(const Value& other) const;
00331   bool operator<=(const Value& other) const;
00332   bool operator>=(const Value& other) const;
00333   bool operator>(const Value& other) const;
00334   bool operator==(const Value& other) const;
00335   bool operator!=(const Value& other) const;
00336   int compare(const Value& other) const;
00337 
00338   const char* asCString() const; 
00339 #if JSONCPP_USING_SECURE_MEMORY
00340   unsigned getCStringLength() const; //Allows you to understand the length of the CString
00341 #endif
00342   JSONCPP_STRING asString() const; 
00343 
00346   bool getString(
00347       char const** begin, char const** end) const;
00348 #ifdef JSON_USE_CPPTL
00349   CppTL::ConstString asConstString() const;
00350 #endif
00351   Int asInt() const;
00352   UInt asUInt() const;
00353 #if defined(JSON_HAS_INT64)
00354   Int64 asInt64() const;
00355   UInt64 asUInt64() const;
00356 #endif // if defined(JSON_HAS_INT64)
00357   LargestInt asLargestInt() const;
00358   LargestUInt asLargestUInt() const;
00359   float asFloat() const;
00360   double asDouble() const;
00361   bool asBool() const;
00362 
00363   bool isNull() const;
00364   bool isBool() const;
00365   bool isInt() const;
00366   bool isInt64() const;
00367   bool isUInt() const;
00368   bool isUInt64() const;
00369   bool isIntegral() const;
00370   bool isDouble() const;
00371   bool isNumeric() const;
00372   bool isString() const;
00373   bool isArray() const;
00374   bool isObject() const;
00375 
00376   bool isConvertibleTo(ValueType other) const;
00377 
00379   ArrayIndex size() const;
00380 
00383   bool empty() const;
00384 
00386   bool operator!() const;
00387 
00391   void clear();
00392 
00398   void resize(ArrayIndex size);
00399 
00406   Value& operator[](ArrayIndex index);
00407 
00414   Value& operator[](int index);
00415 
00419   const Value& operator[](ArrayIndex index) const;
00420 
00424   const Value& operator[](int index) const;
00425 
00429   Value get(ArrayIndex index, const Value& defaultValue) const;
00431   bool isValidIndex(ArrayIndex index) const;
00435   Value& append(const Value& value);
00436 
00440   Value& operator[](const char* key);
00443   const Value& operator[](const char* key) const;
00446   Value& operator[](const JSONCPP_STRING& key);
00450   const Value& operator[](const JSONCPP_STRING& key) const;
00463   Value& operator[](const StaticString& key);
00464 #ifdef JSON_USE_CPPTL
00465 
00466   Value& operator[](const CppTL::ConstString& key);
00469   const Value& operator[](const CppTL::ConstString& key) const;
00470 #endif
00471 
00472 
00473   Value get(const char* key, const Value& defaultValue) const;
00477   Value get(const char* begin, const char* end, const Value& defaultValue) const;
00481   Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
00482 #ifdef JSON_USE_CPPTL
00483 
00484 
00485   Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
00486 #endif
00487 
00488 
00489 
00490   Value const* find(char const* begin, char const* end) const;
00494   Value const* demand(char const* begin, char const* end);
00502   Value removeMember(const char* key);
00506   Value removeMember(const JSONCPP_STRING& key);
00509   bool removeMember(const char* key, Value* removed);
00516   bool removeMember(JSONCPP_STRING const& key, Value* removed);
00518   bool removeMember(const char* begin, const char* end, Value* removed);
00525   bool removeIndex(ArrayIndex i, Value* removed);
00526 
00529   bool isMember(const char* key) const;
00532   bool isMember(const JSONCPP_STRING& key) const;
00534   bool isMember(const char* begin, const char* end) const;
00535 #ifdef JSON_USE_CPPTL
00536 
00537   bool isMember(const CppTL::ConstString& key) const;
00538 #endif
00539 
00545   Members getMemberNames() const;
00546 
00547   //# ifdef JSON_USE_CPPTL
00548   //      EnumMemberNames enumMemberNames() const;
00549   //      EnumValues enumValues() const;
00550   //# endif
00551 
00553   JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
00554   void setComment(const char* comment, CommentPlacement placement);
00556   void setComment(const char* comment, size_t len, CommentPlacement placement);
00558   void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
00559   bool hasComment(CommentPlacement placement) const;
00561   JSONCPP_STRING getComment(CommentPlacement placement) const;
00562 
00563   JSONCPP_STRING toStyledString() const;
00564 
00565   const_iterator begin() const;
00566   const_iterator end() const;
00567 
00568   iterator begin();
00569   iterator end();
00570 
00571   // Accessors for the [start, limit) range of bytes within the JSON text from
00572   // which this value was parsed, if any.
00573   void setOffsetStart(ptrdiff_t start);
00574   void setOffsetLimit(ptrdiff_t limit);
00575   ptrdiff_t getOffsetStart() const;
00576   ptrdiff_t getOffsetLimit() const;
00577 
00578 private:
00579   void initBasic(ValueType type, bool allocated = false);
00580 
00581   Value& resolveReference(const char* key);
00582   Value& resolveReference(const char* key, const char* end);
00583 
00584   struct CommentInfo {
00585     CommentInfo();
00586     ~CommentInfo();
00587 
00588     void setComment(const char* text, size_t len);
00589 
00590     char* comment_;
00591   };
00592 
00593   // struct MemberNamesTransform
00594   //{
00595   //   typedef const char *result_type;
00596   //   const char *operator()( const CZString &name ) const
00597   //   {
00598   //      return name.c_str();
00599   //   }
00600   //};
00601 
00602   union ValueHolder {
00603     LargestInt int_;
00604     LargestUInt uint_;
00605     double real_;
00606     bool bool_;
00607     char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
00608     ObjectValues* map_;
00609   } value_;
00610   ValueType type_ : 8;
00611   unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
00612                                // If not allocated_, string_ must be null-terminated.
00613   CommentInfo* comments_;
00614 
00615   // [start, limit) byte offsets in the source JSON text from which this Value
00616   // was extracted.
00617   ptrdiff_t start_;
00618   ptrdiff_t limit_;
00619 };
00620 
00624 class JSON_API PathArgument {
00625 public:
00626   friend class Path;
00627 
00628   PathArgument();
00629   PathArgument(ArrayIndex index);
00630   PathArgument(const char* key);
00631   PathArgument(const JSONCPP_STRING& key);
00632 
00633 private:
00634   enum Kind {
00635     kindNone = 0,
00636     kindIndex,
00637     kindKey
00638   };
00639   JSONCPP_STRING key_;
00640   ArrayIndex index_;
00641   Kind kind_;
00642 };
00643 
00655 class JSON_API Path {
00656 public:
00657   Path(const JSONCPP_STRING& path,
00658        const PathArgument& a1 = PathArgument(),
00659        const PathArgument& a2 = PathArgument(),
00660        const PathArgument& a3 = PathArgument(),
00661        const PathArgument& a4 = PathArgument(),
00662        const PathArgument& a5 = PathArgument());
00663 
00664   const Value& resolve(const Value& root) const;
00665   Value resolve(const Value& root, const Value& defaultValue) const;
00668   Value& make(Value& root) const;
00669 
00670 private:
00671   typedef std::vector<const PathArgument*> InArgs;
00672   typedef std::vector<PathArgument> Args;
00673 
00674   void makePath(const JSONCPP_STRING& path, const InArgs& in);
00675   void addPathInArg(const JSONCPP_STRING& path,
00676                     const InArgs& in,
00677                     InArgs::const_iterator& itInArg,
00678                     PathArgument::Kind kind);
00679   void invalidPath(const JSONCPP_STRING& path, int location);
00680 
00681   Args args_;
00682 };
00683 
00687 class JSON_API ValueIteratorBase {
00688 public:
00689   typedef std::bidirectional_iterator_tag iterator_category;
00690   typedef unsigned int size_t;
00691   typedef int difference_type;
00692   typedef ValueIteratorBase SelfType;
00693 
00694   bool operator==(const SelfType& other) const { return isEqual(other); }
00695 
00696   bool operator!=(const SelfType& other) const { return !isEqual(other); }
00697 
00698   difference_type operator-(const SelfType& other) const {
00699     return other.computeDistance(*this);
00700   }
00701 
00704   Value key() const;
00705 
00707   UInt index() const;
00708 
00712   JSONCPP_STRING name() const;
00713 
00717   JSONCPP_DEPRECATED("Use `key = name();` instead.")
00718   char const* memberName() const;
00722   char const* memberName(char const** end) const;
00723 
00724 protected:
00725   Value& deref() const;
00726 
00727   void increment();
00728 
00729   void decrement();
00730 
00731   difference_type computeDistance(const SelfType& other) const;
00732 
00733   bool isEqual(const SelfType& other) const;
00734 
00735   void copy(const SelfType& other);
00736 
00737 private:
00738   Value::ObjectValues::iterator current_;
00739   // Indicates that iterator is for a null value.
00740   bool isNull_;
00741 
00742 public:
00743   // For some reason, BORLAND needs these at the end, rather
00744   // than earlier. No idea why.
00745   ValueIteratorBase();
00746   explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
00747 };
00748 
00752 class JSON_API ValueConstIterator : public ValueIteratorBase {
00753   friend class Value;
00754 
00755 public:
00756   typedef const Value value_type;
00757   //typedef unsigned int size_t;
00758   //typedef int difference_type;
00759   typedef const Value& reference;
00760   typedef const Value* pointer;
00761   typedef ValueConstIterator SelfType;
00762 
00763   ValueConstIterator();
00764   ValueConstIterator(ValueIterator const& other);
00765 
00766 private:
00769   explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
00770 public:
00771   SelfType& operator=(const ValueIteratorBase& other);
00772 
00773   SelfType operator++(int) {
00774     SelfType temp(*this);
00775     ++*this;
00776     return temp;
00777   }
00778 
00779   SelfType operator--(int) {
00780     SelfType temp(*this);
00781     --*this;
00782     return temp;
00783   }
00784 
00785   SelfType& operator--() {
00786     decrement();
00787     return *this;
00788   }
00789 
00790   SelfType& operator++() {
00791     increment();
00792     return *this;
00793   }
00794 
00795   reference operator*() const { return deref(); }
00796 
00797   pointer operator->() const { return &deref(); }
00798 };
00799 
00802 class JSON_API ValueIterator : public ValueIteratorBase {
00803   friend class Value;
00804 
00805 public:
00806   typedef Value value_type;
00807   typedef unsigned int size_t;
00808   typedef int difference_type;
00809   typedef Value& reference;
00810   typedef Value* pointer;
00811   typedef ValueIterator SelfType;
00812 
00813   ValueIterator();
00814   explicit ValueIterator(const ValueConstIterator& other);
00815   ValueIterator(const ValueIterator& other);
00816 
00817 private:
00820   explicit ValueIterator(const Value::ObjectValues::iterator& current);
00821 public:
00822   SelfType& operator=(const SelfType& other);
00823 
00824   SelfType operator++(int) {
00825     SelfType temp(*this);
00826     ++*this;
00827     return temp;
00828   }
00829 
00830   SelfType operator--(int) {
00831     SelfType temp(*this);
00832     --*this;
00833     return temp;
00834   }
00835 
00836   SelfType& operator--() {
00837     decrement();
00838     return *this;
00839   }
00840 
00841   SelfType& operator++() {
00842     increment();
00843     return *this;
00844   }
00845 
00846   reference operator*() const { return deref(); }
00847 
00848   pointer operator->() const { return &deref(); }
00849 };
00850 
00851 } // namespace Json
00852 
00853 
00854 namespace std {
00856 template<>
00857 inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
00858 }
00859 
00860 
00861 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00862 #pragma warning(pop)
00863 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00864 
00865 #endif // CPPTL_JSON_H_INCLUDED