blob: 62a323b08f26a83b46e3ceacfd781ecb818bcea5 [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
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10007#define CPPTL_JSON_H_INCLUDED
Christopher Dunn6d135cb2007-06-13 15:51:04 +00008
Baptiste Lepilleureadc4782011-05-02 21:09:30 +00009#if !defined(JSON_IS_AMALGAMATION)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100010#include "forwards.h"
Baptiste Lepilleureadc4782011-05-02 21:09:30 +000011#endif // if !defined(JSON_IS_AMALGAMATION)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100012#include <string>
13#include <vector>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000014
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100015#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
Christopher Dunn6d135cb2007-06-13 15:51:04 +000023
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100024// Disable warning C4251: <data member>: <type> needs to have dll-interface to
25// be used by...
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000026#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100027#pragma warning(push)
28#pragma warning(disable : 4251)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000029#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
30
Christopher Dunn6d135cb2007-06-13 15:51:04 +000031/** \brief JSON (JavaScript Object Notation).
32 */
33namespace Json {
34
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100035/** \brief Type of the value held by a Value object.
36 */
37enum ValueType {
38 nullValue = 0, ///< 'null' value
39 intValue, ///< signed integer value
40 uintValue, ///< unsigned integer value
41 realValue, ///< double value
42 stringValue, ///< UTF-8 string value
43 booleanValue, ///< bool value
44 arrayValue, ///< array value (ordered list)
45 objectValue ///< object value (collection of name/value pairs).
46};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000047
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100048enum CommentPlacement {
49 commentBefore = 0, ///< a comment placed on the line before a value
50 commentAfterOnSameLine, ///< a comment just after a value on the same line
51 commentAfter, ///< a comment on the line after a value (only make sense for
Aaron Jacobs3a0c4fc2014-07-01 09:20:48 +100052 /// root value)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100053 numberOfCommentPlacement
54};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000055
56//# ifdef JSON_USE_CPPTL
57// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
58// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
59//# endif
60
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100061/** \brief Lightweight wrapper to tag static string.
62 *
63 * Value constructor and objectValue member assignement takes advantage of the
64 * StaticString and avoid the cost of string duplication when storing the
65 * string or the member name.
66 *
67 * Example of usage:
68 * \code
69 * Json::Value aValue( StaticString("some text") );
70 * Json::Value object;
71 * static const StaticString code("code");
72 * object[code] = 1234;
73 * \endcode
74 */
75class JSON_API StaticString {
76public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +100077 explicit StaticString(const char* czstring) : str_(czstring) {}
Christopher Dunn6d135cb2007-06-13 15:51:04 +000078
Aaron Jacobs11086dd2014-09-15 10:15:29 +100079 operator const char*() const { return str_; }
Christopher Dunn6d135cb2007-06-13 15:51:04 +000080
Aaron Jacobs11086dd2014-09-15 10:15:29 +100081 const char* c_str() const { return str_; }
Christopher Dunn6d135cb2007-06-13 15:51:04 +000082
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100083private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +100084 const char* str_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100085};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000086
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100087/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
88 *
89 * This class is a discriminated union wrapper that can represents a:
90 * - signed integer [range: Value::minInt - Value::maxInt]
91 * - unsigned integer (range: 0 - Value::maxUInt)
92 * - double
93 * - UTF-8 string
94 * - boolean
95 * - 'null'
96 * - an ordered list of Value
97 * - collection of name/value pairs (javascript object)
98 *
99 * The type of the held value is represented by a #ValueType and
100 * can be obtained using type().
101 *
102 * values of an #objectValue or #arrayValue can be accessed using operator[]()
103 *methods.
104 * Non const methods will automatically create the a #nullValue element
105 * if it does not exist.
106 * The sequence of an #arrayValue will be automatically resize and initialized
107 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
108 *
109 * The get() methods can be used to obtanis default value in the case the
110 *required element
111 * does not exist.
112 *
113 * It is possible to iterate over the list of a #objectValue values using
114 * the getMemberNames() method.
115 */
116class JSON_API Value {
117 friend class ValueIteratorBase;
118#ifdef JSON_VALUE_USE_INTERNAL_MAP
119 friend class ValueInternalLink;
120 friend class ValueInternalMap;
121#endif
122public:
123 typedef std::vector<std::string> Members;
124 typedef ValueIterator iterator;
125 typedef ValueConstIterator const_iterator;
126 typedef Json::UInt UInt;
127 typedef Json::Int Int;
128#if defined(JSON_HAS_INT64)
129 typedef Json::UInt64 UInt64;
130 typedef Json::Int64 Int64;
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000131#endif // defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000132 typedef Json::LargestInt LargestInt;
133 typedef Json::LargestUInt LargestUInt;
134 typedef Json::ArrayIndex ArrayIndex;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000135
Christopher Dunn07f0e932015-02-10 20:45:42 -0600136 static const Value& null; ///! We regret this reference to a global instance; prefer the simpler Value().
137 static const Value& nullRef; ///! just a kludge for binary-compatibility; same as null
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000138 /// Minimum signed integer value that can be stored in a Json::Value.
139 static const LargestInt minLargestInt;
140 /// Maximum signed integer value that can be stored in a Json::Value.
141 static const LargestInt maxLargestInt;
142 /// Maximum unsigned integer value that can be stored in a Json::Value.
143 static const LargestUInt maxLargestUInt;
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000144
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000145 /// Minimum signed int value that can be stored in a Json::Value.
146 static const Int minInt;
147 /// Maximum signed int value that can be stored in a Json::Value.
148 static const Int maxInt;
149 /// Maximum unsigned int value that can be stored in a Json::Value.
150 static const UInt maxUInt;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000151
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000152#if defined(JSON_HAS_INT64)
153 /// Minimum signed 64 bits int value that can be stored in a Json::Value.
154 static const Int64 minInt64;
155 /// Maximum signed 64 bits int value that can be stored in a Json::Value.
156 static const Int64 maxInt64;
157 /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
158 static const UInt64 maxUInt64;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000159#endif // defined(JSON_HAS_INT64)
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000160
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000161private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000162#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000163#ifndef JSON_VALUE_USE_INTERNAL_MAP
164 class CZString {
165 public:
166 enum DuplicationPolicy {
167 noDuplication = 0,
168 duplicate,
169 duplicateOnCopy
170 };
171 CZString(ArrayIndex index);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000172 CZString(const char* cstr, DuplicationPolicy allocate);
173 CZString(const CZString& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000174 ~CZString();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000175 CZString& operator=(CZString other);
176 bool operator<(const CZString& other) const;
177 bool operator==(const CZString& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000178 ArrayIndex index() const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000179 const char* c_str() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000180 bool isStaticString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000181
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000182 private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000183 void swap(CZString& other);
184 const char* cstr_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000185 ArrayIndex index_;
186 };
187
188public:
189#ifndef JSON_USE_CPPTL_SMALLMAP
190 typedef std::map<CZString, Value> ObjectValues;
191#else
192 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
193#endif // ifndef JSON_USE_CPPTL_SMALLMAP
194#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000195#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
196
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000197public:
198 /** \brief Create a default Value of the given type.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000199
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000200 This is a very useful constructor.
201 To create an empty array, pass arrayValue.
202 To create an empty object, pass objectValue.
203 Another Value can then be set to this one by assignment.
204This is useful since clear() and resize() will not alter types.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000205
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000206 Examples:
207\code
208Json::Value null_value; // null
209Json::Value arr_value(Json::arrayValue); // []
210Json::Value obj_value(Json::objectValue); // {}
211\endcode
212 */
213 Value(ValueType type = nullValue);
214 Value(Int value);
215 Value(UInt value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000216#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000217 Value(Int64 value);
218 Value(UInt64 value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000219#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000220 Value(double value);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000221 Value(const char* value);
222 Value(const char* beginValue, const char* endValue);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000223 /** \brief Constructs a value from a static string.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000224
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000225 * Like other value string constructor but do not duplicate the string for
226 * internal storage. The given string must remain alive after the call to this
227 * constructor.
228 * Example of usage:
229 * \code
230 * Json::Value aValue( StaticString("some text") );
231 * \endcode
232 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000233 Value(const StaticString& value);
234 Value(const std::string& value);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000235#ifdef JSON_USE_CPPTL
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000236 Value(const CppTL::ConstString& value);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000237#endif
238 Value(bool value);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600239 /// Deep copy.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000240 Value(const Value& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000241 ~Value();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000242
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600243 // Deep copy, then swap(other).
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000244 Value& operator=(Value other);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600245 /// Swap everything.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000246 void swap(Value& other);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600247 /// Swap values but leave comments and source offsets in place.
248 void swapPayload(Value& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000249
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000250 ValueType type() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000251
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600252 /// Compare payload only, not comments etc.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000253 bool operator<(const Value& other) const;
254 bool operator<=(const Value& other) const;
255 bool operator>=(const Value& other) const;
256 bool operator>(const Value& other) const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000257 bool operator==(const Value& other) const;
258 bool operator!=(const Value& other) const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000259 int compare(const Value& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000260
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000261 const char* asCString() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000262 std::string asString() const;
263#ifdef JSON_USE_CPPTL
264 CppTL::ConstString asConstString() const;
265#endif
266 Int asInt() const;
267 UInt asUInt() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000268#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000269 Int64 asInt64() const;
270 UInt64 asUInt64() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000271#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000272 LargestInt asLargestInt() const;
273 LargestUInt asLargestUInt() const;
274 float asFloat() const;
275 double asDouble() const;
276 bool asBool() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000277
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000278 bool isNull() const;
279 bool isBool() const;
280 bool isInt() const;
281 bool isInt64() const;
282 bool isUInt() const;
283 bool isUInt64() const;
284 bool isIntegral() const;
285 bool isDouble() const;
286 bool isNumeric() const;
287 bool isString() const;
288 bool isArray() const;
289 bool isObject() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000290
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000291 bool isConvertibleTo(ValueType other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000292
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000293 /// Number of values in array or object
294 ArrayIndex size() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000295
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000296 /// \brief Return true if empty array, empty object, or null;
297 /// otherwise, false.
298 bool empty() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000299
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000300 /// Return isNull()
301 bool operator!() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000302
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000303 /// Remove all object members and array elements.
304 /// \pre type() is arrayValue, objectValue, or nullValue
305 /// \post type() is unchanged
306 void clear();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000307
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000308 /// Resize the array to size elements.
309 /// New elements are initialized to null.
310 /// May only be called on nullValue or arrayValue.
311 /// \pre type() is arrayValue or nullValue
312 /// \post type() is arrayValue
313 void resize(ArrayIndex size);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000314
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000315 /// Access an array element (zero based index ).
316 /// If the array contains less than index element, then null value are
317 /// inserted
318 /// in the array so that its size is index+1.
319 /// (You may need to say 'value[0u]' to get your compiler to distinguish
320 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000321 Value& operator[](ArrayIndex index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000322
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000323 /// Access an array element (zero based index ).
324 /// If the array contains less than index element, then null value are
325 /// inserted
326 /// in the array so that its size is index+1.
327 /// (You may need to say 'value[0u]' to get your compiler to distinguish
328 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000329 Value& operator[](int index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000330
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000331 /// Access an array element (zero based index )
332 /// (You may need to say 'value[0u]' to get your compiler to distinguish
333 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000334 const Value& operator[](ArrayIndex index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000335
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000336 /// Access an array element (zero based index )
337 /// (You may need to say 'value[0u]' to get your compiler to distinguish
338 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000339 const Value& operator[](int index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000340
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000341 /// If the array contains at least index+1 elements, returns the element
342 /// value,
343 /// otherwise returns defaultValue.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000344 Value get(ArrayIndex index, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000345 /// Return true if index < size().
346 bool isValidIndex(ArrayIndex index) const;
347 /// \brief Append value to array at the end.
348 ///
349 /// Equivalent to jsonvalue[jsonvalue.size()] = value;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000350 Value& append(const Value& value);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000351
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000352 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000353 Value& operator[](const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000354 /// Access an object value by name, returns null if there is no member with
355 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000356 const Value& operator[](const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000357 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000358 Value& operator[](const std::string& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000359 /// Access an object value by name, returns null if there is no member with
360 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000361 const Value& operator[](const std::string& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000362 /** \brief Access an object value by name, create a null member if it does not
363 exist.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000364
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000365 * If the object as no entry for that name, then the member name used to store
366 * the new entry is not duplicated.
367 * Example of use:
368 * \code
369 * Json::Value object;
370 * static const StaticString code("code");
371 * object[code] = 1234;
372 * \endcode
373 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000374 Value& operator[](const StaticString& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000375#ifdef JSON_USE_CPPTL
376 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000377 Value& operator[](const CppTL::ConstString& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000378 /// Access an object value by name, returns null if there is no member with
379 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000380 const Value& operator[](const CppTL::ConstString& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000381#endif
382 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000383 Value get(const char* key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000384 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000385 Value get(const std::string& key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000386#ifdef JSON_USE_CPPTL
387 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000388 Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000389#endif
390 /// \brief Remove and return the named member.
391 ///
392 /// Do nothing if it did not exist.
393 /// \return the removed Value, or null.
394 /// \pre type() is objectValue or nullValue
395 /// \post type() is unchanged
Christopher Dunn76746b02015-01-21 16:01:30 -0600396 /// \deprecated
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000397 Value removeMember(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000398 /// Same as removeMember(const char*)
Christopher Dunn76746b02015-01-21 16:01:30 -0600399 /// \deprecated
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000400 Value removeMember(const std::string& key);
Christopher Dunn76746b02015-01-21 16:01:30 -0600401 /** \brief Remove the named map member.
402
403 Update 'removed' iff removed.
404 \return true iff removed (no exceptions)
405 */
406 bool removeMember(const char* key, Value* removed);
Christopher Dunn9de2c2d2015-01-20 16:15:40 -0600407 /** \brief Remove the indexed array element.
408
409 O(n) expensive operations.
410 Update 'removed' iff removed.
Christopher Dunne87e41c2015-01-20 16:24:11 -0600411 \return true iff removed (no exceptions)
Christopher Dunn9de2c2d2015-01-20 16:15:40 -0600412 */
413 bool removeIndex(ArrayIndex i, Value* removed);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000414
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000415 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000416 bool isMember(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000417 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000418 bool isMember(const std::string& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000419#ifdef JSON_USE_CPPTL
420 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000421 bool isMember(const CppTL::ConstString& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000422#endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000423
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000424 /// \brief Return a list of the member names.
425 ///
426 /// If null, return an empty list.
427 /// \pre type() is objectValue or nullValue
428 /// \post if type() was nullValue, it remains nullValue
429 Members getMemberNames() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000430
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000431 //# ifdef JSON_USE_CPPTL
432 // EnumMemberNames enumMemberNames() const;
433 // EnumValues enumValues() const;
434 //# endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000435
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600436 /// \deprecated Always pass len.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000437 void setComment(const char* comment, CommentPlacement placement);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000438 /// Comments must be //... or /* ... */
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600439 void setComment(const char* comment, size_t len, CommentPlacement placement);
440 /// Comments must be //... or /* ... */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000441 void setComment(const std::string& comment, CommentPlacement placement);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000442 bool hasComment(CommentPlacement placement) const;
443 /// Include delimiters and embedded newlines.
444 std::string getComment(CommentPlacement placement) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000445
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000446 std::string toStyledString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000447
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000448 const_iterator begin() const;
449 const_iterator end() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000450
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000451 iterator begin();
452 iterator end();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000453
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000454 // Accessors for the [start, limit) range of bytes within the JSON text from
455 // which this value was parsed, if any.
456 void setOffsetStart(size_t start);
457 void setOffsetLimit(size_t limit);
458 size_t getOffsetStart() const;
459 size_t getOffsetLimit() const;
Aaron Jacobs68db6552014-04-23 23:41:12 +0000460
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000461private:
Billy Donahue8eb5d892014-11-10 01:35:42 -0500462 void initBasic(ValueType type, bool allocated = false);
463
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000464 Value& resolveReference(const char* key, bool isStatic);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000465
466#ifdef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000467 inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
468
469 inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
470
471 inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
472
473 inline void setMemberNameIsStatic(bool isStatic) {
474 memberNameIsStatic_ = isStatic ? 1 : 0;
475 }
476#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
477
478private:
479 struct CommentInfo {
480 CommentInfo();
481 ~CommentInfo();
482
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600483 void setComment(const char* text, size_t len);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000484
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000485 char* comment_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000486 };
487
488 // struct MemberNamesTransform
489 //{
490 // typedef const char *result_type;
491 // const char *operator()( const CZString &name ) const
492 // {
493 // return name.c_str();
494 // }
495 //};
496
497 union ValueHolder {
498 LargestInt int_;
499 LargestUInt uint_;
500 double real_;
501 bool bool_;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000502 char* string_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000503#ifdef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000504 ValueInternalArray* array_;
505 ValueInternalMap* map_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000506#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000507 ObjectValues* map_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000508#endif
509 } value_;
510 ValueType type_ : 8;
Christopher Dunn2bc61372015-01-24 13:42:37 -0600511 unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000512#ifdef JSON_VALUE_USE_INTERNAL_MAP
513 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
Christopher Dunn2bc61372015-01-24 13:42:37 -0600514 unsigned int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000515#endif
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000516 CommentInfo* comments_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000517
518 // [start, limit) byte offsets in the source JSON text from which this Value
519 // was extracted.
520 size_t start_;
521 size_t limit_;
522};
523
524/** \brief Experimental and untested: represents an element of the "path" to
525 * access a node.
526 */
527class JSON_API PathArgument {
528public:
529 friend class Path;
530
531 PathArgument();
532 PathArgument(ArrayIndex index);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000533 PathArgument(const char* key);
534 PathArgument(const std::string& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000535
536private:
537 enum Kind {
538 kindNone = 0,
539 kindIndex,
540 kindKey
541 };
542 std::string key_;
543 ArrayIndex index_;
544 Kind kind_;
545};
546
547/** \brief Experimental and untested: represents a "path" to access a node.
548 *
549 * Syntax:
550 * - "." => root node
551 * - ".[n]" => elements at index 'n' of root node (an array value)
552 * - ".name" => member named 'name' of root node (an object value)
553 * - ".name1.name2.name3"
554 * - ".[0][1][2].name1[3]"
555 * - ".%" => member name is provided as parameter
556 * - ".[%]" => index is provied as parameter
557 */
558class JSON_API Path {
559public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000560 Path(const std::string& path,
561 const PathArgument& a1 = PathArgument(),
562 const PathArgument& a2 = PathArgument(),
563 const PathArgument& a3 = PathArgument(),
564 const PathArgument& a4 = PathArgument(),
565 const PathArgument& a5 = PathArgument());
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000566
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000567 const Value& resolve(const Value& root) const;
568 Value resolve(const Value& root, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000569 /// Creates the "path" to access the specified node and returns a reference on
570 /// the node.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000571 Value& make(Value& root) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000572
573private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000574 typedef std::vector<const PathArgument*> InArgs;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000575 typedef std::vector<PathArgument> Args;
576
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000577 void makePath(const std::string& path, const InArgs& in);
578 void addPathInArg(const std::string& path,
579 const InArgs& in,
580 InArgs::const_iterator& itInArg,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000581 PathArgument::Kind kind);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000582 void invalidPath(const std::string& path, int location);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000583
584 Args args_;
585};
586
587#ifdef JSON_VALUE_USE_INTERNAL_MAP
588/** \brief Allocator to customize Value internal map.
589 * Below is an example of a simple implementation (default implementation
590 actually
591 * use memory pool for speed).
592 * \code
593 class DefaultValueMapAllocator : public ValueMapAllocator
594 {
595 public: // overridden from ValueMapAllocator
596 virtual ValueInternalMap *newMap()
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000597 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000598 return new ValueInternalMap();
599 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000600
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000601 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000602 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000603 return new ValueInternalMap( other );
604 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000605
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000606 virtual void destructMap( ValueInternalMap *map )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000607 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000608 delete map;
609 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000610
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000611 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
612 {
613 return new ValueInternalLink[size];
614 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000615
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000616 virtual void releaseMapBuckets( ValueInternalLink *links )
617 {
618 delete [] links;
619 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000620
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000621 virtual ValueInternalLink *allocateMapLink()
622 {
623 return new ValueInternalLink();
624 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000625
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000626 virtual void releaseMapLink( ValueInternalLink *link )
627 {
628 delete link;
629 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000630 };
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000631 * \endcode
632 */
633class JSON_API ValueMapAllocator {
634public:
635 virtual ~ValueMapAllocator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000636 virtual ValueInternalMap* newMap() = 0;
637 virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0;
638 virtual void destructMap(ValueInternalMap* map) = 0;
639 virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0;
640 virtual void releaseMapBuckets(ValueInternalLink* links) = 0;
641 virtual ValueInternalLink* allocateMapLink() = 0;
642 virtual void releaseMapLink(ValueInternalLink* link) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000643};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000644
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000645/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
646 * \internal previous_ & next_ allows for bidirectional traversal.
647 */
648class JSON_API ValueInternalLink {
649public:
650 enum {
651 itemPerLink = 6
652 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
653 enum InternalFlags {
654 flagAvailable = 0,
655 flagUsed = 1
656 };
657
658 ValueInternalLink();
659
660 ~ValueInternalLink();
661
662 Value items_[itemPerLink];
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000663 char* keys_[itemPerLink];
664 ValueInternalLink* previous_;
665 ValueInternalLink* next_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000666};
667
668/** \brief A linked page based hash-table implementation used internally by
669 *Value.
670 * \internal ValueInternalMap is a tradional bucket based hash-table, with a
671 *linked
672 * list in each bucket to handle collision. There is an addional twist in that
673 * each node of the collision linked list is a page containing a fixed amount of
674 * value. This provides a better compromise between memory usage and speed.
675 *
676 * Each bucket is made up of a chained list of ValueInternalLink. The last
677 * link of a given bucket can be found in the 'previous_' field of the following
678 *bucket.
679 * The last link of the last bucket is stored in tailLink_ as it has no
680 *following bucket.
681 * Only the last link of a bucket may contains 'available' item. The last link
682 *always
683 * contains at least one element unless is it the bucket one very first link.
684 */
685class JSON_API ValueInternalMap {
686 friend class ValueIteratorBase;
687 friend class Value;
688
689public:
690 typedef unsigned int HashKey;
691 typedef unsigned int BucketIndex;
692
693#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
694 struct IteratorState {
695 IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000696 ValueInternalMap* map_;
697 ValueInternalLink* link_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000698 BucketIndex itemIndex_;
699 BucketIndex bucketIndex_;
700 };
701#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
702
703 ValueInternalMap();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000704 ValueInternalMap(const ValueInternalMap& other);
705 ValueInternalMap& operator=(ValueInternalMap other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000706 ~ValueInternalMap();
707
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000708 void swap(ValueInternalMap& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000709
710 BucketIndex size() const;
711
712 void clear();
713
714 bool reserveDelta(BucketIndex growth);
715
716 bool reserve(BucketIndex newItemCount);
717
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000718 const Value* find(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000719
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000720 Value* find(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000721
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000722 Value& resolveReference(const char* key, bool isStatic);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000723
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000724 void remove(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000725
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000726 void doActualRemove(ValueInternalLink* link,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000727 BucketIndex index,
728 BucketIndex bucketIndex);
729
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000730 ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000731
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000732 Value& setNewItem(const char* key,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000733 bool isStatic,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000734 ValueInternalLink* link,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000735 BucketIndex index);
736
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000737 Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000738
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000739 HashKey hash(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000740
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000741 int compare(const ValueInternalMap& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000742
743private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000744 void makeBeginIterator(IteratorState& it) const;
745 void makeEndIterator(IteratorState& it) const;
746 static bool equals(const IteratorState& x, const IteratorState& other);
747 static void increment(IteratorState& iterator);
748 static void incrementBucket(IteratorState& iterator);
749 static void decrement(IteratorState& iterator);
750 static const char* key(const IteratorState& iterator);
751 static const char* key(const IteratorState& iterator, bool& isStatic);
752 static Value& value(const IteratorState& iterator);
753 static int distance(const IteratorState& x, const IteratorState& y);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000754
755private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000756 ValueInternalLink* buckets_;
757 ValueInternalLink* tailLink_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000758 BucketIndex bucketsSize_;
759 BucketIndex itemCount_;
760};
761
762/** \brief A simplified deque implementation used internally by Value.
763* \internal
764* It is based on a list of fixed "page", each page contains a fixed number of
765*items.
766* Instead of using a linked-list, a array of pointer is used for fast item
767*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
773*pointers
774* need to be reallocated when items are appended).
775*/
776class JSON_API ValueInternalArray {
777 friend class Value;
778 friend class ValueIteratorBase;
779
780public:
781 enum {
782 itemsPerPage = 8
783 }; // should be a power of 2 for fast divide and modulo.
784 typedef Value::ArrayIndex ArrayIndex;
785 typedef unsigned int PageIndex;
786
787#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
788 struct IteratorState // Must be a POD
789 {
790 IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000791 ValueInternalArray* array_;
792 Value** currentPageIndex_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000793 unsigned int currentItemIndex_;
794 };
795#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
796
797 ValueInternalArray();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000798 ValueInternalArray(const ValueInternalArray& other);
799 ValueInternalArray& operator=(ValueInternalArray other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000800 ~ValueInternalArray();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000801 void swap(ValueInternalArray& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000802
803 void clear();
804 void resize(ArrayIndex newSize);
805
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000806 Value& resolveReference(ArrayIndex index);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000807
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000808 Value* find(ArrayIndex index) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000809
810 ArrayIndex size() const;
811
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000812 int compare(const ValueInternalArray& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000813
814private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000815 static bool equals(const IteratorState& x, const IteratorState& other);
816 static void increment(IteratorState& iterator);
817 static void decrement(IteratorState& iterator);
818 static Value& dereference(const IteratorState& iterator);
819 static Value& unsafeDereference(const IteratorState& iterator);
820 static int distance(const IteratorState& x, const IteratorState& y);
821 static ArrayIndex indexOf(const IteratorState& iterator);
822 void makeBeginIterator(IteratorState& it) const;
823 void makeEndIterator(IteratorState& it) const;
824 void makeIterator(IteratorState& it, ArrayIndex index) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000825
826 void makeIndexValid(ArrayIndex index);
827
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000828 Value** pages_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000829 ArrayIndex size_;
830 PageIndex pageCount_;
831};
832
833/** \brief Experimental: do not use. Allocator to customize Value internal
834array.
835 * Below is an example of a simple implementation (actual implementation use
836 * memory pool).
837 \code
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000838class DefaultValueArrayAllocator : public ValueArrayAllocator
839{
840public: // overridden from ValueArrayAllocator
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000841virtual ~DefaultValueArrayAllocator()
842{
843}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000844
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000845virtual ValueInternalArray *newArray()
846{
847 return new ValueInternalArray();
848}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000849
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000850virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
851{
852 return new ValueInternalArray( other );
853}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000854
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000855virtual void destruct( ValueInternalArray *array )
856{
857 delete array;
858}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000859
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000860virtual void reallocateArrayPageIndex( Value **&indexes,
861 ValueInternalArray::PageIndex
862&indexCount,
863 ValueInternalArray::PageIndex
864minNewIndexCount )
865{
866 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
867 if ( minNewIndexCount > newIndexCount )
868 newIndexCount = minNewIndexCount;
869 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
870 if ( !newIndexes )
871 throw std::bad_alloc();
872 indexCount = newIndexCount;
873 indexes = static_cast<Value **>( newIndexes );
874}
875virtual void releaseArrayPageIndex( Value **indexes,
876 ValueInternalArray::PageIndex indexCount )
877{
878 if ( indexes )
879 free( indexes );
880}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000881
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000882virtual Value *allocateArrayPage()
883{
884 return static_cast<Value *>( malloc( sizeof(Value) *
885ValueInternalArray::itemsPerPage ) );
886}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000887
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000888virtual void releaseArrayPage( Value *value )
889{
890 if ( value )
891 free( value );
892}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000893};
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000894 \endcode
895 */
896class JSON_API ValueArrayAllocator {
897public:
898 virtual ~ValueArrayAllocator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000899 virtual ValueInternalArray* newArray() = 0;
900 virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0;
901 virtual void destructArray(ValueInternalArray* array) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000902 /** \brief Reallocate array page index.
903 * Reallocates an array of pointer on each page.
904 * \param indexes [input] pointer on the current index. May be \c NULL.
905 * [output] pointer on the new index of at least
906 * \a minNewIndexCount pages.
907 * \param indexCount [input] current number of pages in the index.
908 * [output] number of page the reallocated index can handle.
909 * \b MUST be >= \a minNewIndexCount.
910 * \param minNewIndexCount Minimum number of page the new index must be able
911 * to
912 * handle.
913 */
914 virtual void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000915 reallocateArrayPageIndex(Value**& indexes,
916 ValueInternalArray::PageIndex& indexCount,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000917 ValueInternalArray::PageIndex minNewIndexCount) = 0;
918 virtual void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000919 releaseArrayPageIndex(Value** indexes,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000920 ValueInternalArray::PageIndex indexCount) = 0;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000921 virtual Value* allocateArrayPage() = 0;
922 virtual void releaseArrayPage(Value* value) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000923};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000924#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
925
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000926/** \brief base class for Value iterators.
927 *
928 */
929class JSON_API ValueIteratorBase {
930public:
931 typedef std::bidirectional_iterator_tag iterator_category;
932 typedef unsigned int size_t;
933 typedef int difference_type;
934 typedef ValueIteratorBase SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000935
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000936 ValueIteratorBase();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000937#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000938 explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000939#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000940 ValueIteratorBase(const ValueInternalArray::IteratorState& state);
941 ValueIteratorBase(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000942#endif
943
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000944 bool operator==(const SelfType& other) const { return isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000945
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000946 bool operator!=(const SelfType& other) const { return !isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000947
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000948 difference_type operator-(const SelfType& other) const {
Kevin Grant4c5832a2015-02-14 20:53:35 -0800949 return other.computeDistance(*this);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000950 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000951
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000952 /// Return either the index or the member name of the referenced value as a
953 /// Value.
954 Value key() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000955
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000956 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
957 UInt index() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000958
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000959 /// Return the member name of the referenced Value. "" if it is not an
960 /// objectValue.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000961 const char* memberName() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000962
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000963protected:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000964 Value& deref() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000965
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000966 void increment();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000967
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000968 void decrement();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000969
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000970 difference_type computeDistance(const SelfType& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000971
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000972 bool isEqual(const SelfType& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000973
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000974 void copy(const SelfType& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000975
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000976private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000977#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000978 Value::ObjectValues::iterator current_;
979 // Indicates that iterator is for a null value.
980 bool isNull_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000981#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000982 union {
983 ValueInternalArray::IteratorState array_;
984 ValueInternalMap::IteratorState map_;
985 } iterator_;
986 bool isArray_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000987#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000988};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000989
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000990/** \brief const iterator for object and array value.
991 *
992 */
993class JSON_API ValueConstIterator : public ValueIteratorBase {
994 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000995
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000996public:
997 typedef const Value value_type;
998 typedef unsigned int size_t;
999 typedef int difference_type;
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001000 typedef const Value& reference;
1001 typedef const Value* pointer;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001002 typedef ValueConstIterator SelfType;
1003
1004 ValueConstIterator();
1005
1006private:
1007/*! \internal Use by Value to create an iterator.
1008 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001009#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001010 explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001011#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001012 ValueConstIterator(const ValueInternalArray::IteratorState& state);
1013 ValueConstIterator(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001014#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001015public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001016 SelfType& operator=(const ValueIteratorBase& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001017
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001018 SelfType operator++(int) {
1019 SelfType temp(*this);
1020 ++*this;
1021 return temp;
1022 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001023
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001024 SelfType operator--(int) {
1025 SelfType temp(*this);
1026 --*this;
1027 return temp;
1028 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001029
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001030 SelfType& operator--() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001031 decrement();
1032 return *this;
1033 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001034
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001035 SelfType& operator++() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001036 increment();
1037 return *this;
1038 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001039
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001040 reference operator*() const { return deref(); }
Braden McDorman540db3b2014-09-14 02:31:23 -05001041
1042 pointer operator->() const { return &deref(); }
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001043};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001044
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001045/** \brief Iterator for object and array value.
1046 */
1047class JSON_API ValueIterator : public ValueIteratorBase {
1048 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001049
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001050public:
1051 typedef Value value_type;
1052 typedef unsigned int size_t;
1053 typedef int difference_type;
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001054 typedef Value& reference;
1055 typedef Value* pointer;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001056 typedef ValueIterator SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001057
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001058 ValueIterator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001059 ValueIterator(const ValueConstIterator& other);
1060 ValueIterator(const ValueIterator& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001061
1062private:
1063/*! \internal Use by Value to create an iterator.
1064 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001065#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001066 explicit ValueIterator(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001067#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001068 ValueIterator(const ValueInternalArray::IteratorState& state);
1069 ValueIterator(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001070#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001071public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001072 SelfType& operator=(const SelfType& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001073
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001074 SelfType operator++(int) {
1075 SelfType temp(*this);
1076 ++*this;
1077 return temp;
1078 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001079
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001080 SelfType operator--(int) {
1081 SelfType temp(*this);
1082 --*this;
1083 return temp;
1084 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001085
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001086 SelfType& operator--() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001087 decrement();
1088 return *this;
1089 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001090
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001091 SelfType& operator++() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001092 increment();
1093 return *this;
1094 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001095
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001096 reference operator*() const { return deref(); }
Braden McDorman540db3b2014-09-14 02:31:23 -05001097
1098 pointer operator->() const { return &deref(); }
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001099};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001100
1101} // namespace Json
1102
datadiode9454e682015-01-20 15:25:04 -06001103
1104namespace std {
1105/// Specialize std::swap() for Json::Value.
1106template<>
1107inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
1108}
1109
1110
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001111#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001112#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001113#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1114
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001115#endif // CPPTL_JSON_H_INCLUDED