blob: efc34ac51dcaf3bfecf6bf5c25d0178d038ecb60 [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
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000136 static const Value& null;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000137 /// Minimum signed integer value that can be stored in a Json::Value.
138 static const LargestInt minLargestInt;
139 /// Maximum signed integer value that can be stored in a Json::Value.
140 static const LargestInt maxLargestInt;
141 /// Maximum unsigned integer value that can be stored in a Json::Value.
142 static const LargestUInt maxLargestUInt;
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000143
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000144 /// Minimum signed int value that can be stored in a Json::Value.
145 static const Int minInt;
146 /// Maximum signed int value that can be stored in a Json::Value.
147 static const Int maxInt;
148 /// Maximum unsigned int value that can be stored in a Json::Value.
149 static const UInt maxUInt;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000150
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000151#if defined(JSON_HAS_INT64)
152 /// Minimum signed 64 bits int value that can be stored in a Json::Value.
153 static const Int64 minInt64;
154 /// Maximum signed 64 bits int value that can be stored in a Json::Value.
155 static const Int64 maxInt64;
156 /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
157 static const UInt64 maxUInt64;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000158#endif // defined(JSON_HAS_INT64)
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000159
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000160private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000161#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000162#ifndef JSON_VALUE_USE_INTERNAL_MAP
163 class CZString {
164 public:
165 enum DuplicationPolicy {
166 noDuplication = 0,
167 duplicate,
168 duplicateOnCopy
169 };
170 CZString(ArrayIndex index);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000171 CZString(const char* cstr, DuplicationPolicy allocate);
172 CZString(const CZString& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000173 ~CZString();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000174 CZString& operator=(CZString other);
175 bool operator<(const CZString& other) const;
176 bool operator==(const CZString& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000177 ArrayIndex index() const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000178 const char* c_str() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000179 bool isStaticString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000180
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000181 private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000182 void swap(CZString& other);
183 const char* cstr_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000184 ArrayIndex index_;
185 };
186
187public:
188#ifndef JSON_USE_CPPTL_SMALLMAP
189 typedef std::map<CZString, Value> ObjectValues;
190#else
191 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
192#endif // ifndef JSON_USE_CPPTL_SMALLMAP
193#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000194#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
195
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000196public:
197 /** \brief Create a default Value of the given type.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000198
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000199 This is a very useful constructor.
200 To create an empty array, pass arrayValue.
201 To create an empty object, pass objectValue.
202 Another Value can then be set to this one by assignment.
203This is useful since clear() and resize() will not alter types.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000204
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000205 Examples:
206\code
207Json::Value null_value; // null
208Json::Value arr_value(Json::arrayValue); // []
209Json::Value obj_value(Json::objectValue); // {}
210\endcode
211 */
212 Value(ValueType type = nullValue);
213 Value(Int value);
214 Value(UInt value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000215#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000216 Value(Int64 value);
217 Value(UInt64 value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000218#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000219 Value(double value);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000220 Value(const char* value);
221 Value(const char* beginValue, const char* endValue);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000222 /** \brief Constructs a value from a static string.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000223
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000224 * Like other value string constructor but do not duplicate the string for
225 * internal storage. The given string must remain alive after the call to this
226 * constructor.
227 * Example of usage:
228 * \code
229 * Json::Value aValue( StaticString("some text") );
230 * \endcode
231 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000232 Value(const StaticString& value);
233 Value(const std::string& value);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000234#ifdef JSON_USE_CPPTL
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000235 Value(const CppTL::ConstString& value);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000236#endif
237 Value(bool value);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600238 /// Deep copy.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000239 Value(const Value& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000240 ~Value();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000241
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600242 // Deep copy, then swap(other).
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000243 Value& operator=(Value other);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600244 /// Swap everything.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000245 void swap(Value& other);
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600246 /// Swap values but leave comments and source offsets in place.
247 void swapPayload(Value& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000248
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000249 ValueType type() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000250
Christopher Dunn66eb72f2015-01-20 11:02:22 -0600251 /// Compare payload only, not comments etc.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000252 bool operator<(const Value& other) const;
253 bool operator<=(const Value& other) const;
254 bool operator>=(const Value& other) const;
255 bool operator>(const Value& other) const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000256 bool operator==(const Value& other) const;
257 bool operator!=(const Value& other) const;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000258 int compare(const Value& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000259
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000260 const char* asCString() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000261 std::string asString() const;
262#ifdef JSON_USE_CPPTL
263 CppTL::ConstString asConstString() const;
264#endif
265 Int asInt() const;
266 UInt asUInt() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000267#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000268 Int64 asInt64() const;
269 UInt64 asUInt64() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000270#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000271 LargestInt asLargestInt() const;
272 LargestUInt asLargestUInt() const;
273 float asFloat() const;
274 double asDouble() const;
275 bool asBool() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000276
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000277 bool isNull() const;
278 bool isBool() const;
279 bool isInt() const;
280 bool isInt64() const;
281 bool isUInt() const;
282 bool isUInt64() const;
283 bool isIntegral() const;
284 bool isDouble() const;
285 bool isNumeric() const;
286 bool isString() const;
287 bool isArray() const;
288 bool isObject() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000289
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000290 bool isConvertibleTo(ValueType other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000291
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000292 /// Number of values in array or object
293 ArrayIndex size() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000294
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000295 /// \brief Return true if empty array, empty object, or null;
296 /// otherwise, false.
297 bool empty() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000298
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000299 /// Return isNull()
300 bool operator!() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000301
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000302 /// Remove all object members and array elements.
303 /// \pre type() is arrayValue, objectValue, or nullValue
304 /// \post type() is unchanged
305 void clear();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000306
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000307 /// Resize the array to size elements.
308 /// New elements are initialized to null.
309 /// May only be called on nullValue or arrayValue.
310 /// \pre type() is arrayValue or nullValue
311 /// \post type() is arrayValue
312 void resize(ArrayIndex size);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000313
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000314 /// Access an array element (zero based index ).
315 /// If the array contains less than index element, then null value are
316 /// inserted
317 /// in the array so that its size is index+1.
318 /// (You may need to say 'value[0u]' to get your compiler to distinguish
319 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000320 Value& operator[](ArrayIndex index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000321
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000322 /// Access an array element (zero based index ).
323 /// If the array contains less than index element, then null value are
324 /// inserted
325 /// in the array so that its size is index+1.
326 /// (You may need to say 'value[0u]' to get your compiler to distinguish
327 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000328 Value& operator[](int index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000329
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000330 /// Access an array element (zero based index )
331 /// (You may need to say 'value[0u]' to get your compiler to distinguish
332 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000333 const Value& operator[](ArrayIndex index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000334
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000335 /// Access an array element (zero based index )
336 /// (You may need to say 'value[0u]' to get your compiler to distinguish
337 /// this from the operator[] which takes a string.)
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000338 const Value& operator[](int index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000339
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000340 /// If the array contains at least index+1 elements, returns the element
341 /// value,
342 /// otherwise returns defaultValue.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000343 Value get(ArrayIndex index, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000344 /// Return true if index < size().
345 bool isValidIndex(ArrayIndex index) const;
346 /// \brief Append value to array at the end.
347 ///
348 /// Equivalent to jsonvalue[jsonvalue.size()] = value;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000349 Value& append(const Value& value);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000350
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000351 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000352 Value& operator[](const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000353 /// Access an object value by name, returns null if there is no member with
354 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000355 const Value& operator[](const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000356 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000357 Value& operator[](const std::string& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000358 /// Access an object value by name, returns null if there is no member with
359 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000360 const Value& operator[](const std::string& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000361 /** \brief Access an object value by name, create a null member if it does not
362 exist.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000363
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000364 * If the object as no entry for that name, then the member name used to store
365 * the new entry is not duplicated.
366 * Example of use:
367 * \code
368 * Json::Value object;
369 * static const StaticString code("code");
370 * object[code] = 1234;
371 * \endcode
372 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000373 Value& operator[](const StaticString& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000374#ifdef JSON_USE_CPPTL
375 /// Access an object value by name, create a null member if it does not exist.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000376 Value& operator[](const CppTL::ConstString& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000377 /// Access an object value by name, returns null if there is no member with
378 /// that name.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000379 const Value& operator[](const CppTL::ConstString& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000380#endif
381 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000382 Value get(const char* key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000383 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000384 Value get(const std::string& key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000385#ifdef JSON_USE_CPPTL
386 /// Return the member named key if it exist, defaultValue otherwise.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000387 Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000388#endif
389 /// \brief Remove and return the named member.
390 ///
391 /// Do nothing if it did not exist.
392 /// \return the removed Value, or null.
393 /// \pre type() is objectValue or nullValue
394 /// \post type() is unchanged
Christopher Dunn76746b02015-01-21 16:01:30 -0600395 /// \deprecated
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000396 Value removeMember(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000397 /// Same as removeMember(const char*)
Christopher Dunn76746b02015-01-21 16:01:30 -0600398 /// \deprecated
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000399 Value removeMember(const std::string& key);
Christopher Dunn76746b02015-01-21 16:01:30 -0600400 /** \brief Remove the named map member.
401
402 Update 'removed' iff removed.
403 \return true iff removed (no exceptions)
404 */
405 bool removeMember(const char* key, Value* removed);
Christopher Dunn9de2c2d2015-01-20 16:15:40 -0600406 /** \brief Remove the indexed array element.
407
408 O(n) expensive operations.
409 Update 'removed' iff removed.
Christopher Dunne87e41c2015-01-20 16:24:11 -0600410 \return true iff removed (no exceptions)
Christopher Dunn9de2c2d2015-01-20 16:15:40 -0600411 */
412 bool removeIndex(ArrayIndex i, Value* removed);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000413
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000414 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000415 bool isMember(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000416 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000417 bool isMember(const std::string& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000418#ifdef JSON_USE_CPPTL
419 /// Return true if the object has a member named key.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000420 bool isMember(const CppTL::ConstString& key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000421#endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000422
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000423 /// \brief Return a list of the member names.
424 ///
425 /// If null, return an empty list.
426 /// \pre type() is objectValue or nullValue
427 /// \post if type() was nullValue, it remains nullValue
428 Members getMemberNames() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000429
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000430 //# ifdef JSON_USE_CPPTL
431 // EnumMemberNames enumMemberNames() const;
432 // EnumValues enumValues() const;
433 //# endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000434
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600435 /// \deprecated Always pass len.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000436 void setComment(const char* comment, CommentPlacement placement);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000437 /// Comments must be //... or /* ... */
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600438 void setComment(const char* comment, size_t len, CommentPlacement placement);
439 /// Comments must be //... or /* ... */
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000440 void setComment(const std::string& comment, CommentPlacement placement);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000441 bool hasComment(CommentPlacement placement) const;
442 /// Include delimiters and embedded newlines.
443 std::string getComment(CommentPlacement placement) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000444
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000445 std::string toStyledString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000446
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000447 const_iterator begin() const;
448 const_iterator end() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000449
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000450 iterator begin();
451 iterator end();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000452
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000453 // Accessors for the [start, limit) range of bytes within the JSON text from
454 // which this value was parsed, if any.
455 void setOffsetStart(size_t start);
456 void setOffsetLimit(size_t limit);
457 size_t getOffsetStart() const;
458 size_t getOffsetLimit() const;
Aaron Jacobs68db6552014-04-23 23:41:12 +0000459
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000460private:
Billy Donahue8eb5d892014-11-10 01:35:42 -0500461 void initBasic(ValueType type, bool allocated = false);
462
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000463 Value& resolveReference(const char* key, bool isStatic);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000464
465#ifdef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000466 inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
467
468 inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
469
470 inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
471
472 inline void setMemberNameIsStatic(bool isStatic) {
473 memberNameIsStatic_ = isStatic ? 1 : 0;
474 }
475#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
476
477private:
478 struct CommentInfo {
479 CommentInfo();
480 ~CommentInfo();
481
Christopher Dunn1e3149a2015-01-25 14:16:13 -0600482 void setComment(const char* text, size_t len);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000483
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000484 char* comment_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000485 };
486
487 // struct MemberNamesTransform
488 //{
489 // typedef const char *result_type;
490 // const char *operator()( const CZString &name ) const
491 // {
492 // return name.c_str();
493 // }
494 //};
495
496 union ValueHolder {
497 LargestInt int_;
498 LargestUInt uint_;
499 double real_;
500 bool bool_;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000501 char* string_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000502#ifdef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000503 ValueInternalArray* array_;
504 ValueInternalMap* map_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000505#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000506 ObjectValues* map_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000507#endif
508 } value_;
509 ValueType type_ : 8;
Christopher Dunn2bc61372015-01-24 13:42:37 -0600510 unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000511#ifdef JSON_VALUE_USE_INTERNAL_MAP
512 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
Christopher Dunn2bc61372015-01-24 13:42:37 -0600513 unsigned int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000514#endif
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000515 CommentInfo* comments_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000516
517 // [start, limit) byte offsets in the source JSON text from which this Value
518 // was extracted.
519 size_t start_;
520 size_t limit_;
521};
522
523/** \brief Experimental and untested: represents an element of the "path" to
524 * access a node.
525 */
526class JSON_API PathArgument {
527public:
528 friend class Path;
529
530 PathArgument();
531 PathArgument(ArrayIndex index);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000532 PathArgument(const char* key);
533 PathArgument(const std::string& key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000534
535private:
536 enum Kind {
537 kindNone = 0,
538 kindIndex,
539 kindKey
540 };
541 std::string key_;
542 ArrayIndex index_;
543 Kind kind_;
544};
545
546/** \brief Experimental and untested: represents a "path" to access a node.
547 *
548 * Syntax:
549 * - "." => root node
550 * - ".[n]" => elements at index 'n' of root node (an array value)
551 * - ".name" => member named 'name' of root node (an object value)
552 * - ".name1.name2.name3"
553 * - ".[0][1][2].name1[3]"
554 * - ".%" => member name is provided as parameter
555 * - ".[%]" => index is provied as parameter
556 */
557class JSON_API Path {
558public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000559 Path(const std::string& path,
560 const PathArgument& a1 = PathArgument(),
561 const PathArgument& a2 = PathArgument(),
562 const PathArgument& a3 = PathArgument(),
563 const PathArgument& a4 = PathArgument(),
564 const PathArgument& a5 = PathArgument());
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000565
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000566 const Value& resolve(const Value& root) const;
567 Value resolve(const Value& root, const Value& defaultValue) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000568 /// Creates the "path" to access the specified node and returns a reference on
569 /// the node.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000570 Value& make(Value& root) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000571
572private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000573 typedef std::vector<const PathArgument*> InArgs;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000574 typedef std::vector<PathArgument> Args;
575
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000576 void makePath(const std::string& path, const InArgs& in);
577 void addPathInArg(const std::string& path,
578 const InArgs& in,
579 InArgs::const_iterator& itInArg,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000580 PathArgument::Kind kind);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000581 void invalidPath(const std::string& path, int location);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000582
583 Args args_;
584};
585
586#ifdef JSON_VALUE_USE_INTERNAL_MAP
587/** \brief Allocator to customize Value internal map.
588 * Below is an example of a simple implementation (default implementation
589 actually
590 * use memory pool for speed).
591 * \code
592 class DefaultValueMapAllocator : public ValueMapAllocator
593 {
594 public: // overridden from ValueMapAllocator
595 virtual ValueInternalMap *newMap()
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000596 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000597 return new ValueInternalMap();
598 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000599
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000600 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000601 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000602 return new ValueInternalMap( other );
603 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000604
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000605 virtual void destructMap( ValueInternalMap *map )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000606 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000607 delete map;
608 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000609
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000610 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
611 {
612 return new ValueInternalLink[size];
613 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000614
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000615 virtual void releaseMapBuckets( ValueInternalLink *links )
616 {
617 delete [] links;
618 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000619
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000620 virtual ValueInternalLink *allocateMapLink()
621 {
622 return new ValueInternalLink();
623 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000624
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000625 virtual void releaseMapLink( ValueInternalLink *link )
626 {
627 delete link;
628 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000629 };
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000630 * \endcode
631 */
632class JSON_API ValueMapAllocator {
633public:
634 virtual ~ValueMapAllocator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000635 virtual ValueInternalMap* newMap() = 0;
636 virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0;
637 virtual void destructMap(ValueInternalMap* map) = 0;
638 virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0;
639 virtual void releaseMapBuckets(ValueInternalLink* links) = 0;
640 virtual ValueInternalLink* allocateMapLink() = 0;
641 virtual void releaseMapLink(ValueInternalLink* link) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000642};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000643
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000644/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
645 * \internal previous_ & next_ allows for bidirectional traversal.
646 */
647class JSON_API ValueInternalLink {
648public:
649 enum {
650 itemPerLink = 6
651 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
652 enum InternalFlags {
653 flagAvailable = 0,
654 flagUsed = 1
655 };
656
657 ValueInternalLink();
658
659 ~ValueInternalLink();
660
661 Value items_[itemPerLink];
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000662 char* keys_[itemPerLink];
663 ValueInternalLink* previous_;
664 ValueInternalLink* next_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000665};
666
667/** \brief A linked page based hash-table implementation used internally by
668 *Value.
669 * \internal ValueInternalMap is a tradional bucket based hash-table, with a
670 *linked
671 * list in each bucket to handle collision. There is an addional twist in that
672 * each node of the collision linked list is a page containing a fixed amount of
673 * value. This provides a better compromise between memory usage and speed.
674 *
675 * Each bucket is made up of a chained list of ValueInternalLink. The last
676 * link of a given bucket can be found in the 'previous_' field of the following
677 *bucket.
678 * The last link of the last bucket is stored in tailLink_ as it has no
679 *following bucket.
680 * Only the last link of a bucket may contains 'available' item. The last link
681 *always
682 * contains at least one element unless is it the bucket one very first link.
683 */
684class JSON_API ValueInternalMap {
685 friend class ValueIteratorBase;
686 friend class Value;
687
688public:
689 typedef unsigned int HashKey;
690 typedef unsigned int BucketIndex;
691
692#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
693 struct IteratorState {
694 IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000695 ValueInternalMap* map_;
696 ValueInternalLink* link_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000697 BucketIndex itemIndex_;
698 BucketIndex bucketIndex_;
699 };
700#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
701
702 ValueInternalMap();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000703 ValueInternalMap(const ValueInternalMap& other);
704 ValueInternalMap& operator=(ValueInternalMap other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000705 ~ValueInternalMap();
706
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000707 void swap(ValueInternalMap& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000708
709 BucketIndex size() const;
710
711 void clear();
712
713 bool reserveDelta(BucketIndex growth);
714
715 bool reserve(BucketIndex newItemCount);
716
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000717 const Value* find(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000718
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000719 Value* find(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000720
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000721 Value& resolveReference(const char* key, bool isStatic);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000722
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000723 void remove(const char* key);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000724
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000725 void doActualRemove(ValueInternalLink* link,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000726 BucketIndex index,
727 BucketIndex bucketIndex);
728
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000729 ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000730
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000731 Value& setNewItem(const char* key,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000732 bool isStatic,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000733 ValueInternalLink* link,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000734 BucketIndex index);
735
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000736 Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000737
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000738 HashKey hash(const char* key) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000739
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000740 int compare(const ValueInternalMap& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000741
742private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000743 void makeBeginIterator(IteratorState& it) const;
744 void makeEndIterator(IteratorState& it) const;
745 static bool equals(const IteratorState& x, const IteratorState& other);
746 static void increment(IteratorState& iterator);
747 static void incrementBucket(IteratorState& iterator);
748 static void decrement(IteratorState& iterator);
749 static const char* key(const IteratorState& iterator);
750 static const char* key(const IteratorState& iterator, bool& isStatic);
751 static Value& value(const IteratorState& iterator);
752 static int distance(const IteratorState& x, const IteratorState& y);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000753
754private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000755 ValueInternalLink* buckets_;
756 ValueInternalLink* tailLink_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000757 BucketIndex bucketsSize_;
758 BucketIndex itemCount_;
759};
760
761/** \brief A simplified deque implementation used internally by Value.
762* \internal
763* It is based on a list of fixed "page", each page contains a fixed number of
764*items.
765* Instead of using a linked-list, a array of pointer is used for fast item
766*look-up.
767* Look-up for an element is as follow:
768* - compute page index: pageIndex = itemIndex / itemsPerPage
769* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
770*
771* Insertion is amortized constant time (only the array containing the index of
772*pointers
773* need to be reallocated when items are appended).
774*/
775class JSON_API ValueInternalArray {
776 friend class Value;
777 friend class ValueIteratorBase;
778
779public:
780 enum {
781 itemsPerPage = 8
782 }; // should be a power of 2 for fast divide and modulo.
783 typedef Value::ArrayIndex ArrayIndex;
784 typedef unsigned int PageIndex;
785
786#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
787 struct IteratorState // Must be a POD
788 {
789 IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000790 ValueInternalArray* array_;
791 Value** currentPageIndex_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000792 unsigned int currentItemIndex_;
793 };
794#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
795
796 ValueInternalArray();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000797 ValueInternalArray(const ValueInternalArray& other);
798 ValueInternalArray& operator=(ValueInternalArray other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000799 ~ValueInternalArray();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000800 void swap(ValueInternalArray& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000801
802 void clear();
803 void resize(ArrayIndex newSize);
804
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000805 Value& resolveReference(ArrayIndex index);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000806
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000807 Value* find(ArrayIndex index) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000808
809 ArrayIndex size() const;
810
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000811 int compare(const ValueInternalArray& other) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000812
813private:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000814 static bool equals(const IteratorState& x, const IteratorState& other);
815 static void increment(IteratorState& iterator);
816 static void decrement(IteratorState& iterator);
817 static Value& dereference(const IteratorState& iterator);
818 static Value& unsafeDereference(const IteratorState& iterator);
819 static int distance(const IteratorState& x, const IteratorState& y);
820 static ArrayIndex indexOf(const IteratorState& iterator);
821 void makeBeginIterator(IteratorState& it) const;
822 void makeEndIterator(IteratorState& it) const;
823 void makeIterator(IteratorState& it, ArrayIndex index) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000824
825 void makeIndexValid(ArrayIndex index);
826
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000827 Value** pages_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000828 ArrayIndex size_;
829 PageIndex pageCount_;
830};
831
832/** \brief Experimental: do not use. Allocator to customize Value internal
833array.
834 * Below is an example of a simple implementation (actual implementation use
835 * memory pool).
836 \code
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000837class DefaultValueArrayAllocator : public ValueArrayAllocator
838{
839public: // overridden from ValueArrayAllocator
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000840virtual ~DefaultValueArrayAllocator()
841{
842}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000843
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000844virtual ValueInternalArray *newArray()
845{
846 return new ValueInternalArray();
847}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000848
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000849virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
850{
851 return new ValueInternalArray( other );
852}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000853
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000854virtual void destruct( ValueInternalArray *array )
855{
856 delete array;
857}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000858
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000859virtual void reallocateArrayPageIndex( Value **&indexes,
860 ValueInternalArray::PageIndex
861&indexCount,
862 ValueInternalArray::PageIndex
863minNewIndexCount )
864{
865 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
866 if ( minNewIndexCount > newIndexCount )
867 newIndexCount = minNewIndexCount;
868 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
869 if ( !newIndexes )
870 throw std::bad_alloc();
871 indexCount = newIndexCount;
872 indexes = static_cast<Value **>( newIndexes );
873}
874virtual void releaseArrayPageIndex( Value **indexes,
875 ValueInternalArray::PageIndex indexCount )
876{
877 if ( indexes )
878 free( indexes );
879}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000880
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000881virtual Value *allocateArrayPage()
882{
883 return static_cast<Value *>( malloc( sizeof(Value) *
884ValueInternalArray::itemsPerPage ) );
885}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000886
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000887virtual void releaseArrayPage( Value *value )
888{
889 if ( value )
890 free( value );
891}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000892};
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000893 \endcode
894 */
895class JSON_API ValueArrayAllocator {
896public:
897 virtual ~ValueArrayAllocator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000898 virtual ValueInternalArray* newArray() = 0;
899 virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0;
900 virtual void destructArray(ValueInternalArray* array) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000901 /** \brief Reallocate array page index.
902 * Reallocates an array of pointer on each page.
903 * \param indexes [input] pointer on the current index. May be \c NULL.
904 * [output] pointer on the new index of at least
905 * \a minNewIndexCount pages.
906 * \param indexCount [input] current number of pages in the index.
907 * [output] number of page the reallocated index can handle.
908 * \b MUST be >= \a minNewIndexCount.
909 * \param minNewIndexCount Minimum number of page the new index must be able
910 * to
911 * handle.
912 */
913 virtual void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000914 reallocateArrayPageIndex(Value**& indexes,
915 ValueInternalArray::PageIndex& indexCount,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000916 ValueInternalArray::PageIndex minNewIndexCount) = 0;
917 virtual void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000918 releaseArrayPageIndex(Value** indexes,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000919 ValueInternalArray::PageIndex indexCount) = 0;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000920 virtual Value* allocateArrayPage() = 0;
921 virtual void releaseArrayPage(Value* value) = 0;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000922};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000923#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
924
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000925/** \brief base class for Value iterators.
926 *
927 */
928class JSON_API ValueIteratorBase {
929public:
930 typedef std::bidirectional_iterator_tag iterator_category;
931 typedef unsigned int size_t;
932 typedef int difference_type;
933 typedef ValueIteratorBase SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000934
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000935 ValueIteratorBase();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000936#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000937 explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000938#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000939 ValueIteratorBase(const ValueInternalArray::IteratorState& state);
940 ValueIteratorBase(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000941#endif
942
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000943 bool operator==(const SelfType& other) const { return isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000944
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000945 bool operator!=(const SelfType& other) const { return !isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000946
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000947 difference_type operator-(const SelfType& other) const {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000948 return computeDistance(other);
949 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000950
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000951 /// Return either the index or the member name of the referenced value as a
952 /// Value.
953 Value key() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000954
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000955 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
956 UInt index() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000957
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000958 /// Return the member name of the referenced Value. "" if it is not an
959 /// objectValue.
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000960 const char* memberName() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000961
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000962protected:
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000963 Value& deref() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000964
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000965 void increment();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000966
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000967 void decrement();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000968
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000969 difference_type computeDistance(const SelfType& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000970
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000971 bool isEqual(const SelfType& other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000972
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000973 void copy(const SelfType& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000974
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000975private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000976#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000977 Value::ObjectValues::iterator current_;
978 // Indicates that iterator is for a null value.
979 bool isNull_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000980#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000981 union {
982 ValueInternalArray::IteratorState array_;
983 ValueInternalMap::IteratorState map_;
984 } iterator_;
985 bool isArray_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000986#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000987};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000988
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000989/** \brief const iterator for object and array value.
990 *
991 */
992class JSON_API ValueConstIterator : public ValueIteratorBase {
993 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000994
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000995public:
996 typedef const Value value_type;
997 typedef unsigned int size_t;
998 typedef int difference_type;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000999 typedef const Value& reference;
1000 typedef const Value* pointer;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001001 typedef ValueConstIterator SelfType;
1002
1003 ValueConstIterator();
1004
1005private:
1006/*! \internal Use by Value to create an iterator.
1007 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001008#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001009 explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001010#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001011 ValueConstIterator(const ValueInternalArray::IteratorState& state);
1012 ValueConstIterator(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001013#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001014public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001015 SelfType& operator=(const ValueIteratorBase& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001016
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001017 SelfType operator++(int) {
1018 SelfType temp(*this);
1019 ++*this;
1020 return temp;
1021 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001022
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001023 SelfType operator--(int) {
1024 SelfType temp(*this);
1025 --*this;
1026 return temp;
1027 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001028
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001029 SelfType& operator--() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001030 decrement();
1031 return *this;
1032 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001033
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001034 SelfType& operator++() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001035 increment();
1036 return *this;
1037 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001038
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001039 reference operator*() const { return deref(); }
Braden McDorman540db3b2014-09-14 02:31:23 -05001040
1041 pointer operator->() const { return &deref(); }
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001042};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001043
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001044/** \brief Iterator for object and array value.
1045 */
1046class JSON_API ValueIterator : public ValueIteratorBase {
1047 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001048
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001049public:
1050 typedef Value value_type;
1051 typedef unsigned int size_t;
1052 typedef int difference_type;
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001053 typedef Value& reference;
1054 typedef Value* pointer;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001055 typedef ValueIterator SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001056
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001057 ValueIterator();
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001058 ValueIterator(const ValueConstIterator& other);
1059 ValueIterator(const ValueIterator& other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001060
1061private:
1062/*! \internal Use by Value to create an iterator.
1063 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001064#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001065 explicit ValueIterator(const Value::ObjectValues::iterator& current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001066#else
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001067 ValueIterator(const ValueInternalArray::IteratorState& state);
1068 ValueIterator(const ValueInternalMap::IteratorState& state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001069#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001070public:
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001071 SelfType& operator=(const SelfType& other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001072
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001073 SelfType operator++(int) {
1074 SelfType temp(*this);
1075 ++*this;
1076 return temp;
1077 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001078
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001079 SelfType operator--(int) {
1080 SelfType temp(*this);
1081 --*this;
1082 return temp;
1083 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001084
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001085 SelfType& operator--() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001086 decrement();
1087 return *this;
1088 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001089
Aaron Jacobs11086dd2014-09-15 10:15:29 +10001090 SelfType& operator++() {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001091 increment();
1092 return *this;
1093 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001094
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001095 reference operator*() const { return deref(); }
Braden McDorman540db3b2014-09-14 02:31:23 -05001096
1097 pointer operator->() const { return &deref(); }
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001098};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001099
1100} // namespace Json
1101
datadiode9454e682015-01-20 15:25:04 -06001102
1103namespace std {
1104/// Specialize std::swap() for Json::Value.
1105template<>
1106inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
1107}
1108
1109
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001110#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001111#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001112#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1113
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001114#endif // CPPTL_JSON_H_INCLUDED