Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / jsoncpp / overrides / include / json / value.h
blob57072602034e81b674e357cefddca45ed578473b
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
6 #ifndef CPPTL_JSON_H_INCLUDED
7 # define CPPTL_JSON_H_INCLUDED
9 #if !defined(JSON_IS_AMALGAMATION)
10 # include "third_party/jsoncpp/source/include/json/forwards.h"
11 #endif // if !defined(JSON_IS_AMALGAMATION)
12 # include <string>
13 # include <vector>
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
24 /** \brief JSON (JavaScript Object Notation).
26 namespace Json {
28 /** \brief Type of the value held by a Value object.
30 enum ValueType
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).
42 enum CommentPlacement
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
50 //# ifdef JSON_USE_CPPTL
51 // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
52 // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
53 //# endif
55 /** \brief Lightweight wrapper to tag static string.
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.
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
69 class JSON_API StaticString
71 public:
72 explicit StaticString( const char *czstring )
73 : str_( czstring )
77 operator const char *() const
79 return str_;
82 const char *c_str() const
84 return str_;
87 private:
88 const char *str_;
91 /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
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)
103 * The type of the held value is represented by a #ValueType and
104 * can be obtained using type().
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.
112 * The get() methods can be used to obtanis default value in the case the required element
113 * does not exist.
115 * It is possible to iterate over the list of a #objectValue values using
116 * the getMemberNames() method.
118 class JSON_API Value
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;
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;
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;
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)
163 private:
164 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
165 # ifndef JSON_VALUE_USE_INTERNAL_MAP
166 class CZString
168 public:
169 enum DuplicationPolicy
171 noDuplication = 0,
172 duplicate,
173 duplicateOnCopy
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_;
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
200 public:
201 /** \brief Create a default Value of the given type.
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.
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
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.
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
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();
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 );
251 ValueType type() const;
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;
258 bool operator ==( const Value &other ) const;
259 bool operator !=( const Value &other ) const;
261 int compare( const Value &other ) const;
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;
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;
293 bool isConvertibleTo( ValueType other ) const;
295 /// Number of values in array or object
296 ArrayIndex size() const;
298 /// \brief Return true if empty array, empty object, or null;
299 /// otherwise, false.
300 bool empty() const;
302 /// Return isNull()
303 bool operator!() const;
305 /// Remove all object members and array elements.
306 /// \pre type() is arrayValue, objectValue, or nullValue
307 /// \post type() is unchanged
308 void clear();
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 );
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 );
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 );
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;
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;
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.
349 /// Equivalent to jsonvalue[jsonvalue.size()] = value;
350 Value &append( const Value &value );
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.
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
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.
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 );
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
408 /// \brief Return a list of the member names.
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;
415 //# ifdef JSON_USE_CPPTL
416 // EnumMemberNames enumMemberNames() const;
417 // EnumValues enumValues() const;
418 //# endif
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;
430 std::string toStyledString() const;
432 const_iterator begin() const;
433 const_iterator end() const;
435 iterator begin();
436 iterator end();
438 private:
439 Value &resolveReference( const char *key,
440 bool isStatic );
442 # ifdef JSON_VALUE_USE_INTERNAL_MAP
443 inline bool isItemAvailable() const
445 return itemIsUsed_ == 0;
448 inline void setItemUsed( bool isUsed = true )
450 itemIsUsed_ = isUsed ? 1 : 0;
453 inline bool isMemberNameStatic() const
455 return memberNameIsStatic_ == 0;
458 inline void setMemberNameIsStatic( bool isStatic )
460 memberNameIsStatic_ = isStatic ? 1 : 0;
462 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
464 private:
465 struct CommentInfo
467 CommentInfo();
468 ~CommentInfo();
470 void setComment( const char *text );
472 char *comment_;
475 //struct MemberNamesTransform
477 // typedef const char *result_type;
478 // const char *operator()( const CZString &name ) const
479 // {
480 // return name.c_str();
481 // }
482 //};
484 union ValueHolder
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 // One-bit bitfields must be unsigned to allow storing 1.
500 // They must be 32-bits to share storage with ValueHolder.
501 unsigned int allocated_ : 1;
502 # ifdef JSON_VALUE_USE_INTERNAL_MAP
503 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
504 unsigned int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
505 # endif
506 CommentInfo *comments_;
510 /** \brief Experimental and untested: represents an element of the "path" to access a node.
512 class PathArgument
514 public:
515 friend class Path;
517 PathArgument();
518 PathArgument( ArrayIndex index );
519 PathArgument( const char *key );
520 PathArgument( const std::string &key );
522 private:
523 enum Kind
525 kindNone = 0,
526 kindIndex,
527 kindKey
529 std::string key_;
530 ArrayIndex index_;
531 Kind kind_;
534 /** \brief Experimental and untested: represents a "path" to access a node.
536 * Syntax:
537 * - "." => root node
538 * - ".[n]" => elements at index 'n' of root node (an array value)
539 * - ".name" => member named 'name' of root node (an object value)
540 * - ".name1.name2.name3"
541 * - ".[0][1][2].name1[3]"
542 * - ".%" => member name is provided as parameter
543 * - ".[%]" => index is provied as parameter
545 class Path
547 public:
548 Path( const std::string &path,
549 const PathArgument &a1 = PathArgument(),
550 const PathArgument &a2 = PathArgument(),
551 const PathArgument &a3 = PathArgument(),
552 const PathArgument &a4 = PathArgument(),
553 const PathArgument &a5 = PathArgument() );
555 const Value &resolve( const Value &root ) const;
556 Value resolve( const Value &root,
557 const Value &defaultValue ) const;
558 /// Creates the "path" to access the specified node and returns a reference on the node.
559 Value &make( Value &root ) const;
561 private:
562 typedef std::vector<const PathArgument *> InArgs;
563 typedef std::vector<PathArgument> Args;
565 void makePath( const std::string &path,
566 const InArgs &in );
567 void addPathInArg( const std::string &path,
568 const InArgs &in,
569 InArgs::const_iterator &itInArg,
570 PathArgument::Kind kind );
571 void invalidPath( const std::string &path,
572 int location );
574 Args args_;
579 #ifdef JSON_VALUE_USE_INTERNAL_MAP
580 /** \brief Allocator to customize Value internal map.
581 * Below is an example of a simple implementation (default implementation actually
582 * use memory pool for speed).
583 * \code
584 class DefaultValueMapAllocator : public ValueMapAllocator
586 public: // overridden from ValueMapAllocator
587 virtual ValueInternalMap *newMap()
589 return new ValueInternalMap();
592 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
594 return new ValueInternalMap( other );
597 virtual void destructMap( ValueInternalMap *map )
599 delete map;
602 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
604 return new ValueInternalLink[size];
607 virtual void releaseMapBuckets( ValueInternalLink *links )
609 delete [] links;
612 virtual ValueInternalLink *allocateMapLink()
614 return new ValueInternalLink();
617 virtual void releaseMapLink( ValueInternalLink *link )
619 delete link;
622 * \endcode
624 class JSON_API ValueMapAllocator
626 public:
627 virtual ~ValueMapAllocator();
628 virtual ValueInternalMap *newMap() = 0;
629 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
630 virtual void destructMap( ValueInternalMap *map ) = 0;
631 virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
632 virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
633 virtual ValueInternalLink *allocateMapLink() = 0;
634 virtual void releaseMapLink( ValueInternalLink *link ) = 0;
637 /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
638 * \internal previous_ & next_ allows for bidirectional traversal.
640 class JSON_API ValueInternalLink
642 public:
643 enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
644 enum InternalFlags {
645 flagAvailable = 0,
646 flagUsed = 1
649 ValueInternalLink();
651 ~ValueInternalLink();
653 Value items_[itemPerLink];
654 char *keys_[itemPerLink];
655 ValueInternalLink *previous_;
656 ValueInternalLink *next_;
660 /** \brief A linked page based hash-table implementation used internally by Value.
661 * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
662 * list in each bucket to handle collision. There is an addional twist in that
663 * each node of the collision linked list is a page containing a fixed amount of
664 * value. This provides a better compromise between memory usage and speed.
666 * Each bucket is made up of a chained list of ValueInternalLink. The last
667 * link of a given bucket can be found in the 'previous_' field of the following bucket.
668 * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
669 * Only the last link of a bucket may contains 'available' item. The last link always
670 * contains at least one element unless is it the bucket one very first link.
672 class JSON_API ValueInternalMap
674 friend class ValueIteratorBase;
675 friend class Value;
676 public:
677 typedef unsigned int HashKey;
678 typedef unsigned int BucketIndex;
680 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
681 struct IteratorState
683 IteratorState()
684 : map_(0)
685 , link_(0)
686 , itemIndex_(0)
687 , bucketIndex_(0)
690 ValueInternalMap *map_;
691 ValueInternalLink *link_;
692 BucketIndex itemIndex_;
693 BucketIndex bucketIndex_;
695 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
697 ValueInternalMap();
698 ValueInternalMap( const ValueInternalMap &other );
699 ValueInternalMap &operator =( const ValueInternalMap &other );
700 ~ValueInternalMap();
702 void swap( ValueInternalMap &other );
704 BucketIndex size() const;
706 void clear();
708 bool reserveDelta( BucketIndex growth );
710 bool reserve( BucketIndex newItemCount );
712 const Value *find( const char *key ) const;
714 Value *find( const char *key );
716 Value &resolveReference( const char *key,
717 bool isStatic );
719 void remove( const char *key );
721 void doActualRemove( ValueInternalLink *link,
722 BucketIndex index,
723 BucketIndex bucketIndex );
725 ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
727 Value &setNewItem( const char *key,
728 bool isStatic,
729 ValueInternalLink *link,
730 BucketIndex index );
732 Value &unsafeAdd( const char *key,
733 bool isStatic,
734 HashKey hashedKey );
736 HashKey hash( const char *key ) const;
738 int compare( const ValueInternalMap &other ) const;
740 private:
741 void makeBeginIterator( IteratorState &it ) const;
742 void makeEndIterator( IteratorState &it ) const;
743 static bool equals( const IteratorState &x, const IteratorState &other );
744 static void increment( IteratorState &iterator );
745 static void incrementBucket( IteratorState &iterator );
746 static void decrement( IteratorState &iterator );
747 static const char *key( const IteratorState &iterator );
748 static const char *key( const IteratorState &iterator, bool &isStatic );
749 static Value &value( const IteratorState &iterator );
750 static int distance( const IteratorState &x, const IteratorState &y );
752 private:
753 ValueInternalLink *buckets_;
754 ValueInternalLink *tailLink_;
755 BucketIndex bucketsSize_;
756 BucketIndex itemCount_;
759 /** \brief A simplified deque implementation used internally by Value.
760 * \internal
761 * It is based on a list of fixed "page", each page contains a fixed number of items.
762 * Instead of using a linked-list, a array of pointer is used for fast item look-up.
763 * Look-up for an element is as follow:
764 * - compute page index: pageIndex = itemIndex / itemsPerPage
765 * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
767 * Insertion is amortized constant time (only the array containing the index of pointers
768 * need to be reallocated when items are appended).
770 class JSON_API ValueInternalArray
772 friend class Value;
773 friend class ValueIteratorBase;
774 public:
775 enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
776 typedef Value::ArrayIndex ArrayIndex;
777 typedef unsigned int PageIndex;
779 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
780 struct IteratorState // Must be a POD
782 IteratorState()
783 : array_(0)
784 , currentPageIndex_(0)
785 , currentItemIndex_(0)
788 ValueInternalArray *array_;
789 Value **currentPageIndex_;
790 unsigned int currentItemIndex_;
792 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
794 ValueInternalArray();
795 ValueInternalArray( const ValueInternalArray &other );
796 ValueInternalArray &operator =( const ValueInternalArray &other );
797 ~ValueInternalArray();
798 void swap( ValueInternalArray &other );
800 void clear();
801 void resize( ArrayIndex newSize );
803 Value &resolveReference( ArrayIndex index );
805 Value *find( ArrayIndex index ) const;
807 ArrayIndex size() const;
809 int compare( const ValueInternalArray &other ) const;
811 private:
812 static bool equals( const IteratorState &x, const IteratorState &other );
813 static void increment( IteratorState &iterator );
814 static void decrement( IteratorState &iterator );
815 static Value &dereference( const IteratorState &iterator );
816 static Value &unsafeDereference( const IteratorState &iterator );
817 static int distance( const IteratorState &x, const IteratorState &y );
818 static ArrayIndex indexOf( const IteratorState &iterator );
819 void makeBeginIterator( IteratorState &it ) const;
820 void makeEndIterator( IteratorState &it ) const;
821 void makeIterator( IteratorState &it, ArrayIndex index ) const;
823 void makeIndexValid( ArrayIndex index );
825 Value **pages_;
826 ArrayIndex size_;
827 PageIndex pageCount_;
830 /** \brief Experimental: do not use. Allocator to customize Value internal array.
831 * Below is an example of a simple implementation (actual implementation use
832 * memory pool).
833 \code
834 class DefaultValueArrayAllocator : public ValueArrayAllocator
836 public: // overridden from ValueArrayAllocator
837 virtual ~DefaultValueArrayAllocator()
841 virtual ValueInternalArray *newArray()
843 return new ValueInternalArray();
846 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
848 return new ValueInternalArray( other );
851 virtual void destruct( ValueInternalArray *array )
853 delete array;
856 virtual void reallocateArrayPageIndex( Value **&indexes,
857 ValueInternalArray::PageIndex &indexCount,
858 ValueInternalArray::PageIndex minNewIndexCount )
860 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
861 if ( minNewIndexCount > newIndexCount )
862 newIndexCount = minNewIndexCount;
863 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
864 if ( !newIndexes )
865 throw std::bad_alloc();
866 indexCount = newIndexCount;
867 indexes = static_cast<Value **>( newIndexes );
869 virtual void releaseArrayPageIndex( Value **indexes,
870 ValueInternalArray::PageIndex indexCount )
872 if ( indexes )
873 free( indexes );
876 virtual Value *allocateArrayPage()
878 return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
881 virtual void releaseArrayPage( Value *value )
883 if ( value )
884 free( value );
887 \endcode
889 class JSON_API ValueArrayAllocator
891 public:
892 virtual ~ValueArrayAllocator();
893 virtual ValueInternalArray *newArray() = 0;
894 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
895 virtual void destructArray( ValueInternalArray *array ) = 0;
896 /** \brief Reallocate array page index.
897 * Reallocates an array of pointer on each page.
898 * \param indexes [input] pointer on the current index. May be \c NULL.
899 * [output] pointer on the new index of at least
900 * \a minNewIndexCount pages.
901 * \param indexCount [input] current number of pages in the index.
902 * [output] number of page the reallocated index can handle.
903 * \b MUST be >= \a minNewIndexCount.
904 * \param minNewIndexCount Minimum number of page the new index must be able to
905 * handle.
907 virtual void reallocateArrayPageIndex( Value **&indexes,
908 ValueInternalArray::PageIndex &indexCount,
909 ValueInternalArray::PageIndex minNewIndexCount ) = 0;
910 virtual void releaseArrayPageIndex( Value **indexes,
911 ValueInternalArray::PageIndex indexCount ) = 0;
912 virtual Value *allocateArrayPage() = 0;
913 virtual void releaseArrayPage( Value *value ) = 0;
915 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
918 /** \brief base class for Value iterators.
921 class ValueIteratorBase
923 public:
924 typedef unsigned int size_t;
925 typedef int difference_type;
926 typedef ValueIteratorBase SelfType;
928 ValueIteratorBase();
929 #ifndef JSON_VALUE_USE_INTERNAL_MAP
930 explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
931 #else
932 ValueIteratorBase( const ValueInternalArray::IteratorState &state );
933 ValueIteratorBase( const ValueInternalMap::IteratorState &state );
934 #endif
936 bool operator ==( const SelfType &other ) const
938 return isEqual( other );
941 bool operator !=( const SelfType &other ) const
943 return !isEqual( other );
946 difference_type operator -( const SelfType &other ) const
948 return computeDistance( other );
951 /// Return either the index or the member name of the referenced value as a Value.
952 Value key() const;
954 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
955 UInt index() const;
957 /// Return the member name of the referenced Value. "" if it is not an objectValue.
958 const char *memberName() const;
960 protected:
961 Value &deref() const;
963 void increment();
965 void decrement();
967 difference_type computeDistance( const SelfType &other ) const;
969 bool isEqual( const SelfType &other ) const;
971 void copy( const SelfType &other );
973 private:
974 #ifndef JSON_VALUE_USE_INTERNAL_MAP
975 Value::ObjectValues::iterator current_;
976 // Indicates that iterator is for a null value.
977 bool isNull_;
978 #else
979 union
981 ValueInternalArray::IteratorState array_;
982 ValueInternalMap::IteratorState map_;
983 } iterator_;
984 bool isArray_;
985 #endif
988 /** \brief const iterator for object and array value.
991 class ValueConstIterator : public ValueIteratorBase
993 friend class Value;
994 public:
995 typedef unsigned int size_t;
996 typedef int difference_type;
997 typedef const Value &reference;
998 typedef const Value *pointer;
999 typedef ValueConstIterator SelfType;
1001 ValueConstIterator();
1002 private:
1003 /*! \internal Use by Value to create an iterator.
1005 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1006 explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
1007 #else
1008 ValueConstIterator( const ValueInternalArray::IteratorState &state );
1009 ValueConstIterator( const ValueInternalMap::IteratorState &state );
1010 #endif
1011 public:
1012 SelfType &operator =( const ValueIteratorBase &other );
1014 SelfType operator++( int )
1016 SelfType temp( *this );
1017 ++*this;
1018 return temp;
1021 SelfType operator--( int )
1023 SelfType temp( *this );
1024 --*this;
1025 return temp;
1028 SelfType &operator--()
1030 decrement();
1031 return *this;
1034 SelfType &operator++()
1036 increment();
1037 return *this;
1040 reference operator *() const
1042 return deref();
1047 /** \brief Iterator for object and array value.
1049 class ValueIterator : public ValueIteratorBase
1051 friend class Value;
1052 public:
1053 typedef unsigned int size_t;
1054 typedef int difference_type;
1055 typedef Value &reference;
1056 typedef Value *pointer;
1057 typedef ValueIterator SelfType;
1059 ValueIterator();
1060 ValueIterator( const ValueConstIterator &other );
1061 ValueIterator( const ValueIterator &other );
1062 private:
1063 /*! \internal Use by Value to create an iterator.
1065 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1066 explicit ValueIterator( const Value::ObjectValues::iterator &current );
1067 #else
1068 ValueIterator( const ValueInternalArray::IteratorState &state );
1069 ValueIterator( const ValueInternalMap::IteratorState &state );
1070 #endif
1071 public:
1073 SelfType &operator =( const SelfType &other );
1075 SelfType operator++( int )
1077 SelfType temp( *this );
1078 ++*this;
1079 return temp;
1082 SelfType operator--( int )
1084 SelfType temp( *this );
1085 --*this;
1086 return temp;
1089 SelfType &operator--()
1091 decrement();
1092 return *this;
1095 SelfType &operator++()
1097 increment();
1098 return *this;
1101 reference operator *() const
1103 return deref();
1108 } // namespace Json
1111 #endif // CPPTL_JSON_H_INCLUDED