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