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