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