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