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 // Disable warning C4251: <data member>: <type> needs to have dll-interface to
00026 // be used by...
00027 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00028 #pragma warning(push)
00029 #pragma warning(disable : 4251)
00030 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00031 
00034 namespace Json {
00035 
00040 class JSON_API Exception;
00047 class JSON_API RuntimeError;
00054 class JSON_API LogicError;
00055 
00057 void throwRuntimeError(std::string const& msg);
00059 void throwLogicError(std::string const& msg);
00060 
00063 enum ValueType {
00064   nullValue = 0, 
00065   intValue,      
00066   uintValue,     
00067   realValue,     
00068   stringValue,   
00069   booleanValue,  
00070   arrayValue,    
00071   objectValue    
00072 };
00073 
00074 enum CommentPlacement {
00075   commentBefore = 0,      
00076   commentAfterOnSameLine, 
00077   commentAfter, 
00078 
00079   numberOfCommentPlacement
00080 };
00081 
00082 //# ifdef JSON_USE_CPPTL
00083 //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
00084 //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
00085 //# endif
00086 
00101 class JSON_API StaticString {
00102 public:
00103   explicit StaticString(const char* czstring) : c_str_(czstring) {}
00104 
00105   operator const char*() const { return c_str_; }
00106 
00107   const char* c_str() const { return c_str_; }
00108 
00109 private:
00110   const char* c_str_;
00111 };
00112 
00147 class JSON_API Value {
00148   friend class ValueIteratorBase;
00149 public:
00150   typedef std::vector<std::string> Members;
00151   typedef ValueIterator iterator;
00152   typedef ValueConstIterator const_iterator;
00153   typedef Json::UInt UInt;
00154   typedef Json::Int Int;
00155 #if defined(JSON_HAS_INT64)
00156   typedef Json::UInt64 UInt64;
00157   typedef Json::Int64 Int64;
00158 #endif // defined(JSON_HAS_INT64)
00159   typedef Json::LargestInt LargestInt;
00160   typedef Json::LargestUInt LargestUInt;
00161   typedef Json::ArrayIndex ArrayIndex;
00162 
00163   static const Value& null;  
00164   static const Value& nullRef;  
00165 
00166   static const LargestInt minLargestInt;
00168   static const LargestInt maxLargestInt;
00170   static const LargestUInt maxLargestUInt;
00171 
00173   static const Int minInt;
00175   static const Int maxInt;
00177   static const UInt maxUInt;
00178 
00179 #if defined(JSON_HAS_INT64)
00180 
00181   static const Int64 minInt64;
00183   static const Int64 maxInt64;
00185   static const UInt64 maxUInt64;
00186 #endif // defined(JSON_HAS_INT64)
00187 
00188 private:
00189 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00190   class CZString {
00191   public:
00192     enum DuplicationPolicy {
00193       noDuplication = 0,
00194       duplicate,
00195       duplicateOnCopy
00196     };
00197     CZString(ArrayIndex index);
00198     CZString(char const* str, unsigned length, DuplicationPolicy allocate);
00199     CZString(CZString const& other);
00200     ~CZString();
00201     CZString& operator=(CZString other);
00202     bool operator<(CZString const& other) const;
00203     bool operator==(CZString const& other) const;
00204     ArrayIndex index() const;
00205     //const char* c_str() const; ///< \deprecated
00206     char const* data() const;
00207     unsigned length() const;
00208     bool isStaticString() const;
00209 
00210   private:
00211     void swap(CZString& other);
00212 
00213     struct StringStorage {
00214       DuplicationPolicy policy_: 2;
00215       unsigned length_: 30; // 1GB max
00216     };
00217 
00218     char const* cstr_;  // actually, a prefixed string, unless policy is noDup
00219     union {
00220       ArrayIndex index_;
00221       StringStorage storage_;
00222     };
00223   };
00224 
00225 public:
00226 #ifndef JSON_USE_CPPTL_SMALLMAP
00227   typedef std::map<CZString, Value> ObjectValues;
00228 #else
00229   typedef CppTL::SmallMap<CZString, Value> ObjectValues;
00230 #endif // ifndef JSON_USE_CPPTL_SMALLMAP
00231 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00232 
00233 public:
00249   Value(ValueType type = nullValue);
00250   Value(Int value);
00251   Value(UInt value);
00252 #if defined(JSON_HAS_INT64)
00253   Value(Int64 value);
00254   Value(UInt64 value);
00255 #endif // if defined(JSON_HAS_INT64)
00256   Value(double value);
00257   Value(const char* value); 
00258   Value(const char* beginValue, const char* endValue); 
00259 
00274   Value(const StaticString& value);
00275   Value(const std::string& value); 
00276 #ifdef JSON_USE_CPPTL
00277   Value(const CppTL::ConstString& value);
00278 #endif
00279   Value(bool value);
00281   Value(const Value& other);
00282   ~Value();
00283 
00286   Value& operator=(Value other);
00288   void swap(Value& other);
00290   void swapPayload(Value& other);
00291 
00292   ValueType type() const;
00293 
00295   bool operator<(const Value& other) const;
00296   bool operator<=(const Value& other) const;
00297   bool operator>=(const Value& other) const;
00298   bool operator>(const Value& other) const;
00299   bool operator==(const Value& other) const;
00300   bool operator!=(const Value& other) const;
00301   int compare(const Value& other) const;
00302 
00303   const char* asCString() const; 
00304   std::string asString() const; 
00305 
00308   bool getString(
00309       char const** str, char const** end) const;
00310 #ifdef JSON_USE_CPPTL
00311   CppTL::ConstString asConstString() const;
00312 #endif
00313   Int asInt() const;
00314   UInt asUInt() const;
00315 #if defined(JSON_HAS_INT64)
00316   Int64 asInt64() const;
00317   UInt64 asUInt64() const;
00318 #endif // if defined(JSON_HAS_INT64)
00319   LargestInt asLargestInt() const;
00320   LargestUInt asLargestUInt() const;
00321   float asFloat() const;
00322   double asDouble() const;
00323   bool asBool() const;
00324 
00325   bool isNull() const;
00326   bool isBool() const;
00327   bool isInt() const;
00328   bool isInt64() const;
00329   bool isUInt() const;
00330   bool isUInt64() const;
00331   bool isIntegral() const;
00332   bool isDouble() const;
00333   bool isNumeric() const;
00334   bool isString() const;
00335   bool isArray() const;
00336   bool isObject() const;
00337 
00338   bool isConvertibleTo(ValueType other) const;
00339 
00341   ArrayIndex size() const;
00342 
00345   bool empty() const;
00346 
00348   bool operator!() const;
00349 
00353   void clear();
00354 
00360   void resize(ArrayIndex size);
00361 
00368   Value& operator[](ArrayIndex index);
00369 
00376   Value& operator[](int index);
00377 
00381   const Value& operator[](ArrayIndex index) const;
00382 
00386   const Value& operator[](int index) const;
00387 
00391   Value get(ArrayIndex index, const Value& defaultValue) const;
00393   bool isValidIndex(ArrayIndex index) const;
00397   Value& append(const Value& value);
00398 
00402   Value& operator[](const char* key);
00405   const Value& operator[](const char* key) const;
00408   Value& operator[](const std::string& key);
00412   const Value& operator[](const std::string& key) const;
00425   Value& operator[](const StaticString& key);
00426 #ifdef JSON_USE_CPPTL
00427 
00428   Value& operator[](const CppTL::ConstString& key);
00431   const Value& operator[](const CppTL::ConstString& key) const;
00432 #endif
00433 
00434 
00435   Value get(const char* key, const Value& defaultValue) const;
00439   Value get(const char* key, const char* end, const Value& defaultValue) const;
00443   Value get(const std::string& key, const Value& defaultValue) const;
00444 #ifdef JSON_USE_CPPTL
00445 
00446 
00447   Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
00448 #endif
00449 
00450 
00451 
00452   Value const* find(char const* key, char const* end) const;
00456   Value const* demand(char const* key, char const* end);
00464   Value removeMember(const char* key);
00468   Value removeMember(const std::string& key);
00471   bool removeMember(const char* key, Value* removed);
00478   bool removeMember(std::string const& key, Value* removed);
00480   bool removeMember(const char* key, const char* end, Value* removed);
00487   bool removeIndex(ArrayIndex i, Value* removed);
00488 
00491   bool isMember(const char* key) const;
00494   bool isMember(const std::string& key) const;
00496   bool isMember(const char* key, const char* end) const;
00497 #ifdef JSON_USE_CPPTL
00498 
00499   bool isMember(const CppTL::ConstString& key) const;
00500 #endif
00501 
00507   Members getMemberNames() const;
00508 
00509   //# ifdef JSON_USE_CPPTL
00510   //      EnumMemberNames enumMemberNames() const;
00511   //      EnumValues enumValues() const;
00512   //# endif
00513 
00515   void setComment(const char* comment, CommentPlacement placement);
00517   void setComment(const char* comment, size_t len, CommentPlacement placement);
00519   void setComment(const std::string& comment, CommentPlacement placement);
00520   bool hasComment(CommentPlacement placement) const;
00522   std::string getComment(CommentPlacement placement) const;
00523 
00524   std::string toStyledString() const;
00525 
00526   const_iterator begin() const;
00527   const_iterator end() const;
00528 
00529   iterator begin();
00530   iterator end();
00531 
00532   // Accessors for the [start, limit) range of bytes within the JSON text from
00533   // which this value was parsed, if any.
00534   void setOffsetStart(size_t start);
00535   void setOffsetLimit(size_t limit);
00536   size_t getOffsetStart() const;
00537   size_t getOffsetLimit() const;
00538 
00539 private:
00540   void initBasic(ValueType type, bool allocated = false);
00541 
00542   Value& resolveReference(const char* key);
00543   Value& resolveReference(const char* key, const char* end);
00544 
00545   struct CommentInfo {
00546     CommentInfo();
00547     ~CommentInfo();
00548 
00549     void setComment(const char* text, size_t len);
00550 
00551     char* comment_;
00552   };
00553 
00554   // struct MemberNamesTransform
00555   //{
00556   //   typedef const char *result_type;
00557   //   const char *operator()( const CZString &name ) const
00558   //   {
00559   //      return name.c_str();
00560   //   }
00561   //};
00562 
00563   union ValueHolder {
00564     LargestInt int_;
00565     LargestUInt uint_;
00566     double real_;
00567     bool bool_;
00568     char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
00569     ObjectValues* map_;
00570   } value_;
00571   ValueType type_ : 8;
00572   unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
00573                                // If not allocated_, string_ must be null-terminated.
00574   CommentInfo* comments_;
00575 
00576   // [start, limit) byte offsets in the source JSON text from which this Value
00577   // was extracted.
00578   size_t start_;
00579   size_t limit_;
00580 };
00581 
00585 class JSON_API PathArgument {
00586 public:
00587   friend class Path;
00588 
00589   PathArgument();
00590   PathArgument(ArrayIndex index);
00591   PathArgument(const char* key);
00592   PathArgument(const std::string& key);
00593 
00594 private:
00595   enum Kind {
00596     kindNone = 0,
00597     kindIndex,
00598     kindKey
00599   };
00600   std::string key_;
00601   ArrayIndex index_;
00602   Kind kind_;
00603 };
00604 
00616 class JSON_API Path {
00617 public:
00618   Path(const std::string& path,
00619        const PathArgument& a1 = PathArgument(),
00620        const PathArgument& a2 = PathArgument(),
00621        const PathArgument& a3 = PathArgument(),
00622        const PathArgument& a4 = PathArgument(),
00623        const PathArgument& a5 = PathArgument());
00624 
00625   const Value& resolve(const Value& root) const;
00626   Value resolve(const Value& root, const Value& defaultValue) const;
00629   Value& make(Value& root) const;
00630 
00631 private:
00632   typedef std::vector<const PathArgument*> InArgs;
00633   typedef std::vector<PathArgument> Args;
00634 
00635   void makePath(const std::string& path, const InArgs& in);
00636   void addPathInArg(const std::string& path,
00637                     const InArgs& in,
00638                     InArgs::const_iterator& itInArg,
00639                     PathArgument::Kind kind);
00640   void invalidPath(const std::string& path, int location);
00641 
00642   Args args_;
00643 };
00644 
00648 class JSON_API ValueIteratorBase {
00649 public:
00650   typedef std::bidirectional_iterator_tag iterator_category;
00651   typedef unsigned int size_t;
00652   typedef int difference_type;
00653   typedef ValueIteratorBase SelfType;
00654 
00655   ValueIteratorBase();
00656   explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
00657 
00658   bool operator==(const SelfType& other) const { return isEqual(other); }
00659 
00660   bool operator!=(const SelfType& other) const { return !isEqual(other); }
00661 
00662   difference_type operator-(const SelfType& other) const {
00663     return other.computeDistance(*this);
00664   }
00665 
00668   Value key() const;
00669 
00671   UInt index() const;
00672 
00676   std::string name() const;
00677 
00681   JSONCPP_DEPRECATED("Use `key = name();` instead.")
00682   char const* memberName() const;
00686   char const* memberName(char const** end) const;
00687 
00688 protected:
00689   Value& deref() const;
00690 
00691   void increment();
00692 
00693   void decrement();
00694 
00695   difference_type computeDistance(const SelfType& other) const;
00696 
00697   bool isEqual(const SelfType& other) const;
00698 
00699   void copy(const SelfType& other);
00700 
00701 private:
00702   Value::ObjectValues::iterator current_;
00703   // Indicates that iterator is for a null value.
00704   bool isNull_;
00705 };
00706 
00710 class JSON_API ValueConstIterator : public ValueIteratorBase {
00711   friend class Value;
00712 
00713 public:
00714   typedef const Value value_type;
00715   //typedef unsigned int size_t;
00716   //typedef int difference_type;
00717   typedef const Value& reference;
00718   typedef const Value* pointer;
00719   typedef ValueConstIterator SelfType;
00720 
00721   ValueConstIterator();
00722 
00723 private:
00726   explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
00727 public:
00728   SelfType& operator=(const ValueIteratorBase& other);
00729 
00730   SelfType operator++(int) {
00731     SelfType temp(*this);
00732     ++*this;
00733     return temp;
00734   }
00735 
00736   SelfType operator--(int) {
00737     SelfType temp(*this);
00738     --*this;
00739     return temp;
00740   }
00741 
00742   SelfType& operator--() {
00743     decrement();
00744     return *this;
00745   }
00746 
00747   SelfType& operator++() {
00748     increment();
00749     return *this;
00750   }
00751 
00752   reference operator*() const { return deref(); }
00753 
00754   pointer operator->() const { return &deref(); }
00755 };
00756 
00759 class JSON_API ValueIterator : public ValueIteratorBase {
00760   friend class Value;
00761 
00762 public:
00763   typedef Value value_type;
00764   typedef unsigned int size_t;
00765   typedef int difference_type;
00766   typedef Value& reference;
00767   typedef Value* pointer;
00768   typedef ValueIterator SelfType;
00769 
00770   ValueIterator();
00771   ValueIterator(const ValueConstIterator& other);
00772   ValueIterator(const ValueIterator& other);
00773 
00774 private:
00777   explicit ValueIterator(const Value::ObjectValues::iterator& current);
00778 public:
00779   SelfType& operator=(const SelfType& other);
00780 
00781   SelfType operator++(int) {
00782     SelfType temp(*this);
00783     ++*this;
00784     return temp;
00785   }
00786 
00787   SelfType operator--(int) {
00788     SelfType temp(*this);
00789     --*this;
00790     return temp;
00791   }
00792 
00793   SelfType& operator--() {
00794     decrement();
00795     return *this;
00796   }
00797 
00798   SelfType& operator++() {
00799     increment();
00800     return *this;
00801   }
00802 
00803   reference operator*() const { return deref(); }
00804 
00805   pointer operator->() const { return &deref(); }
00806 };
00807 
00808 } // namespace Json
00809 
00810 
00811 namespace std {
00813 template<>
00814 inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
00815 }
00816 
00817 
00818 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00819 #pragma warning(pop)
00820 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
00821 
00822 #endif // CPPTL_JSON_H_INCLUDED