blob: f18457a892399ea4a4aa14a86c4ddd6bac5a640f [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
Aaron Jacobs68db6552014-04-23 23:41:12 +0000445 // Accessors for the [start, limit) range of bytes within the JSON text from
446 // which this value was parsed, if any.
447 void setOffsetStart( size_t start );
448 void setOffsetLimit( size_t limit );
449 size_t getOffsetStart() const;
450 size_t getOffsetLimit() const;
451
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000452 private:
453 Value &resolveReference( const char *key,
454 bool isStatic );
455
456# ifdef JSON_VALUE_USE_INTERNAL_MAP
457 inline bool isItemAvailable() const
458 {
459 return itemIsUsed_ == 0;
460 }
461
462 inline void setItemUsed( bool isUsed = true )
463 {
464 itemIsUsed_ = isUsed ? 1 : 0;
465 }
466
467 inline bool isMemberNameStatic() const
468 {
469 return memberNameIsStatic_ == 0;
470 }
471
472 inline void setMemberNameIsStatic( bool isStatic )
473 {
474 memberNameIsStatic_ = isStatic ? 1 : 0;
475 }
476# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
477
478 private:
479 struct CommentInfo
480 {
481 CommentInfo();
482 ~CommentInfo();
483
484 void setComment( const char *text );
485
486 char *comment_;
487 };
488
489 //struct MemberNamesTransform
490 //{
491 // typedef const char *result_type;
492 // const char *operator()( const CZString &name ) const
493 // {
494 // return name.c_str();
495 // }
496 //};
497
498 union ValueHolder
499 {
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000500 LargestInt int_;
501 LargestUInt uint_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000502 double real_;
503 bool bool_;
504 char *string_;
505# ifdef JSON_VALUE_USE_INTERNAL_MAP
506 ValueInternalArray *array_;
507 ValueInternalMap *map_;
508#else
509 ObjectValues *map_;
510# endif
511 } value_;
512 ValueType type_ : 8;
513 int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
514# ifdef JSON_VALUE_USE_INTERNAL_MAP
515 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
516 int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
517# endif
518 CommentInfo *comments_;
Aaron Jacobs68db6552014-04-23 23:41:12 +0000519
520 // [start, limit) byte offsets in the source JSON text from which this Value
521 // was extracted.
522 size_t start_;
523 size_t limit_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000524 };
525
526
527 /** \brief Experimental and untested: represents an element of the "path" to access a node.
528 */
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +0000529 class JSON_API PathArgument
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000530 {
531 public:
532 friend class Path;
533
534 PathArgument();
Baptiste Lepilleur201fb2c2010-04-19 07:37:41 +0000535 PathArgument( ArrayIndex index );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000536 PathArgument( const char *key );
537 PathArgument( const std::string &key );
538
539 private:
540 enum Kind
541 {
542 kindNone = 0,
543 kindIndex,
544 kindKey
545 };
546 std::string key_;
Baptiste Lepilleur201fb2c2010-04-19 07:37:41 +0000547 ArrayIndex index_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000548 Kind kind_;
549 };
550
551 /** \brief Experimental and untested: represents a "path" to access a node.
552 *
553 * Syntax:
554 * - "." => root node
555 * - ".[n]" => elements at index 'n' of root node (an array value)
556 * - ".name" => member named 'name' of root node (an object value)
557 * - ".name1.name2.name3"
558 * - ".[0][1][2].name1[3]"
559 * - ".%" => member name is provided as parameter
560 * - ".[%]" => index is provied as parameter
561 */
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +0000562 class JSON_API Path
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000563 {
564 public:
565 Path( const std::string &path,
566 const PathArgument &a1 = PathArgument(),
567 const PathArgument &a2 = PathArgument(),
568 const PathArgument &a3 = PathArgument(),
569 const PathArgument &a4 = PathArgument(),
570 const PathArgument &a5 = PathArgument() );
571
572 const Value &resolve( const Value &root ) const;
573 Value resolve( const Value &root,
574 const Value &defaultValue ) const;
575 /// Creates the "path" to access the specified node and returns a reference on the node.
576 Value &make( Value &root ) const;
577
578 private:
579 typedef std::vector<const PathArgument *> InArgs;
580 typedef std::vector<PathArgument> Args;
581
582 void makePath( const std::string &path,
583 const InArgs &in );
584 void addPathInArg( const std::string &path,
585 const InArgs &in,
586 InArgs::const_iterator &itInArg,
587 PathArgument::Kind kind );
588 void invalidPath( const std::string &path,
589 int location );
590
591 Args args_;
592 };
593
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000594
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000595
596#ifdef JSON_VALUE_USE_INTERNAL_MAP
597 /** \brief Allocator to customize Value internal map.
598 * Below is an example of a simple implementation (default implementation actually
599 * use memory pool for speed).
600 * \code
601 class DefaultValueMapAllocator : public ValueMapAllocator
602 {
603 public: // overridden from ValueMapAllocator
604 virtual ValueInternalMap *newMap()
605 {
606 return new ValueInternalMap();
607 }
608
609 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
610 {
611 return new ValueInternalMap( other );
612 }
613
614 virtual void destructMap( ValueInternalMap *map )
615 {
616 delete map;
617 }
618
619 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
620 {
621 return new ValueInternalLink[size];
622 }
623
624 virtual void releaseMapBuckets( ValueInternalLink *links )
625 {
626 delete [] links;
627 }
628
629 virtual ValueInternalLink *allocateMapLink()
630 {
631 return new ValueInternalLink();
632 }
633
634 virtual void releaseMapLink( ValueInternalLink *link )
635 {
636 delete link;
637 }
638 };
639 * \endcode
640 */
641 class JSON_API ValueMapAllocator
642 {
643 public:
644 virtual ~ValueMapAllocator();
645 virtual ValueInternalMap *newMap() = 0;
646 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
647 virtual void destructMap( ValueInternalMap *map ) = 0;
648 virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
649 virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
650 virtual ValueInternalLink *allocateMapLink() = 0;
651 virtual void releaseMapLink( ValueInternalLink *link ) = 0;
652 };
653
654 /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
655 * \internal previous_ & next_ allows for bidirectional traversal.
656 */
657 class JSON_API ValueInternalLink
658 {
659 public:
660 enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
661 enum InternalFlags {
662 flagAvailable = 0,
663 flagUsed = 1
664 };
665
666 ValueInternalLink();
667
668 ~ValueInternalLink();
669
670 Value items_[itemPerLink];
671 char *keys_[itemPerLink];
672 ValueInternalLink *previous_;
673 ValueInternalLink *next_;
674 };
675
676
677 /** \brief A linked page based hash-table implementation used internally by Value.
678 * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
679 * list in each bucket to handle collision. There is an addional twist in that
680 * each node of the collision linked list is a page containing a fixed amount of
681 * value. This provides a better compromise between memory usage and speed.
682 *
683 * Each bucket is made up of a chained list of ValueInternalLink. The last
684 * link of a given bucket can be found in the 'previous_' field of the following bucket.
685 * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
686 * Only the last link of a bucket may contains 'available' item. The last link always
687 * contains at least one element unless is it the bucket one very first link.
688 */
689 class JSON_API ValueInternalMap
690 {
691 friend class ValueIteratorBase;
692 friend class Value;
693 public:
694 typedef unsigned int HashKey;
695 typedef unsigned int BucketIndex;
696
697# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
698 struct IteratorState
699 {
Baptiste Lepilleur4a5e58c2010-01-15 14:56:59 +0000700 IteratorState()
701 : map_(0)
702 , link_(0)
703 , itemIndex_(0)
704 , bucketIndex_(0)
705 {
706 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000707 ValueInternalMap *map_;
708 ValueInternalLink *link_;
709 BucketIndex itemIndex_;
710 BucketIndex bucketIndex_;
711 };
712# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
713
714 ValueInternalMap();
715 ValueInternalMap( const ValueInternalMap &other );
716 ValueInternalMap &operator =( const ValueInternalMap &other );
717 ~ValueInternalMap();
718
719 void swap( ValueInternalMap &other );
720
721 BucketIndex size() const;
722
723 void clear();
724
725 bool reserveDelta( BucketIndex growth );
726
727 bool reserve( BucketIndex newItemCount );
728
729 const Value *find( const char *key ) const;
730
731 Value *find( const char *key );
732
733 Value &resolveReference( const char *key,
734 bool isStatic );
735
736 void remove( const char *key );
737
738 void doActualRemove( ValueInternalLink *link,
739 BucketIndex index,
740 BucketIndex bucketIndex );
741
742 ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
743
744 Value &setNewItem( const char *key,
745 bool isStatic,
746 ValueInternalLink *link,
747 BucketIndex index );
748
749 Value &unsafeAdd( const char *key,
750 bool isStatic,
751 HashKey hashedKey );
752
753 HashKey hash( const char *key ) const;
754
755 int compare( const ValueInternalMap &other ) const;
756
757 private:
758 void makeBeginIterator( IteratorState &it ) const;
759 void makeEndIterator( IteratorState &it ) const;
760 static bool equals( const IteratorState &x, const IteratorState &other );
761 static void increment( IteratorState &iterator );
762 static void incrementBucket( IteratorState &iterator );
763 static void decrement( IteratorState &iterator );
764 static const char *key( const IteratorState &iterator );
765 static const char *key( const IteratorState &iterator, bool &isStatic );
766 static Value &value( const IteratorState &iterator );
767 static int distance( const IteratorState &x, const IteratorState &y );
768
769 private:
770 ValueInternalLink *buckets_;
771 ValueInternalLink *tailLink_;
772 BucketIndex bucketsSize_;
773 BucketIndex itemCount_;
774 };
775
776 /** \brief A simplified deque implementation used internally by Value.
777 * \internal
778 * It is based on a list of fixed "page", each page contains a fixed number of items.
779 * Instead of using a linked-list, a array of pointer is used for fast item look-up.
780 * Look-up for an element is as follow:
781 * - compute page index: pageIndex = itemIndex / itemsPerPage
782 * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
783 *
784 * Insertion is amortized constant time (only the array containing the index of pointers
785 * need to be reallocated when items are appended).
786 */
787 class JSON_API ValueInternalArray
788 {
789 friend class Value;
790 friend class ValueIteratorBase;
791 public:
792 enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
793 typedef Value::ArrayIndex ArrayIndex;
794 typedef unsigned int PageIndex;
795
796# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
797 struct IteratorState // Must be a POD
798 {
Baptiste Lepilleur4a5e58c2010-01-15 14:56:59 +0000799 IteratorState()
800 : array_(0)
801 , currentPageIndex_(0)
802 , currentItemIndex_(0)
803 {
804 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000805 ValueInternalArray *array_;
806 Value **currentPageIndex_;
807 unsigned int currentItemIndex_;
808 };
809# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
810
811 ValueInternalArray();
812 ValueInternalArray( const ValueInternalArray &other );
813 ValueInternalArray &operator =( const ValueInternalArray &other );
814 ~ValueInternalArray();
815 void swap( ValueInternalArray &other );
816
817 void clear();
818 void resize( ArrayIndex newSize );
819
820 Value &resolveReference( ArrayIndex index );
821
822 Value *find( ArrayIndex index ) const;
823
824 ArrayIndex size() const;
825
826 int compare( const ValueInternalArray &other ) const;
827
828 private:
829 static bool equals( const IteratorState &x, const IteratorState &other );
830 static void increment( IteratorState &iterator );
831 static void decrement( IteratorState &iterator );
832 static Value &dereference( const IteratorState &iterator );
833 static Value &unsafeDereference( const IteratorState &iterator );
834 static int distance( const IteratorState &x, const IteratorState &y );
835 static ArrayIndex indexOf( const IteratorState &iterator );
836 void makeBeginIterator( IteratorState &it ) const;
837 void makeEndIterator( IteratorState &it ) const;
838 void makeIterator( IteratorState &it, ArrayIndex index ) const;
839
840 void makeIndexValid( ArrayIndex index );
841
842 Value **pages_;
843 ArrayIndex size_;
844 PageIndex pageCount_;
845 };
846
Baptiste Lepilleur0c5fff12010-03-11 20:23:07 +0000847 /** \brief Experimental: do not use. Allocator to customize Value internal array.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000848 * Below is an example of a simple implementation (actual implementation use
849 * memory pool).
850 \code
851class DefaultValueArrayAllocator : public ValueArrayAllocator
852{
853public: // overridden from ValueArrayAllocator
854 virtual ~DefaultValueArrayAllocator()
855 {
856 }
857
858 virtual ValueInternalArray *newArray()
859 {
860 return new ValueInternalArray();
861 }
862
863 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
864 {
865 return new ValueInternalArray( other );
866 }
867
868 virtual void destruct( ValueInternalArray *array )
869 {
870 delete array;
871 }
872
873 virtual void reallocateArrayPageIndex( Value **&indexes,
874 ValueInternalArray::PageIndex &indexCount,
875 ValueInternalArray::PageIndex minNewIndexCount )
876 {
877 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
878 if ( minNewIndexCount > newIndexCount )
879 newIndexCount = minNewIndexCount;
880 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
881 if ( !newIndexes )
882 throw std::bad_alloc();
883 indexCount = newIndexCount;
884 indexes = static_cast<Value **>( newIndexes );
885 }
886 virtual void releaseArrayPageIndex( Value **indexes,
887 ValueInternalArray::PageIndex indexCount )
888 {
889 if ( indexes )
890 free( indexes );
891 }
892
893 virtual Value *allocateArrayPage()
894 {
895 return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
896 }
897
898 virtual void releaseArrayPage( Value *value )
899 {
900 if ( value )
901 free( value );
902 }
903};
904 \endcode
905 */
906 class JSON_API ValueArrayAllocator
907 {
908 public:
909 virtual ~ValueArrayAllocator();
910 virtual ValueInternalArray *newArray() = 0;
911 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
912 virtual void destructArray( ValueInternalArray *array ) = 0;
913 /** \brief Reallocate array page index.
914 * Reallocates an array of pointer on each page.
915 * \param indexes [input] pointer on the current index. May be \c NULL.
916 * [output] pointer on the new index of at least
917 * \a minNewIndexCount pages.
918 * \param indexCount [input] current number of pages in the index.
919 * [output] number of page the reallocated index can handle.
920 * \b MUST be >= \a minNewIndexCount.
921 * \param minNewIndexCount Minimum number of page the new index must be able to
922 * handle.
923 */
924 virtual void reallocateArrayPageIndex( Value **&indexes,
925 ValueInternalArray::PageIndex &indexCount,
926 ValueInternalArray::PageIndex minNewIndexCount ) = 0;
927 virtual void releaseArrayPageIndex( Value **indexes,
928 ValueInternalArray::PageIndex indexCount ) = 0;
929 virtual Value *allocateArrayPage() = 0;
930 virtual void releaseArrayPage( Value *value ) = 0;
931 };
932#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
933
934
Baptiste Lepilleur0c5fff12010-03-11 20:23:07 +0000935 /** \brief base class for Value iterators.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000936 *
937 */
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +0000938 class JSON_API ValueIteratorBase
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000939 {
940 public:
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +0000941 typedef std::bidirectional_iterator_tag iterator_category;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000942 typedef unsigned int size_t;
943 typedef int difference_type;
944 typedef ValueIteratorBase SelfType;
945
946 ValueIteratorBase();
947#ifndef JSON_VALUE_USE_INTERNAL_MAP
948 explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
949#else
950 ValueIteratorBase( const ValueInternalArray::IteratorState &state );
951 ValueIteratorBase( const ValueInternalMap::IteratorState &state );
952#endif
953
954 bool operator ==( const SelfType &other ) const
955 {
956 return isEqual( other );
957 }
958
959 bool operator !=( const SelfType &other ) const
960 {
961 return !isEqual( other );
962 }
963
964 difference_type operator -( const SelfType &other ) const
965 {
966 return computeDistance( other );
967 }
968
969 /// Return either the index or the member name of the referenced value as a Value.
970 Value key() const;
971
972 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
Baptiste Lepilleur3a1b93b2010-02-21 14:08:17 +0000973 UInt index() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000974
975 /// Return the member name of the referenced Value. "" if it is not an objectValue.
976 const char *memberName() const;
977
978 protected:
979 Value &deref() const;
980
981 void increment();
982
983 void decrement();
984
985 difference_type computeDistance( const SelfType &other ) const;
986
987 bool isEqual( const SelfType &other ) const;
988
989 void copy( const SelfType &other );
990
991 private:
992#ifndef JSON_VALUE_USE_INTERNAL_MAP
993 Value::ObjectValues::iterator current_;
Baptiste Lepilleura1d6c9e2009-11-23 22:33:30 +0000994 // Indicates that iterator is for a null value.
995 bool isNull_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000996#else
997 union
998 {
999 ValueInternalArray::IteratorState array_;
1000 ValueInternalMap::IteratorState map_;
1001 } iterator_;
1002 bool isArray_;
1003#endif
1004 };
1005
Baptiste Lepilleur0c5fff12010-03-11 20:23:07 +00001006 /** \brief const iterator for object and array value.
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001007 *
1008 */
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +00001009 class JSON_API ValueConstIterator : public ValueIteratorBase
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001010 {
1011 friend class Value;
1012 public:
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +00001013 typedef const Value value_type;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001014 typedef unsigned int size_t;
1015 typedef int difference_type;
1016 typedef const Value &reference;
1017 typedef const Value *pointer;
1018 typedef ValueConstIterator SelfType;
1019
1020 ValueConstIterator();
1021 private:
1022 /*! \internal Use by Value to create an iterator.
1023 */
1024#ifndef JSON_VALUE_USE_INTERNAL_MAP
1025 explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
1026#else
1027 ValueConstIterator( const ValueInternalArray::IteratorState &state );
1028 ValueConstIterator( const ValueInternalMap::IteratorState &state );
1029#endif
1030 public:
1031 SelfType &operator =( const ValueIteratorBase &other );
1032
1033 SelfType operator++( int )
1034 {
1035 SelfType temp( *this );
1036 ++*this;
1037 return temp;
1038 }
1039
1040 SelfType operator--( int )
1041 {
1042 SelfType temp( *this );
1043 --*this;
1044 return temp;
1045 }
1046
1047 SelfType &operator--()
1048 {
1049 decrement();
1050 return *this;
1051 }
1052
1053 SelfType &operator++()
1054 {
1055 increment();
1056 return *this;
1057 }
1058
1059 reference operator *() const
1060 {
1061 return deref();
1062 }
1063 };
1064
1065
Baptiste Lepilleur0c5fff12010-03-11 20:23:07 +00001066 /** \brief Iterator for object and array value.
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001067 */
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +00001068 class JSON_API ValueIterator : public ValueIteratorBase
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001069 {
1070 friend class Value;
1071 public:
Baptiste Lepilleura8afdd42013-04-12 14:10:13 +00001072 typedef Value value_type;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001073 typedef unsigned int size_t;
1074 typedef int difference_type;
1075 typedef Value &reference;
1076 typedef Value *pointer;
1077 typedef ValueIterator SelfType;
1078
1079 ValueIterator();
1080 ValueIterator( const ValueConstIterator &other );
1081 ValueIterator( const ValueIterator &other );
1082 private:
1083 /*! \internal Use by Value to create an iterator.
1084 */
1085#ifndef JSON_VALUE_USE_INTERNAL_MAP
1086 explicit ValueIterator( const Value::ObjectValues::iterator &current );
1087#else
1088 ValueIterator( const ValueInternalArray::IteratorState &state );
1089 ValueIterator( const ValueInternalMap::IteratorState &state );
1090#endif
1091 public:
1092
1093 SelfType &operator =( const SelfType &other );
1094
1095 SelfType operator++( int )
1096 {
1097 SelfType temp( *this );
1098 ++*this;
1099 return temp;
1100 }
1101
1102 SelfType operator--( int )
1103 {
1104 SelfType temp( *this );
1105 --*this;
1106 return temp;
1107 }
1108
1109 SelfType &operator--()
1110 {
1111 decrement();
1112 return *this;
1113 }
1114
1115 SelfType &operator++()
1116 {
1117 increment();
1118 return *this;
1119 }
1120
1121 reference operator *() const
1122 {
1123 return deref();
1124 }
1125 };
1126
1127
1128} // namespace Json
1129
1130
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001131#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1132# pragma warning(pop)
1133#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1134
1135
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001136#endif // CPPTL_JSON_H_INCLUDED