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:
StaticString(const char * czstring)72       explicit StaticString( const char *czstring )
73          : str_( czstring )
74       {
75       }
76 
77       operator const char *() const
78       {
79          return str_;
80       }
81 
c_str()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
isItemAvailable()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 
isMemberNameStatic()453       inline bool isMemberNameStatic() const
454       {
455          return memberNameIsStatic_ == 0;
456       }
457 
setMemberNameIsStatic(bool isStatic)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       {
IteratorStateIteratorState681          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       {
IteratorStateIteratorState780          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