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