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