Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-20 22:39:45

0001 #ifndef CPPTL_JSON_H_INCLUDED
0002 #define CPPTL_JSON_H_INCLUDED
0003 
0004 #include "forwards.h"
0005 #include <string>
0006 #include <vector>
0007 
0008 #ifndef JSON_USE_CPPTL_SMALLMAP
0009 #include <map>
0010 #else
0011 #include <cpptl/smallmap.h>
0012 #endif
0013 #ifdef JSON_USE_CPPTL
0014 #include <cpptl/forwards.h>
0015 #endif
0016 
0017 /** \brief JSON (JavaScript Object Notation).
0018  */
0019 
0020 namespace jsoncollector {
0021   namespace Json {
0022 
0023     /** \brief Type of the value held by a Value object.
0024     */
0025     enum ValueType {
0026       nullValue = 0,  ///< 'null' value
0027       intValue,       ///< signed integer value
0028       uintValue,      ///< unsigned integer value
0029       realValue,      ///< double value
0030       stringValue,    ///< UTF-8 string value
0031       booleanValue,   ///< bool value
0032       arrayValue,     ///< array value (ordered list)
0033       objectValue     ///< object value (collection of name/value pairs).
0034     };
0035 
0036     enum CommentPlacement {
0037       commentBefore = 0,       ///< a comment placed on the line before a value
0038       commentAfterOnSameLine,  ///< a comment just after a value on the same line
0039       commentAfter,            ///< a comment on the line after a value (only make sense for root value)
0040       numberOfCommentPlacement
0041     };
0042 
0043     //# ifdef JSON_USE_CPPTL
0044     //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
0045     //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
0046     //# endif
0047 
0048     /** \brief Lightweight wrapper to tag static string.
0049     *
0050     * Value constructor and objectValue member assignement takes advantage of the
0051     * StaticString and avoid the cost of string duplication when storing the
0052     * string or the member name.
0053     *
0054     * Example of usage:
0055     * \code
0056     * Json::Value aValue( StaticString("some text") );
0057     * Json::Value object;
0058     * static const StaticString code("code");
0059     * object[code] = 1234;
0060     * \endcode
0061     */
0062     class JSON_API StaticString {
0063     public:
0064       explicit StaticString(const char *czstring) : str_(czstring) {}
0065 
0066       operator const char *() const { return str_; }
0067 
0068       const char *c_str() const { return str_; }
0069 
0070     private:
0071       const char *str_;
0072     };
0073 
0074     /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
0075     *
0076     * This class is a discriminated union wrapper that can represents a:
0077     * - signed integer [range: Value::minInt - Value::maxInt]
0078     * - unsigned integer (range: 0 - Value::maxUInt)
0079     * - double
0080     * - UTF-8 string
0081     * - boolean
0082     * - 'null'
0083     * - an ordered list of Value
0084     * - collection of name/value pairs (javascript object)
0085     *
0086     * The type of the held value is represented by a #ValueType and 
0087     * can be obtained using type().
0088     *
0089     * values of an #objectValue or #arrayValue can be accessed using operator[]() methods. 
0090     * Non const methods will automatically create the a #nullValue element 
0091     * if it does not exist. 
0092     * The sequence of an #arrayValue will be automatically resize and initialized 
0093     * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
0094     *
0095     * The get() methods can be used to obtanis default value in the case the required element
0096     * does not exist.
0097     *
0098     * It is possible to iterate over the list of a #objectValue values using 
0099     * the getMemberNames() method.
0100     */
0101     class JSON_API Value {
0102       friend class ValueIteratorBase;
0103 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0104       friend class ValueInternalLink;
0105       friend class ValueInternalMap;
0106 #endif
0107     public:
0108       typedef std::vector<std::string> Members;
0109       typedef ValueIterator iterator;
0110       typedef ValueConstIterator const_iterator;
0111       typedef Json::UInt UInt;
0112       typedef Json::Int Int;
0113       typedef UInt ArrayIndex;
0114 
0115       static const Value null;
0116       static const Int minInt;
0117       static const Int maxInt;
0118       static const UInt maxUInt;
0119 
0120     private:
0121 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0122 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0123       class CZString {
0124       public:
0125         enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
0126         CZString(int index);
0127         CZString(const char *cstr, DuplicationPolicy allocate);
0128         CZString(const CZString &other);
0129         ~CZString();
0130         CZString &operator=(const CZString &other);
0131         bool operator<(const CZString &other) const;
0132         bool operator==(const CZString &other) const;
0133         int index() const;
0134         const char *c_str() const;
0135         bool isStaticString() const;
0136 
0137       private:
0138         void swap(CZString &other);
0139         const char *cstr_;
0140         int index_;
0141       };
0142 
0143     public:
0144 #ifndef JSON_USE_CPPTL_SMALLMAP
0145       typedef std::map<CZString, Value> ObjectValues;
0146 #else
0147       typedef CppTL::SmallMap<CZString, Value> ObjectValues;
0148 #endif  // ifndef JSON_USE_CPPTL_SMALLMAP
0149 #endif  // ifndef JSON_VALUE_USE_INTERNAL_MAP
0150 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0151 
0152     public:
0153       /** \brief Create a default Value of the given type.
0154 
0155         This is a very useful constructor.
0156         To create an empty array, pass arrayValue.
0157         To create an empty object, pass objectValue.
0158         Another Value can then be set to this one by assignment.
0159     This is useful since clear() and resize() will not alter types.
0160 
0161         Examples:
0162     \code
0163     Json::Value null_value; // null
0164     Json::Value arr_value(Json::arrayValue); // []
0165     Json::Value obj_value(Json::objectValue); // {}
0166     \endcode
0167       */
0168       Value(ValueType type = nullValue);
0169       Value(Int value);
0170       Value(UInt value);
0171       Value(double value);
0172       Value(const char *value);
0173       Value(const char *beginValue, const char *endValue);
0174       /** \brief Constructs a value from a static string.
0175 
0176        * Like other value string constructor but do not duplicate the string for
0177        * internal storage. The given string must remain alive after the call to this
0178        * constructor.
0179        * Example of usage:
0180        * \code
0181        * Json::Value aValue( StaticString("some text") );
0182        * \endcode
0183        */
0184       Value(const StaticString &value);
0185       Value(const std::string &value);
0186 #ifdef JSON_USE_CPPTL
0187       Value(const CppTL::ConstString &value);
0188 #endif
0189       Value(bool value);
0190       Value(const Value &other);
0191       ~Value();
0192 
0193       Value &operator=(const Value &other);
0194       /// Swap values.
0195       /// \note Currently, comments are intentionally not swapped, for
0196       /// both logic and efficiency.
0197       void swap(Value &other);
0198 
0199       ValueType type() const;
0200 
0201       bool operator<(const Value &other) const;
0202       bool operator<=(const Value &other) const;
0203       bool operator>=(const Value &other) const;
0204       bool operator>(const Value &other) const;
0205 
0206       bool operator==(const Value &other) const;
0207       bool operator!=(const Value &other) const;
0208 
0209       int compare(const Value &other);
0210 
0211       const char *asCString() const;
0212       std::string asString() const;
0213 #ifdef JSON_USE_CPPTL
0214       CppTL::ConstString asConstString() const;
0215 #endif
0216       Int asInt() const;
0217       UInt asUInt() const;
0218       double asDouble() const;
0219       bool asBool() const;
0220 
0221       bool isNull() const;
0222       bool isBool() const;
0223       bool isInt() const;
0224       bool isUInt() const;
0225       bool isIntegral() const;
0226       bool isDouble() const;
0227       bool isNumeric() const;
0228       bool isString() const;
0229       bool isArray() const;
0230       bool isObject() const;
0231 
0232       bool isConvertibleTo(ValueType other) const;
0233 
0234       /// Number of values in array or object
0235       UInt size() const;
0236 
0237       /// \brief Return true if empty array, empty object, or null;
0238       /// otherwise, false.
0239       bool empty() const;
0240 
0241       /// Return isNull()
0242       bool operator!() const;
0243 
0244       /// Remove all object members and array elements.
0245       /// \pre type() is arrayValue, objectValue, or nullValue
0246       /// \post type() is unchanged
0247       void clear();
0248 
0249       /// Resize the array to size elements.
0250       /// New elements are initialized to null.
0251       /// May only be called on nullValue or arrayValue.
0252       /// \pre type() is arrayValue or nullValue
0253       /// \post type() is arrayValue
0254       void resize(UInt size);
0255 
0256       /// Access an array element (zero based index ).
0257       /// If the array contains less than index element, then null value are inserted
0258       /// in the array so that its size is index+1.
0259       /// (You may need to say 'value[0u]' to get your compiler to distinguish
0260       ///  this from the operator[] which takes a string.)
0261       Value &operator[](UInt index);
0262       /// Access an array element (zero based index )
0263       /// (You may need to say 'value[0u]' to get your compiler to distinguish
0264       ///  this from the operator[] which takes a string.)
0265       const Value &operator[](UInt index) const;
0266       /// If the array contains at least index+1 elements, returns the element value,
0267       /// otherwise returns defaultValue.
0268       Value get(UInt index, const Value &defaultValue) const;
0269       /// Return true if index < size().
0270       bool isValidIndex(UInt index) const;
0271       /// \brief Append value to array at the end.
0272       ///
0273       /// Equivalent to jsonvalue[jsonvalue.size()] = value;
0274       Value &append(const Value &value);
0275 
0276       /// Access an object value by name, create a null member if it does not exist.
0277       Value &operator[](const char *key);
0278       /// Access an object value by name, returns null if there is no member with that name.
0279       const Value &operator[](const char *key) const;
0280       /// Access an object value by name, create a null member if it does not exist.
0281       Value &operator[](const std::string &key);
0282       /// Access an object value by name, returns null if there is no member with that name.
0283       const Value &operator[](const std::string &key) const;
0284       /** \brief Access an object value by name, create a null member if it does not exist.
0285 
0286        * If the object as no entry for that name, then the member name used to store
0287        * the new entry is not duplicated.
0288        * Example of use:
0289        * \code
0290        * Json::Value object;
0291        * static const StaticString code("code");
0292        * object[code] = 1234;
0293        * \endcode
0294        */
0295       Value &operator[](const StaticString &key);
0296 #ifdef JSON_USE_CPPTL
0297       /// Access an object value by name, create a null member if it does not exist.
0298       Value &operator[](const CppTL::ConstString &key);
0299       /// Access an object value by name, returns null if there is no member with that name.
0300       const Value &operator[](const CppTL::ConstString &key) const;
0301 #endif
0302       /// Return the member named key if it exist, defaultValue otherwise.
0303       Value get(const char *key, const Value &defaultValue) const;
0304       /// Return the member named key if it exist, defaultValue otherwise.
0305       Value get(const std::string &key, const Value &defaultValue) const;
0306 #ifdef JSON_USE_CPPTL
0307       /// Return the member named key if it exist, defaultValue otherwise.
0308       Value get(const CppTL::ConstString &key, const Value &defaultValue) const;
0309 #endif
0310       /// \brief Remove and return the named member.
0311       ///
0312       /// Do nothing if it did not exist.
0313       /// \return the removed Value, or null.
0314       /// \pre type() is objectValue or nullValue
0315       /// \post type() is unchanged
0316       Value removeMember(const char *key);
0317       /// Same as removeMember(const char*)
0318       Value removeMember(const std::string &key);
0319 
0320       /// Return true if the object has a member named key.
0321       bool isMember(const char *key) const;
0322       /// Return true if the object has a member named key.
0323       bool isMember(const std::string &key) const;
0324 #ifdef JSON_USE_CPPTL
0325       /// Return true if the object has a member named key.
0326       bool isMember(const CppTL::ConstString &key) const;
0327 #endif
0328 
0329       /// \brief Return a list of the member names.
0330       ///
0331       /// If null, return an empty list.
0332       /// \pre type() is objectValue or nullValue
0333       /// \post if type() was nullValue, it remains nullValue
0334       Members getMemberNames() const;
0335 
0336       //# ifdef JSON_USE_CPPTL
0337       //      EnumMemberNames enumMemberNames() const;
0338       //      EnumValues enumValues() const;
0339       //# endif
0340 
0341       /// Comments must be //... or /* ... */
0342       void setComment(const char *comment, CommentPlacement placement);
0343       /// Comments must be //... or /* ... */
0344       void setComment(const std::string &comment, CommentPlacement placement);
0345       bool hasComment(CommentPlacement placement) const;
0346       /// Include delimiters and embedded newlines.
0347       std::string getComment(CommentPlacement placement) const;
0348 
0349       std::string toStyledString() const;
0350 
0351       const_iterator begin() const;
0352       const_iterator end() const;
0353 
0354       iterator begin();
0355       iterator end();
0356 
0357     private:
0358       Value &resolveReference(const char *key, bool isStatic);
0359 
0360 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0361       inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
0362 
0363       inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
0364 
0365       inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
0366 
0367       inline void setMemberNameIsStatic(bool isStatic) { memberNameIsStatic_ = isStatic ? 1 : 0; }
0368 #endif  // # ifdef JSON_VALUE_USE_INTERNAL_MAP
0369 
0370     private:
0371       struct CommentInfo {
0372         CommentInfo();
0373         ~CommentInfo();
0374 
0375         void setComment(const char *text);
0376 
0377         char *comment_;
0378       };
0379 
0380       //struct MemberNamesTransform
0381       //{
0382       //   typedef const char *result_type;
0383       //   const char *operator()( const CZString &name ) const
0384       //   {
0385       //      return name.c_str();
0386       //   }
0387       //};
0388 
0389       union ValueHolder {
0390         Int int_;
0391         UInt uint_;
0392         double real_;
0393         bool bool_;
0394         char *string_;
0395 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0396         ValueInternalArray *array_;
0397         ValueInternalMap *map_;
0398 #else
0399         ObjectValues *map_;
0400 #endif
0401       } value_;
0402       ValueType type_ : 8;
0403       int allocated_ : 1;  // Notes: if declared as bool, bitfield is useless.
0404 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0405       unsigned int itemIsUsed_ : 1;  // used by the ValueInternalMap container.
0406       int memberNameIsStatic_ : 1;   // used by the ValueInternalMap container.
0407 #endif
0408       CommentInfo *comments_;
0409     };
0410 
0411     /** \brief Experimental and untested: represents an element of the "path" to access a node.
0412     */
0413     class PathArgument {
0414     public:
0415       friend class Path;
0416 
0417       PathArgument();
0418       PathArgument(UInt index);
0419       PathArgument(const char *key);
0420       PathArgument(const std::string &key);
0421 
0422     private:
0423       enum Kind { kindNone = 0, kindIndex, kindKey };
0424       std::string key_;
0425       UInt index_;
0426       Kind kind_;
0427     };
0428 
0429     /** \brief Experimental and untested: represents a "path" to access a node.
0430     *
0431     * Syntax:
0432     * - "." => root node
0433     * - ".[n]" => elements at index 'n' of root node (an array value)
0434     * - ".name" => member named 'name' of root node (an object value)
0435     * - ".name1.name2.name3"
0436     * - ".[0][1][2].name1[3]"
0437     * - ".%" => member name is provided as parameter
0438     * - ".[%]" => index is provied as parameter
0439     */
0440     class Path {
0441     public:
0442       Path(const std::string &path,
0443            const PathArgument &a1 = PathArgument(),
0444            const PathArgument &a2 = PathArgument(),
0445            const PathArgument &a3 = PathArgument(),
0446            const PathArgument &a4 = PathArgument(),
0447            const PathArgument &a5 = PathArgument());
0448 
0449       const Value &resolve(const Value &root) const;
0450       Value resolve(const Value &root, const Value &defaultValue) const;
0451       /// Creates the "path" to access the specified node and returns a reference on the node.
0452       Value &make(Value &root) const;
0453 
0454     private:
0455       typedef std::vector<const PathArgument *> InArgs;
0456       typedef std::vector<PathArgument> Args;
0457 
0458       void makePath(const std::string &path, const InArgs &in);
0459       void addPathInArg(const std::string &path,
0460                         const InArgs &in,
0461                         InArgs::const_iterator &itInArg,
0462                         PathArgument::Kind kind);
0463       void invalidPath(const std::string &path, int location);
0464 
0465       Args args_;
0466     };
0467 
0468     /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
0469     *
0470     * - makeMemberName() and releaseMemberName() are called to respectively duplicate and
0471     *   free an Json::objectValue member name.
0472     * - duplicateStringValue() and releaseStringValue() are called similarly to
0473     *   duplicate and free a Json::stringValue value.
0474     */
0475     class ValueAllocator {
0476     public:
0477       enum { unknown = (unsigned)-1 };
0478 
0479       virtual ~ValueAllocator();
0480 
0481       virtual char *makeMemberName(const char *memberName) const = 0;
0482       virtual void releaseMemberName(char *memberName) const = 0;
0483       virtual char *duplicateStringValue(const char *value, unsigned int length = unknown) const = 0;
0484       virtual void releaseStringValue(char *value) const = 0;
0485     };
0486 
0487 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0488     /** \brief Allocator to customize Value internal map.
0489     * Below is an example of a simple implementation (default implementation actually
0490     * use memory pool for speed).
0491     * \code
0492       class DefaultValueMapAllocator : public ValueMapAllocator
0493       {
0494       public: // overridden from ValueMapAllocator
0495          virtual ValueInternalMap *newMap()
0496          {
0497             return new ValueInternalMap();
0498          }
0499 
0500          virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
0501          {
0502             return new ValueInternalMap( other );
0503          }
0504 
0505          virtual void destructMap( ValueInternalMap *map )
0506          {
0507             delete map;
0508          }
0509 
0510          virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
0511          {
0512             return new ValueInternalLink[size];
0513          }
0514 
0515          virtual void releaseMapBuckets( ValueInternalLink *links )
0516          {
0517             delete [] links;
0518          }
0519 
0520          virtual ValueInternalLink *allocateMapLink()
0521          {
0522             return new ValueInternalLink();
0523          }
0524 
0525          virtual void releaseMapLink( ValueInternalLink *link )
0526          {
0527             delete link;
0528          }
0529       };
0530     * \endcode
0531     */
0532     class JSON_API ValueMapAllocator {
0533     public:
0534       virtual ~ValueMapAllocator();
0535       virtual ValueInternalMap *newMap() = 0;
0536       virtual ValueInternalMap *newMapCopy(const ValueInternalMap &other) = 0;
0537       virtual void destructMap(ValueInternalMap *map) = 0;
0538       virtual ValueInternalLink *allocateMapBuckets(unsigned int size) = 0;
0539       virtual void releaseMapBuckets(ValueInternalLink *links) = 0;
0540       virtual ValueInternalLink *allocateMapLink() = 0;
0541       virtual void releaseMapLink(ValueInternalLink *link) = 0;
0542     };
0543 
0544     /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
0545     * \internal previous_ & next_ allows for bidirectional traversal.
0546     */
0547     class JSON_API ValueInternalLink {
0548     public:
0549       enum { itemPerLink = 6 };  // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
0550       enum InternalFlags { flagAvailable = 0, flagUsed = 1 };
0551 
0552       ValueInternalLink();
0553 
0554       ~ValueInternalLink();
0555 
0556       Value items_[itemPerLink];
0557       char *keys_[itemPerLink];
0558       ValueInternalLink *previous_;
0559       ValueInternalLink *next_;
0560     };
0561 
0562     /** \brief A linked page based hash-table implementation used internally by Value.
0563     * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
0564     * list in each bucket to handle collision. There is an addional twist in that
0565     * each node of the collision linked list is a page containing a fixed amount of
0566     * value. This provides a better compromise between memory usage and speed.
0567     * 
0568     * Each bucket is made up of a chained list of ValueInternalLink. The last
0569     * link of a given bucket can be found in the 'previous_' field of the following bucket.
0570     * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
0571     * Only the last link of a bucket may contains 'available' item. The last link always
0572     * contains at least one element unless is it the bucket one very first link.
0573     */
0574     class JSON_API ValueInternalMap {
0575       friend class ValueIteratorBase;
0576       friend class Value;
0577 
0578     public:
0579       typedef unsigned int HashKey;
0580       typedef unsigned int BucketIndex;
0581 
0582 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0583       struct IteratorState {
0584         IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
0585         ValueInternalMap *map_;
0586         ValueInternalLink *link_;
0587         BucketIndex itemIndex_;
0588         BucketIndex bucketIndex_;
0589       };
0590 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0591 
0592       ValueInternalMap();
0593       ValueInternalMap(const ValueInternalMap &other);
0594       ValueInternalMap &operator=(const ValueInternalMap &other);
0595       ~ValueInternalMap();
0596 
0597       void swap(ValueInternalMap &other);
0598 
0599       BucketIndex size() const;
0600 
0601       void clear();
0602 
0603       bool reserveDelta(BucketIndex growth);
0604 
0605       bool reserve(BucketIndex newItemCount);
0606 
0607       const Value *find(const char *key) const;
0608 
0609       Value *find(const char *key);
0610 
0611       Value &resolveReference(const char *key, bool isStatic);
0612 
0613       void remove(const char *key);
0614 
0615       void doActualRemove(ValueInternalLink *link, BucketIndex index, BucketIndex bucketIndex);
0616 
0617       ValueInternalLink *&getLastLinkInBucket(BucketIndex bucketIndex);
0618 
0619       Value &setNewItem(const char *key, bool isStatic, ValueInternalLink *link, BucketIndex index);
0620 
0621       Value &unsafeAdd(const char *key, bool isStatic, HashKey hashedKey);
0622 
0623       HashKey hash(const char *key) const;
0624 
0625       int compare(const ValueInternalMap &other) const;
0626 
0627     private:
0628       void makeBeginIterator(IteratorState &it) const;
0629       void makeEndIterator(IteratorState &it) const;
0630       static bool equals(const IteratorState &x, const IteratorState &other);
0631       static void increment(IteratorState &iterator);
0632       static void incrementBucket(IteratorState &iterator);
0633       static void decrement(IteratorState &iterator);
0634       static const char *key(const IteratorState &iterator);
0635       static const char *key(const IteratorState &iterator, bool &isStatic);
0636       static Value &value(const IteratorState &iterator);
0637       static int distance(const IteratorState &x, const IteratorState &y);
0638 
0639     private:
0640       ValueInternalLink *buckets_;
0641       ValueInternalLink *tailLink_;
0642       BucketIndex bucketsSize_;
0643       BucketIndex itemCount_;
0644     };
0645 
0646     /** \brief A simplified deque implementation used internally by Value.
0647    * \internal
0648    * It is based on a list of fixed "page", each page contains a fixed number of items.
0649    * Instead of using a linked-list, a array of pointer is used for fast item look-up.
0650    * Look-up for an element is as follow:
0651    * - compute page index: pageIndex = itemIndex / itemsPerPage
0652    * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
0653    *
0654    * Insertion is amortized constant time (only the array containing the index of pointers
0655    * need to be reallocated when items are appended).
0656    */
0657     class JSON_API ValueInternalArray {
0658       friend class Value;
0659       friend class ValueIteratorBase;
0660 
0661     public:
0662       enum { itemsPerPage = 8 };  // should be a power of 2 for fast divide and modulo.
0663       typedef Value::ArrayIndex ArrayIndex;
0664       typedef unsigned int PageIndex;
0665 
0666 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0667       struct IteratorState  // Must be a POD
0668       {
0669         IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
0670         ValueInternalArray *array_;
0671         Value **currentPageIndex_;
0672         unsigned int currentItemIndex_;
0673       };
0674 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0675 
0676       ValueInternalArray();
0677       ValueInternalArray(const ValueInternalArray &other);
0678       ValueInternalArray &operator=(const ValueInternalArray &other);
0679       ~ValueInternalArray();
0680       void swap(ValueInternalArray &other);
0681 
0682       void clear();
0683       void resize(ArrayIndex newSize);
0684 
0685       Value &resolveReference(ArrayIndex index);
0686 
0687       Value *find(ArrayIndex index) const;
0688 
0689       ArrayIndex size() const;
0690 
0691       int compare(const ValueInternalArray &other) const;
0692 
0693     private:
0694       static bool equals(const IteratorState &x, const IteratorState &other);
0695       static void increment(IteratorState &iterator);
0696       static void decrement(IteratorState &iterator);
0697       static Value &dereference(const IteratorState &iterator);
0698       static Value &unsafeDereference(const IteratorState &iterator);
0699       static int distance(const IteratorState &x, const IteratorState &y);
0700       static ArrayIndex indexOf(const IteratorState &iterator);
0701       void makeBeginIterator(IteratorState &it) const;
0702       void makeEndIterator(IteratorState &it) const;
0703       void makeIterator(IteratorState &it, ArrayIndex index) const;
0704 
0705       void makeIndexValid(ArrayIndex index);
0706 
0707       Value **pages_;
0708       ArrayIndex size_;
0709       PageIndex pageCount_;
0710     };
0711 
0712     /** \brief Experimental: do not use. Allocator to customize Value internal array.
0713     * Below is an example of a simple implementation (actual implementation use
0714     * memory pool).
0715       \code
0716 class DefaultValueArrayAllocator : public ValueArrayAllocator
0717 {
0718 public: // overridden from ValueArrayAllocator
0719    virtual ~DefaultValueArrayAllocator()
0720    {
0721    }
0722 
0723    virtual ValueInternalArray *newArray()
0724    {
0725       return new ValueInternalArray();
0726    }
0727 
0728    virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
0729    {
0730       return new ValueInternalArray( other );
0731    }
0732 
0733    virtual void destruct( ValueInternalArray *array )
0734    {
0735       delete array;
0736    }
0737 
0738    virtual void reallocateArrayPageIndex( Value **&indexes, 
0739                                           ValueInternalArray::PageIndex &indexCount,
0740                                           ValueInternalArray::PageIndex minNewIndexCount )
0741    {
0742       ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
0743       if ( minNewIndexCount > newIndexCount )
0744          newIndexCount = minNewIndexCount;
0745       void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
0746       if ( !newIndexes )
0747          throw std::bad_alloc();
0748       indexCount = newIndexCount;
0749       indexes = static_cast<Value **>( newIndexes );
0750    }
0751    virtual void releaseArrayPageIndex( Value **indexes, 
0752                                        ValueInternalArray::PageIndex indexCount )
0753    {
0754       if ( indexes )
0755          free( indexes );
0756    }
0757 
0758    virtual Value *allocateArrayPage()
0759    {
0760       return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
0761    }
0762 
0763    virtual void releaseArrayPage( Value *value )
0764    {
0765       if ( value )
0766          free( value );
0767    }
0768 };
0769       \endcode
0770     */
0771     class JSON_API ValueArrayAllocator {
0772     public:
0773       virtual ~ValueArrayAllocator();
0774       virtual ValueInternalArray *newArray() = 0;
0775       virtual ValueInternalArray *newArrayCopy(const ValueInternalArray &other) = 0;
0776       virtual void destructArray(ValueInternalArray *array) = 0;
0777       /** \brief Reallocate array page index.
0778        * Reallocates an array of pointer on each page.
0779        * \param indexes [input] pointer on the current index. May be \c NULL.
0780        *                [output] pointer on the new index of at least 
0781        *                         \a minNewIndexCount pages. 
0782        * \param indexCount [input] current number of pages in the index.
0783        *                   [output] number of page the reallocated index can handle.
0784        *                            \b MUST be >= \a minNewIndexCount.
0785        * \param minNewIndexCount Minimum number of page the new index must be able to
0786        *                         handle.
0787        */
0788       virtual void reallocateArrayPageIndex(Value **&indexes,
0789                                             ValueInternalArray::PageIndex &indexCount,
0790                                             ValueInternalArray::PageIndex minNewIndexCount) = 0;
0791       virtual void releaseArrayPageIndex(Value **indexes, ValueInternalArray::PageIndex indexCount) = 0;
0792       virtual Value *allocateArrayPage() = 0;
0793       virtual void releaseArrayPage(Value *value) = 0;
0794     };
0795 #endif  // #ifdef JSON_VALUE_USE_INTERNAL_MAP
0796 
0797     /** \brief base class for Value iterators.
0798     *
0799     */
0800     class ValueIteratorBase {
0801     public:
0802       typedef unsigned int size_t;
0803       typedef int difference_type;
0804       typedef ValueIteratorBase SelfType;
0805 
0806       ValueIteratorBase();
0807 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0808       explicit ValueIteratorBase(const Value::ObjectValues::iterator &current);
0809 #else
0810       ValueIteratorBase(const ValueInternalArray::IteratorState &state);
0811       ValueIteratorBase(const ValueInternalMap::IteratorState &state);
0812 #endif
0813 
0814       bool operator==(const SelfType &other) const { return isEqual(other); }
0815 
0816       bool operator!=(const SelfType &other) const { return !isEqual(other); }
0817 
0818       difference_type operator-(const SelfType &other) const { return computeDistance(other); }
0819 
0820       /// Return either the index or the member name of the referenced value as a Value.
0821       Value key() const;
0822 
0823       /// Return the index of the referenced Value. -1 if it is not an arrayValue.
0824       UInt index() const;
0825 
0826       /// Return the member name of the referenced Value. "" if it is not an objectValue.
0827       const char *memberName() const;
0828 
0829     protected:
0830       Value &deref() const;
0831 
0832       void increment();
0833 
0834       void decrement();
0835 
0836       difference_type computeDistance(const SelfType &other) const;
0837 
0838       bool isEqual(const SelfType &other) const;
0839 
0840       void copy(const SelfType &other);
0841 
0842     private:
0843 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0844       Value::ObjectValues::iterator current_;
0845       // Indicates that iterator is for a null value.
0846       bool isNull_;
0847 #else
0848       union {
0849         ValueInternalArray::IteratorState array_;
0850         ValueInternalMap::IteratorState map_;
0851       } iterator_;
0852       bool isArray_;
0853 #endif
0854     };
0855 
0856     /** \brief const iterator for object and array value.
0857     *
0858     */
0859     class ValueConstIterator : public ValueIteratorBase {
0860       friend class Value;
0861 
0862     public:
0863       typedef unsigned int size_t;
0864       typedef int difference_type;
0865       typedef const Value &reference;
0866       typedef const Value *pointer;
0867       typedef ValueConstIterator SelfType;
0868 
0869       ValueConstIterator();
0870 
0871     private:
0872       /*! \internal Use by Value to create an iterator.
0873        */
0874 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0875       explicit ValueConstIterator(const Value::ObjectValues::iterator &current);
0876 #else
0877       ValueConstIterator(const ValueInternalArray::IteratorState &state);
0878       ValueConstIterator(const ValueInternalMap::IteratorState &state);
0879 #endif
0880     public:
0881       SelfType &operator=(const ValueIteratorBase &other);
0882 
0883       SelfType operator++(int) {
0884         SelfType temp(*this);
0885         ++*this;
0886         return temp;
0887       }
0888 
0889       SelfType operator--(int) {
0890         SelfType temp(*this);
0891         --*this;
0892         return temp;
0893       }
0894 
0895       SelfType &operator--() {
0896         decrement();
0897         return *this;
0898       }
0899 
0900       SelfType &operator++() {
0901         increment();
0902         return *this;
0903       }
0904 
0905       reference operator*() const { return deref(); }
0906     };
0907 
0908     /** \brief Iterator for object and array value.
0909     */
0910     class ValueIterator : public ValueIteratorBase {
0911       friend class Value;
0912 
0913     public:
0914       typedef unsigned int size_t;
0915       typedef int difference_type;
0916       typedef Value &reference;
0917       typedef Value *pointer;
0918       typedef ValueIterator SelfType;
0919 
0920       ValueIterator();
0921       ValueIterator(const ValueConstIterator &other);
0922       ValueIterator(const ValueIterator &other);
0923 
0924     private:
0925       /*! \internal Use by Value to create an iterator.
0926        */
0927 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0928       explicit ValueIterator(const Value::ObjectValues::iterator &current);
0929 #else
0930       ValueIterator(const ValueInternalArray::IteratorState &state);
0931       ValueIterator(const ValueInternalMap::IteratorState &state);
0932 #endif
0933     public:
0934       SelfType &operator=(const SelfType &other);
0935 
0936       SelfType operator++(int) {
0937         SelfType temp(*this);
0938         ++*this;
0939         return temp;
0940       }
0941 
0942       SelfType operator--(int) {
0943         SelfType temp(*this);
0944         --*this;
0945         return temp;
0946       }
0947 
0948       SelfType &operator--() {
0949         decrement();
0950         return *this;
0951       }
0952 
0953       SelfType &operator++() {
0954         increment();
0955         return *this;
0956       }
0957 
0958       reference operator*() const { return deref(); }
0959     };
0960 
0961   }  // namespace Json
0962 }  // namespace jsoncollector
0963 #endif  // CPPTL_JSON_H_INCLUDED