Home | History | Annotate | Download | only in json
      1 // Copyright 2007-2010 Baptiste Lepilleur
      2 // Distributed under MIT license, or public domain if desired and
      3 // recognized in your jurisdiction.
      4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
      5 
      6 #ifndef CPPTL_JSON_H_INCLUDED
      7 #define CPPTL_JSON_H_INCLUDED
      8 
      9 #if !defined(JSON_IS_AMALGAMATION)
     10 #include "forwards.h"
     11 #endif // if !defined(JSON_IS_AMALGAMATION)
     12 #include <string>
     13 #include <vector>
     14 
     15 #ifndef JSON_USE_CPPTL_SMALLMAP
     16 #include <map>
     17 #else
     18 #include <cpptl/smallmap.h>
     19 #endif
     20 #ifdef JSON_USE_CPPTL
     21 #include <cpptl/forwards.h>
     22 #endif
     23 
     24 // Disable warning C4251: <data member>: <type> needs to have dll-interface to
     25 // be used by...
     26 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
     27 #pragma warning(push)
     28 #pragma warning(disable : 4251)
     29 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
     30 
     31 /** \brief JSON (JavaScript Object Notation).
     32  */
     33 namespace Json {
     34 
     35 /** \brief Type of the value held by a Value object.
     36  */
     37 enum ValueType {
     38   nullValue = 0, ///< 'null' value
     39   intValue,      ///< signed integer value
     40   uintValue,     ///< unsigned integer value
     41   realValue,     ///< double value
     42   stringValue,   ///< UTF-8 string value
     43   booleanValue,  ///< bool value
     44   arrayValue,    ///< array value (ordered list)
     45   objectValue    ///< object value (collection of name/value pairs).
     46 };
     47 
     48 enum CommentPlacement {
     49   commentBefore = 0,      ///< a comment placed on the line before a value
     50   commentAfterOnSameLine, ///< a comment just after a value on the same line
     51   commentAfter, ///< a comment on the line after a value (only make sense for
     52   /// root value)
     53   numberOfCommentPlacement
     54 };
     55 
     56 //# ifdef JSON_USE_CPPTL
     57 //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
     58 //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
     59 //# endif
     60 
     61 /** \brief Lightweight wrapper to tag static string.
     62  *
     63  * Value constructor and objectValue member assignement takes advantage of the
     64  * StaticString and avoid the cost of string duplication when storing the
     65  * string or the member name.
     66  *
     67  * Example of usage:
     68  * \code
     69  * Json::Value aValue( StaticString("some text") );
     70  * Json::Value object;
     71  * static const StaticString code("code");
     72  * object[code] = 1234;
     73  * \endcode
     74  */
     75 class JSON_API StaticString {
     76 public:
     77   explicit StaticString(const char* czstring) : str_(czstring) {}
     78 
     79   operator const char*() const { return str_; }
     80 
     81   const char* c_str() const { return str_; }
     82 
     83 private:
     84   const char* str_;
     85 };
     86 
     87 /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
     88  *
     89  * This class is a discriminated union wrapper that can represents a:
     90  * - signed integer [range: Value::minInt - Value::maxInt]
     91  * - unsigned integer (range: 0 - Value::maxUInt)
     92  * - double
     93  * - UTF-8 string
     94  * - boolean
     95  * - 'null'
     96  * - an ordered list of Value
     97  * - collection of name/value pairs (javascript object)
     98  *
     99  * The type of the held value is represented by a #ValueType and
    100  * can be obtained using type().
    101  *
    102  * values of an #objectValue or #arrayValue can be accessed using operator[]()
    103  *methods.
    104  * Non const methods will automatically create the a #nullValue element
    105  * if it does not exist.
    106  * The sequence of an #arrayValue will be automatically resize and initialized
    107  * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
    108  *
    109  * The get() methods can be used to obtanis default value in the case the
    110  *required element
    111  * does not exist.
    112  *
    113  * It is possible to iterate over the list of a #objectValue values using
    114  * the getMemberNames() method.
    115  */
    116 class JSON_API Value {
    117   friend class ValueIteratorBase;
    118 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    119   friend class ValueInternalLink;
    120   friend class ValueInternalMap;
    121 #endif
    122 public:
    123   typedef std::vector<std::string> Members;
    124   typedef ValueIterator iterator;
    125   typedef ValueConstIterator const_iterator;
    126   typedef Json::UInt UInt;
    127   typedef Json::Int Int;
    128 #if defined(JSON_HAS_INT64)
    129   typedef Json::UInt64 UInt64;
    130   typedef Json::Int64 Int64;
    131 #endif // defined(JSON_HAS_INT64)
    132   typedef Json::LargestInt LargestInt;
    133   typedef Json::LargestUInt LargestUInt;
    134   typedef Json::ArrayIndex ArrayIndex;
    135 
    136   static const Value& null;
    137   /// Minimum signed integer value that can be stored in a Json::Value.
    138   static const LargestInt minLargestInt;
    139   /// Maximum signed integer value that can be stored in a Json::Value.
    140   static const LargestInt maxLargestInt;
    141   /// Maximum unsigned integer value that can be stored in a Json::Value.
    142   static const LargestUInt maxLargestUInt;
    143 
    144   /// Minimum signed int value that can be stored in a Json::Value.
    145   static const Int minInt;
    146   /// Maximum signed int value that can be stored in a Json::Value.
    147   static const Int maxInt;
    148   /// Maximum unsigned int value that can be stored in a Json::Value.
    149   static const UInt maxUInt;
    150 
    151 #if defined(JSON_HAS_INT64)
    152   /// Minimum signed 64 bits int value that can be stored in a Json::Value.
    153   static const Int64 minInt64;
    154   /// Maximum signed 64 bits int value that can be stored in a Json::Value.
    155   static const Int64 maxInt64;
    156   /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
    157   static const UInt64 maxUInt64;
    158 #endif // defined(JSON_HAS_INT64)
    159 
    160 private:
    161 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    162 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    163   class CZString {
    164   public:
    165     enum DuplicationPolicy {
    166       noDuplication = 0,
    167       duplicate,
    168       duplicateOnCopy
    169     };
    170     CZString(ArrayIndex index);
    171     CZString(const char* cstr, DuplicationPolicy allocate);
    172     CZString(const CZString& other);
    173     ~CZString();
    174     CZString& operator=(CZString other);
    175     bool operator<(const CZString& other) const;
    176     bool operator==(const CZString& other) const;
    177     ArrayIndex index() const;
    178     const char* c_str() const;
    179     bool isStaticString() const;
    180 
    181   private:
    182     void swap(CZString& other);
    183     const char* cstr_;
    184     ArrayIndex index_;
    185   };
    186 
    187 public:
    188 #ifndef JSON_USE_CPPTL_SMALLMAP
    189   typedef std::map<CZString, Value> ObjectValues;
    190 #else
    191   typedef CppTL::SmallMap<CZString, Value> ObjectValues;
    192 #endif // ifndef JSON_USE_CPPTL_SMALLMAP
    193 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
    194 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    195 
    196 public:
    197   /** \brief Create a default Value of the given type.
    198 
    199     This is a very useful constructor.
    200     To create an empty array, pass arrayValue.
    201     To create an empty object, pass objectValue.
    202     Another Value can then be set to this one by assignment.
    203 This is useful since clear() and resize() will not alter types.
    204 
    205     Examples:
    206 \code
    207 Json::Value null_value; // null
    208 Json::Value arr_value(Json::arrayValue); // []
    209 Json::Value obj_value(Json::objectValue); // {}
    210 \endcode
    211   */
    212   Value(ValueType type = nullValue);
    213   Value(Int value);
    214   Value(UInt value);
    215 #if defined(JSON_HAS_INT64)
    216   Value(Int64 value);
    217   Value(UInt64 value);
    218 #endif // if defined(JSON_HAS_INT64)
    219   Value(double value);
    220   Value(const char* value);
    221   Value(const char* beginValue, const char* endValue);
    222   /** \brief Constructs a value from a static string.
    223 
    224    * Like other value string constructor but do not duplicate the string for
    225    * internal storage. The given string must remain alive after the call to this
    226    * constructor.
    227    * Example of usage:
    228    * \code
    229    * Json::Value aValue( StaticString("some text") );
    230    * \endcode
    231    */
    232   Value(const StaticString& value);
    233   Value(const std::string& value);
    234 #ifdef JSON_USE_CPPTL
    235   Value(const CppTL::ConstString& value);
    236 #endif
    237   Value(bool value);
    238   Value(const Value& other);
    239   ~Value();
    240 
    241   Value& operator=(Value other);
    242   /// Swap values.
    243   /// \note Currently, comments are intentionally not swapped, for
    244   /// both logic and efficiency.
    245   void swap(Value& other);
    246 
    247   ValueType type() const;
    248 
    249   bool operator<(const Value& other) const;
    250   bool operator<=(const Value& other) const;
    251   bool operator>=(const Value& other) const;
    252   bool operator>(const Value& other) const;
    253 
    254   bool operator==(const Value& other) const;
    255   bool operator!=(const Value& other) const;
    256 
    257   int compare(const Value& other) const;
    258 
    259   const char* asCString() const;
    260   std::string asString() const;
    261 #ifdef JSON_USE_CPPTL
    262   CppTL::ConstString asConstString() const;
    263 #endif
    264   Int asInt() const;
    265   UInt asUInt() const;
    266 #if defined(JSON_HAS_INT64)
    267   Int64 asInt64() const;
    268   UInt64 asUInt64() const;
    269 #endif // if defined(JSON_HAS_INT64)
    270   LargestInt asLargestInt() const;
    271   LargestUInt asLargestUInt() const;
    272   float asFloat() const;
    273   double asDouble() const;
    274   bool asBool() const;
    275 
    276   bool isNull() const;
    277   bool isBool() const;
    278   bool isInt() const;
    279   bool isInt64() const;
    280   bool isUInt() const;
    281   bool isUInt64() const;
    282   bool isIntegral() const;
    283   bool isDouble() const;
    284   bool isNumeric() const;
    285   bool isString() const;
    286   bool isArray() const;
    287   bool isObject() const;
    288 
    289   bool isConvertibleTo(ValueType other) const;
    290 
    291   /// Number of values in array or object
    292   ArrayIndex size() const;
    293 
    294   /// \brief Return true if empty array, empty object, or null;
    295   /// otherwise, false.
    296   bool empty() const;
    297 
    298   /// Return isNull()
    299   bool operator!() const;
    300 
    301   /// Remove all object members and array elements.
    302   /// \pre type() is arrayValue, objectValue, or nullValue
    303   /// \post type() is unchanged
    304   void clear();
    305 
    306   /// Resize the array to size elements.
    307   /// New elements are initialized to null.
    308   /// May only be called on nullValue or arrayValue.
    309   /// \pre type() is arrayValue or nullValue
    310   /// \post type() is arrayValue
    311   void resize(ArrayIndex size);
    312 
    313   /// Access an array element (zero based index ).
    314   /// If the array contains less than index element, then null value are
    315   /// inserted
    316   /// in the array so that its size is index+1.
    317   /// (You may need to say 'value[0u]' to get your compiler to distinguish
    318   ///  this from the operator[] which takes a string.)
    319   Value& operator[](ArrayIndex index);
    320 
    321   /// Access an array element (zero based index ).
    322   /// If the array contains less than index element, then null value are
    323   /// inserted
    324   /// in the array so that its size is index+1.
    325   /// (You may need to say 'value[0u]' to get your compiler to distinguish
    326   ///  this from the operator[] which takes a string.)
    327   Value& operator[](int index);
    328 
    329   /// Access an array element (zero based index )
    330   /// (You may need to say 'value[0u]' to get your compiler to distinguish
    331   ///  this from the operator[] which takes a string.)
    332   const Value& operator[](ArrayIndex index) const;
    333 
    334   /// Access an array element (zero based index )
    335   /// (You may need to say 'value[0u]' to get your compiler to distinguish
    336   ///  this from the operator[] which takes a string.)
    337   const Value& operator[](int index) const;
    338 
    339   /// If the array contains at least index+1 elements, returns the element
    340   /// value,
    341   /// otherwise returns defaultValue.
    342   Value get(ArrayIndex index, const Value& defaultValue) const;
    343   /// Return true if index < size().
    344   bool isValidIndex(ArrayIndex index) const;
    345   /// \brief Append value to array at the end.
    346   ///
    347   /// Equivalent to jsonvalue[jsonvalue.size()] = value;
    348   Value& append(const Value& value);
    349 
    350   /// Access an object value by name, create a null member if it does not exist.
    351   Value& operator[](const char* key);
    352   /// Access an object value by name, returns null if there is no member with
    353   /// that name.
    354   const Value& operator[](const char* key) const;
    355   /// Access an object value by name, create a null member if it does not exist.
    356   Value& operator[](const std::string& key);
    357   /// Access an object value by name, returns null if there is no member with
    358   /// that name.
    359   const Value& operator[](const std::string& key) const;
    360   /** \brief Access an object value by name, create a null member if it does not
    361    exist.
    362 
    363    * If the object as no entry for that name, then the member name used to store
    364    * the new entry is not duplicated.
    365    * Example of use:
    366    * \code
    367    * Json::Value object;
    368    * static const StaticString code("code");
    369    * object[code] = 1234;
    370    * \endcode
    371    */
    372   Value& operator[](const StaticString& key);
    373 #ifdef JSON_USE_CPPTL
    374   /// Access an object value by name, create a null member if it does not exist.
    375   Value& operator[](const CppTL::ConstString& key);
    376   /// Access an object value by name, returns null if there is no member with
    377   /// that name.
    378   const Value& operator[](const CppTL::ConstString& key) const;
    379 #endif
    380   /// Return the member named key if it exist, defaultValue otherwise.
    381   Value get(const char* key, const Value& defaultValue) const;
    382   /// Return the member named key if it exist, defaultValue otherwise.
    383   Value get(const std::string& key, const Value& defaultValue) const;
    384 #ifdef JSON_USE_CPPTL
    385   /// Return the member named key if it exist, defaultValue otherwise.
    386   Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
    387 #endif
    388   /// \brief Remove and return the named member.
    389   ///
    390   /// Do nothing if it did not exist.
    391   /// \return the removed Value, or null.
    392   /// \pre type() is objectValue or nullValue
    393   /// \post type() is unchanged
    394   Value removeMember(const char* key);
    395   /// Same as removeMember(const char*)
    396   Value removeMember(const std::string& key);
    397 
    398   /// Return true if the object has a member named key.
    399   bool isMember(const char* key) const;
    400   /// Return true if the object has a member named key.
    401   bool isMember(const std::string& key) const;
    402 #ifdef JSON_USE_CPPTL
    403   /// Return true if the object has a member named key.
    404   bool isMember(const CppTL::ConstString& key) const;
    405 #endif
    406 
    407   /// \brief Return a list of the member names.
    408   ///
    409   /// If null, return an empty list.
    410   /// \pre type() is objectValue or nullValue
    411   /// \post if type() was nullValue, it remains nullValue
    412   Members getMemberNames() const;
    413 
    414   //# ifdef JSON_USE_CPPTL
    415   //      EnumMemberNames enumMemberNames() const;
    416   //      EnumValues enumValues() const;
    417   //# endif
    418 
    419   /// Comments must be //... or /* ... */
    420   void setComment(const char* comment, CommentPlacement placement);
    421   /// Comments must be //... or /* ... */
    422   void setComment(const std::string& comment, CommentPlacement placement);
    423   bool hasComment(CommentPlacement placement) const;
    424   /// Include delimiters and embedded newlines.
    425   std::string getComment(CommentPlacement placement) const;
    426 
    427   std::string toStyledString() const;
    428 
    429   const_iterator begin() const;
    430   const_iterator end() const;
    431 
    432   iterator begin();
    433   iterator end();
    434 
    435   // Accessors for the [start, limit) range of bytes within the JSON text from
    436   // which this value was parsed, if any.
    437   void setOffsetStart(size_t start);
    438   void setOffsetLimit(size_t limit);
    439   size_t getOffsetStart() const;
    440   size_t getOffsetLimit() const;
    441 
    442 private:
    443   void initBasic(ValueType type, bool allocated = false);
    444 
    445   Value& resolveReference(const char* key, bool isStatic);
    446 
    447 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    448   inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
    449 
    450   inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
    451 
    452   inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
    453 
    454   inline void setMemberNameIsStatic(bool isStatic) {
    455     memberNameIsStatic_ = isStatic ? 1 : 0;
    456   }
    457 #endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
    458 
    459 private:
    460   struct CommentInfo {
    461     CommentInfo();
    462     ~CommentInfo();
    463 
    464     void setComment(const char* text);
    465 
    466     char* comment_;
    467   };
    468 
    469   // struct MemberNamesTransform
    470   //{
    471   //   typedef const char *result_type;
    472   //   const char *operator()( const CZString &name ) const
    473   //   {
    474   //      return name.c_str();
    475   //   }
    476   //};
    477 
    478   union ValueHolder {
    479     LargestInt int_;
    480     LargestUInt uint_;
    481     double real_;
    482     bool bool_;
    483     char* string_;
    484 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    485     ValueInternalArray* array_;
    486     ValueInternalMap* map_;
    487 #else
    488     ObjectValues* map_;
    489 #endif
    490   } value_;
    491   ValueType type_ : 8;
    492   int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
    493 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    494   unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
    495   int memberNameIsStatic_ : 1;  // used by the ValueInternalMap container.
    496 #endif
    497   CommentInfo* comments_;
    498 
    499   // [start, limit) byte offsets in the source JSON text from which this Value
    500   // was extracted.
    501   size_t start_;
    502   size_t limit_;
    503 };
    504 
    505 /** \brief Experimental and untested: represents an element of the "path" to
    506  * access a node.
    507  */
    508 class JSON_API PathArgument {
    509 public:
    510   friend class Path;
    511 
    512   PathArgument();
    513   PathArgument(ArrayIndex index);
    514   PathArgument(const char* key);
    515   PathArgument(const std::string& key);
    516 
    517 private:
    518   enum Kind {
    519     kindNone = 0,
    520     kindIndex,
    521     kindKey
    522   };
    523   std::string key_;
    524   ArrayIndex index_;
    525   Kind kind_;
    526 };
    527 
    528 /** \brief Experimental and untested: represents a "path" to access a node.
    529  *
    530  * Syntax:
    531  * - "." => root node
    532  * - ".[n]" => elements at index 'n' of root node (an array value)
    533  * - ".name" => member named 'name' of root node (an object value)
    534  * - ".name1.name2.name3"
    535  * - ".[0][1][2].name1[3]"
    536  * - ".%" => member name is provided as parameter
    537  * - ".[%]" => index is provied as parameter
    538  */
    539 class JSON_API Path {
    540 public:
    541   Path(const std::string& path,
    542        const PathArgument& a1 = PathArgument(),
    543        const PathArgument& a2 = PathArgument(),
    544        const PathArgument& a3 = PathArgument(),
    545        const PathArgument& a4 = PathArgument(),
    546        const PathArgument& a5 = PathArgument());
    547 
    548   const Value& resolve(const Value& root) const;
    549   Value resolve(const Value& root, const Value& defaultValue) const;
    550   /// Creates the "path" to access the specified node and returns a reference on
    551   /// the node.
    552   Value& make(Value& root) const;
    553 
    554 private:
    555   typedef std::vector<const PathArgument*> InArgs;
    556   typedef std::vector<PathArgument> Args;
    557 
    558   void makePath(const std::string& path, const InArgs& in);
    559   void addPathInArg(const std::string& path,
    560                     const InArgs& in,
    561                     InArgs::const_iterator& itInArg,
    562                     PathArgument::Kind kind);
    563   void invalidPath(const std::string& path, int location);
    564 
    565   Args args_;
    566 };
    567 
    568 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    569 /** \brief Allocator to customize Value internal map.
    570  * Below is an example of a simple implementation (default implementation
    571  actually
    572  * use memory pool for speed).
    573  * \code
    574    class DefaultValueMapAllocator : public ValueMapAllocator
    575    {
    576    public: // overridden from ValueMapAllocator
    577       virtual ValueInternalMap *newMap()
    578       {
    579          return new ValueInternalMap();
    580       }
    581 
    582       virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
    583       {
    584          return new ValueInternalMap( other );
    585       }
    586 
    587       virtual void destructMap( ValueInternalMap *map )
    588       {
    589          delete map;
    590       }
    591 
    592       virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
    593       {
    594          return new ValueInternalLink[size];
    595       }
    596 
    597       virtual void releaseMapBuckets( ValueInternalLink *links )
    598       {
    599          delete [] links;
    600       }
    601 
    602       virtual ValueInternalLink *allocateMapLink()
    603       {
    604          return new ValueInternalLink();
    605       }
    606 
    607       virtual void releaseMapLink( ValueInternalLink *link )
    608       {
    609          delete link;
    610       }
    611    };
    612  * \endcode
    613  */
    614 class JSON_API ValueMapAllocator {
    615 public:
    616   virtual ~ValueMapAllocator();
    617   virtual ValueInternalMap* newMap() = 0;
    618   virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0;
    619   virtual void destructMap(ValueInternalMap* map) = 0;
    620   virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0;
    621   virtual void releaseMapBuckets(ValueInternalLink* links) = 0;
    622   virtual ValueInternalLink* allocateMapLink() = 0;
    623   virtual void releaseMapLink(ValueInternalLink* link) = 0;
    624 };
    625 
    626 /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
    627  * \internal previous_ & next_ allows for bidirectional traversal.
    628  */
    629 class JSON_API ValueInternalLink {
    630 public:
    631   enum {
    632     itemPerLink = 6
    633   }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
    634   enum InternalFlags {
    635     flagAvailable = 0,
    636     flagUsed = 1
    637   };
    638 
    639   ValueInternalLink();
    640 
    641   ~ValueInternalLink();
    642 
    643   Value items_[itemPerLink];
    644   char* keys_[itemPerLink];
    645   ValueInternalLink* previous_;
    646   ValueInternalLink* next_;
    647 };
    648 
    649 /** \brief A linked page based hash-table implementation used internally by
    650  *Value.
    651  * \internal ValueInternalMap is a tradional bucket based hash-table, with a
    652  *linked
    653  * list in each bucket to handle collision. There is an addional twist in that
    654  * each node of the collision linked list is a page containing a fixed amount of
    655  * value. This provides a better compromise between memory usage and speed.
    656  *
    657  * Each bucket is made up of a chained list of ValueInternalLink. The last
    658  * link of a given bucket can be found in the 'previous_' field of the following
    659  *bucket.
    660  * The last link of the last bucket is stored in tailLink_ as it has no
    661  *following bucket.
    662  * Only the last link of a bucket may contains 'available' item. The last link
    663  *always
    664  * contains at least one element unless is it the bucket one very first link.
    665  */
    666 class JSON_API ValueInternalMap {
    667   friend class ValueIteratorBase;
    668   friend class Value;
    669 
    670 public:
    671   typedef unsigned int HashKey;
    672   typedef unsigned int BucketIndex;
    673 
    674 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    675   struct IteratorState {
    676     IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
    677     ValueInternalMap* map_;
    678     ValueInternalLink* link_;
    679     BucketIndex itemIndex_;
    680     BucketIndex bucketIndex_;
    681   };
    682 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    683 
    684   ValueInternalMap();
    685   ValueInternalMap(const ValueInternalMap& other);
    686   ValueInternalMap& operator=(ValueInternalMap other);
    687   ~ValueInternalMap();
    688 
    689   void swap(ValueInternalMap& other);
    690 
    691   BucketIndex size() const;
    692 
    693   void clear();
    694 
    695   bool reserveDelta(BucketIndex growth);
    696 
    697   bool reserve(BucketIndex newItemCount);
    698 
    699   const Value* find(const char* key) const;
    700 
    701   Value* find(const char* key);
    702 
    703   Value& resolveReference(const char* key, bool isStatic);
    704 
    705   void remove(const char* key);
    706 
    707   void doActualRemove(ValueInternalLink* link,
    708                       BucketIndex index,
    709                       BucketIndex bucketIndex);
    710 
    711   ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex);
    712 
    713   Value& setNewItem(const char* key,
    714                     bool isStatic,
    715                     ValueInternalLink* link,
    716                     BucketIndex index);
    717 
    718   Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey);
    719 
    720   HashKey hash(const char* key) const;
    721 
    722   int compare(const ValueInternalMap& other) const;
    723 
    724 private:
    725   void makeBeginIterator(IteratorState& it) const;
    726   void makeEndIterator(IteratorState& it) const;
    727   static bool equals(const IteratorState& x, const IteratorState& other);
    728   static void increment(IteratorState& iterator);
    729   static void incrementBucket(IteratorState& iterator);
    730   static void decrement(IteratorState& iterator);
    731   static const char* key(const IteratorState& iterator);
    732   static const char* key(const IteratorState& iterator, bool& isStatic);
    733   static Value& value(const IteratorState& iterator);
    734   static int distance(const IteratorState& x, const IteratorState& y);
    735 
    736 private:
    737   ValueInternalLink* buckets_;
    738   ValueInternalLink* tailLink_;
    739   BucketIndex bucketsSize_;
    740   BucketIndex itemCount_;
    741 };
    742 
    743 /** \brief A simplified deque implementation used internally by Value.
    744 * \internal
    745 * It is based on a list of fixed "page", each page contains a fixed number of
    746 *items.
    747 * Instead of using a linked-list, a array of pointer is used for fast item
    748 *look-up.
    749 * Look-up for an element is as follow:
    750 * - compute page index: pageIndex = itemIndex / itemsPerPage
    751 * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
    752 *
    753 * Insertion is amortized constant time (only the array containing the index of
    754 *pointers
    755 * need to be reallocated when items are appended).
    756 */
    757 class JSON_API ValueInternalArray {
    758   friend class Value;
    759   friend class ValueIteratorBase;
    760 
    761 public:
    762   enum {
    763     itemsPerPage = 8
    764   }; // should be a power of 2 for fast divide and modulo.
    765   typedef Value::ArrayIndex ArrayIndex;
    766   typedef unsigned int PageIndex;
    767 
    768 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    769   struct IteratorState // Must be a POD
    770       {
    771     IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
    772     ValueInternalArray* array_;
    773     Value** currentPageIndex_;
    774     unsigned int currentItemIndex_;
    775   };
    776 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
    777 
    778   ValueInternalArray();
    779   ValueInternalArray(const ValueInternalArray& other);
    780   ValueInternalArray& operator=(ValueInternalArray other);
    781   ~ValueInternalArray();
    782   void swap(ValueInternalArray& other);
    783 
    784   void clear();
    785   void resize(ArrayIndex newSize);
    786 
    787   Value& resolveReference(ArrayIndex index);
    788 
    789   Value* find(ArrayIndex index) const;
    790 
    791   ArrayIndex size() const;
    792 
    793   int compare(const ValueInternalArray& other) const;
    794 
    795 private:
    796   static bool equals(const IteratorState& x, const IteratorState& other);
    797   static void increment(IteratorState& iterator);
    798   static void decrement(IteratorState& iterator);
    799   static Value& dereference(const IteratorState& iterator);
    800   static Value& unsafeDereference(const IteratorState& iterator);
    801   static int distance(const IteratorState& x, const IteratorState& y);
    802   static ArrayIndex indexOf(const IteratorState& iterator);
    803   void makeBeginIterator(IteratorState& it) const;
    804   void makeEndIterator(IteratorState& it) const;
    805   void makeIterator(IteratorState& it, ArrayIndex index) const;
    806 
    807   void makeIndexValid(ArrayIndex index);
    808 
    809   Value** pages_;
    810   ArrayIndex size_;
    811   PageIndex pageCount_;
    812 };
    813 
    814 /** \brief Experimental: do not use. Allocator to customize Value internal
    815 array.
    816  * Below is an example of a simple implementation (actual implementation use
    817  * memory pool).
    818    \code
    819 class DefaultValueArrayAllocator : public ValueArrayAllocator
    820 {
    821 public: // overridden from ValueArrayAllocator
    822 virtual ~DefaultValueArrayAllocator()
    823 {
    824 }
    825 
    826 virtual ValueInternalArray *newArray()
    827 {
    828    return new ValueInternalArray();
    829 }
    830 
    831 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
    832 {
    833    return new ValueInternalArray( other );
    834 }
    835 
    836 virtual void destruct( ValueInternalArray *array )
    837 {
    838    delete array;
    839 }
    840 
    841 virtual void reallocateArrayPageIndex( Value **&indexes,
    842                                        ValueInternalArray::PageIndex
    843 &indexCount,
    844                                        ValueInternalArray::PageIndex
    845 minNewIndexCount )
    846 {
    847    ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
    848    if ( minNewIndexCount > newIndexCount )
    849       newIndexCount = minNewIndexCount;
    850    void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
    851    if ( !newIndexes )
    852       throw std::bad_alloc();
    853    indexCount = newIndexCount;
    854    indexes = static_cast<Value **>( newIndexes );
    855 }
    856 virtual void releaseArrayPageIndex( Value **indexes,
    857                                     ValueInternalArray::PageIndex indexCount )
    858 {
    859    if ( indexes )
    860       free( indexes );
    861 }
    862 
    863 virtual Value *allocateArrayPage()
    864 {
    865    return static_cast<Value *>( malloc( sizeof(Value) *
    866 ValueInternalArray::itemsPerPage ) );
    867 }
    868 
    869 virtual void releaseArrayPage( Value *value )
    870 {
    871    if ( value )
    872       free( value );
    873 }
    874 };
    875    \endcode
    876  */
    877 class JSON_API ValueArrayAllocator {
    878 public:
    879   virtual ~ValueArrayAllocator();
    880   virtual ValueInternalArray* newArray() = 0;
    881   virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0;
    882   virtual void destructArray(ValueInternalArray* array) = 0;
    883   /** \brief Reallocate array page index.
    884    * Reallocates an array of pointer on each page.
    885    * \param indexes [input] pointer on the current index. May be \c NULL.
    886    *                [output] pointer on the new index of at least
    887    *                         \a minNewIndexCount pages.
    888    * \param indexCount [input] current number of pages in the index.
    889    *                   [output] number of page the reallocated index can handle.
    890    *                            \b MUST be >= \a minNewIndexCount.
    891    * \param minNewIndexCount Minimum number of page the new index must be able
    892    * to
    893    *                         handle.
    894    */
    895   virtual void
    896   reallocateArrayPageIndex(Value**& indexes,
    897                            ValueInternalArray::PageIndex& indexCount,
    898                            ValueInternalArray::PageIndex minNewIndexCount) = 0;
    899   virtual void
    900   releaseArrayPageIndex(Value** indexes,
    901                         ValueInternalArray::PageIndex indexCount) = 0;
    902   virtual Value* allocateArrayPage() = 0;
    903   virtual void releaseArrayPage(Value* value) = 0;
    904 };
    905 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
    906 
    907 /** \brief base class for Value iterators.
    908  *
    909  */
    910 class JSON_API ValueIteratorBase {
    911 public:
    912   typedef std::bidirectional_iterator_tag iterator_category;
    913   typedef unsigned int size_t;
    914   typedef int difference_type;
    915   typedef ValueIteratorBase SelfType;
    916 
    917   ValueIteratorBase();
    918 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    919   explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
    920 #else
    921   ValueIteratorBase(const ValueInternalArray::IteratorState& state);
    922   ValueIteratorBase(const ValueInternalMap::IteratorState& state);
    923 #endif
    924 
    925   bool operator==(const SelfType& other) const { return isEqual(other); }
    926 
    927   bool operator!=(const SelfType& other) const { return !isEqual(other); }
    928 
    929   difference_type operator-(const SelfType& other) const {
    930     return computeDistance(other);
    931   }
    932 
    933   /// Return either the index or the member name of the referenced value as a
    934   /// Value.
    935   Value key() const;
    936 
    937   /// Return the index of the referenced Value. -1 if it is not an arrayValue.
    938   UInt index() const;
    939 
    940   /// Return the member name of the referenced Value. "" if it is not an
    941   /// objectValue.
    942   const char* memberName() const;
    943 
    944 protected:
    945   Value& deref() const;
    946 
    947   void increment();
    948 
    949   void decrement();
    950 
    951   difference_type computeDistance(const SelfType& other) const;
    952 
    953   bool isEqual(const SelfType& other) const;
    954 
    955   void copy(const SelfType& other);
    956 
    957 private:
    958 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    959   Value::ObjectValues::iterator current_;
    960   // Indicates that iterator is for a null value.
    961   bool isNull_;
    962 #else
    963   union {
    964     ValueInternalArray::IteratorState array_;
    965     ValueInternalMap::IteratorState map_;
    966   } iterator_;
    967   bool isArray_;
    968 #endif
    969 };
    970 
    971 /** \brief const iterator for object and array value.
    972  *
    973  */
    974 class JSON_API ValueConstIterator : public ValueIteratorBase {
    975   friend class Value;
    976 
    977 public:
    978   typedef const Value value_type;
    979   typedef unsigned int size_t;
    980   typedef int difference_type;
    981   typedef const Value& reference;
    982   typedef const Value* pointer;
    983   typedef ValueConstIterator SelfType;
    984 
    985   ValueConstIterator();
    986 
    987 private:
    988 /*! \internal Use by Value to create an iterator.
    989  */
    990 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    991   explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
    992 #else
    993   ValueConstIterator(const ValueInternalArray::IteratorState& state);
    994   ValueConstIterator(const ValueInternalMap::IteratorState& state);
    995 #endif
    996 public:
    997   SelfType& operator=(const ValueIteratorBase& other);
    998 
    999   SelfType operator++(int) {
   1000     SelfType temp(*this);
   1001     ++*this;
   1002     return temp;
   1003   }
   1004 
   1005   SelfType operator--(int) {
   1006     SelfType temp(*this);
   1007     --*this;
   1008     return temp;
   1009   }
   1010 
   1011   SelfType& operator--() {
   1012     decrement();
   1013     return *this;
   1014   }
   1015 
   1016   SelfType& operator++() {
   1017     increment();
   1018     return *this;
   1019   }
   1020 
   1021   reference operator*() const { return deref(); }
   1022 
   1023   pointer operator->() const { return &deref(); }
   1024 };
   1025 
   1026 /** \brief Iterator for object and array value.
   1027  */
   1028 class JSON_API ValueIterator : public ValueIteratorBase {
   1029   friend class Value;
   1030 
   1031 public:
   1032   typedef Value value_type;
   1033   typedef unsigned int size_t;
   1034   typedef int difference_type;
   1035   typedef Value& reference;
   1036   typedef Value* pointer;
   1037   typedef ValueIterator SelfType;
   1038 
   1039   ValueIterator();
   1040   ValueIterator(const ValueConstIterator& other);
   1041   ValueIterator(const ValueIterator& other);
   1042 
   1043 private:
   1044 /*! \internal Use by Value to create an iterator.
   1045  */
   1046 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1047   explicit ValueIterator(const Value::ObjectValues::iterator& current);
   1048 #else
   1049   ValueIterator(const ValueInternalArray::IteratorState& state);
   1050   ValueIterator(const ValueInternalMap::IteratorState& state);
   1051 #endif
   1052 public:
   1053   SelfType& operator=(const SelfType& other);
   1054 
   1055   SelfType operator++(int) {
   1056     SelfType temp(*this);
   1057     ++*this;
   1058     return temp;
   1059   }
   1060 
   1061   SelfType operator--(int) {
   1062     SelfType temp(*this);
   1063     --*this;
   1064     return temp;
   1065   }
   1066 
   1067   SelfType& operator--() {
   1068     decrement();
   1069     return *this;
   1070   }
   1071 
   1072   SelfType& operator++() {
   1073     increment();
   1074     return *this;
   1075   }
   1076 
   1077   reference operator*() const { return deref(); }
   1078 
   1079   pointer operator->() const { return &deref(); }
   1080 };
   1081 
   1082 } // namespace Json
   1083 
   1084 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
   1085 #pragma warning(pop)
   1086 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
   1087 
   1088 #endif // CPPTL_JSON_H_INCLUDED
   1089