Line data Source code
1 : // 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 :
6 : #ifndef CPPTL_JSON_H_INCLUDED
7 : #define CPPTL_JSON_H_INCLUDED
8 :
9 : #if !defined(JSON_IS_AMALGAMATION)
10 : #include "forwards.h"
11 : #endif // if !defined(JSON_IS_AMALGAMATION)
12 : #include <string>
13 : #include <vector>
14 : #include <exception>
15 :
16 : #ifndef JSON_USE_CPPTL_SMALLMAP
17 : #include <map>
18 : #else
19 : #include <cpptl/smallmap.h>
20 : #endif
21 : #ifdef JSON_USE_CPPTL
22 : #include <cpptl/forwards.h>
23 : #endif
24 :
25 : //Conditional NORETURN attribute on the throw functions would:
26 : // a) suppress false positives from static code analysis
27 : // b) possibly improve optimization opportunities.
28 : #if !defined(JSONCPP_NORETURN)
29 : # if defined(_MSC_VER)
30 : # define JSONCPP_NORETURN __declspec(noreturn)
31 : # elif defined(__GNUC__)
32 : # define JSONCPP_NORETURN __attribute__ ((__noreturn__))
33 : # else
34 : # define JSONCPP_NORETURN
35 : # endif
36 : #endif
37 :
38 : // Disable warning C4251: <data member>: <type> needs to have dll-interface to
39 : // be used by...
40 : #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
41 : #pragma warning(push)
42 : #pragma warning(disable : 4251)
43 : #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
44 :
45 : #pragma pack(push, 8)
46 :
47 : /** \brief JSON (JavaScript Object Notation).
48 : */
49 : namespace Json {
50 :
51 : /** Base class for all exceptions we throw.
52 : *
53 : * We use nothing but these internally. Of course, STL can throw others.
54 : */
55 : class JSON_API Exception : public std::exception {
56 : public:
57 : Exception(JSONCPP_STRING const& msg);
58 : ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
59 : char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
60 : protected:
61 : JSONCPP_STRING msg_;
62 : };
63 :
64 : /** Exceptions which the user cannot easily avoid.
65 : *
66 : * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
67 : *
68 : * \remark derived from Json::Exception
69 : */
70 0 : class JSON_API RuntimeError : public Exception {
71 : public:
72 : RuntimeError(JSONCPP_STRING const& msg);
73 : };
74 :
75 : /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
76 : *
77 : * These are precondition-violations (user bugs) and internal errors (our bugs).
78 : *
79 : * \remark derived from Json::Exception
80 : */
81 0 : class JSON_API LogicError : public Exception {
82 : public:
83 : LogicError(JSONCPP_STRING const& msg);
84 : };
85 :
86 : /// used internally
87 : JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
88 : /// used internally
89 : JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
90 :
91 : /** \brief Type of the value held by a Value object.
92 : */
93 : enum ValueType {
94 : nullValue = 0, ///< 'null' value
95 : intValue, ///< signed integer value
96 : uintValue, ///< unsigned integer value
97 : realValue, ///< double value
98 : stringValue, ///< UTF-8 string value
99 : booleanValue, ///< bool value
100 : arrayValue, ///< array value (ordered list)
101 : objectValue ///< object value (collection of name/value pairs).
102 : };
103 :
104 : enum CommentPlacement {
105 : commentBefore = 0, ///< a comment placed on the line before a value
106 : commentAfterOnSameLine, ///< a comment just after a value on the same line
107 : commentAfter, ///< a comment on the line after a value (only make sense for
108 : /// root value)
109 : numberOfCommentPlacement
110 : };
111 :
112 : //# ifdef JSON_USE_CPPTL
113 : // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
114 : // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
115 : //# endif
116 :
117 : /** \brief Lightweight wrapper to tag static string.
118 : *
119 : * Value constructor and objectValue member assignement takes advantage of the
120 : * StaticString and avoid the cost of string duplication when storing the
121 : * string or the member name.
122 : *
123 : * Example of usage:
124 : * \code
125 : * Json::Value aValue( StaticString("some text") );
126 : * Json::Value object;
127 : * static const StaticString code("code");
128 : * object[code] = 1234;
129 : * \endcode
130 : */
131 : class JSON_API StaticString {
132 : public:
133 0 : explicit StaticString(const char* czstring) : c_str_(czstring) {}
134 :
135 : operator const char*() const { return c_str_; }
136 :
137 0 : const char* c_str() const { return c_str_; }
138 :
139 : private:
140 : const char* c_str_;
141 : };
142 :
143 : /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
144 : *
145 : * This class is a discriminated union wrapper that can represents a:
146 : * - signed integer [range: Value::minInt - Value::maxInt]
147 : * - unsigned integer (range: 0 - Value::maxUInt)
148 : * - double
149 : * - UTF-8 string
150 : * - boolean
151 : * - 'null'
152 : * - an ordered list of Value
153 : * - collection of name/value pairs (javascript object)
154 : *
155 : * The type of the held value is represented by a #ValueType and
156 : * can be obtained using type().
157 : *
158 : * Values of an #objectValue or #arrayValue can be accessed using operator[]()
159 : * methods.
160 : * Non-const methods will automatically create the a #nullValue element
161 : * if it does not exist.
162 : * The sequence of an #arrayValue will be automatically resized and initialized
163 : * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
164 : *
165 : * The get() methods can be used to obtain default value in the case the
166 : * required element does not exist.
167 : *
168 : * It is possible to iterate over the list of a #objectValue values using
169 : * the getMemberNames() method.
170 : *
171 : * \note #Value string-length fit in size_t, but keys must be < 2^30.
172 : * (The reason is an implementation detail.) A #CharReader will raise an
173 : * exception if a bound is exceeded to avoid security holes in your app,
174 : * but the Value API does *not* check bounds. That is the responsibility
175 : * of the caller.
176 : */
177 : class JSON_API Value {
178 : friend class ValueIteratorBase;
179 : public:
180 : typedef std::vector<JSONCPP_STRING> Members;
181 : typedef ValueIterator iterator;
182 : typedef ValueConstIterator const_iterator;
183 : typedef Json::UInt UInt;
184 : typedef Json::Int Int;
185 : #if defined(JSON_HAS_INT64)
186 : typedef Json::UInt64 UInt64;
187 : typedef Json::Int64 Int64;
188 : #endif // defined(JSON_HAS_INT64)
189 : typedef Json::LargestInt LargestInt;
190 : typedef Json::LargestUInt LargestUInt;
191 : typedef Json::ArrayIndex ArrayIndex;
192 :
193 : static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
194 : static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
195 : static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
196 :
197 : /// Minimum signed integer value that can be stored in a Json::Value.
198 : static const LargestInt minLargestInt;
199 : /// Maximum signed integer value that can be stored in a Json::Value.
200 : static const LargestInt maxLargestInt;
201 : /// Maximum unsigned integer value that can be stored in a Json::Value.
202 : static const LargestUInt maxLargestUInt;
203 :
204 : /// Minimum signed int value that can be stored in a Json::Value.
205 : static const Int minInt;
206 : /// Maximum signed int value that can be stored in a Json::Value.
207 : static const Int maxInt;
208 : /// Maximum unsigned int value that can be stored in a Json::Value.
209 : static const UInt maxUInt;
210 :
211 : #if defined(JSON_HAS_INT64)
212 : /// Minimum signed 64 bits int value that can be stored in a Json::Value.
213 : static const Int64 minInt64;
214 : /// Maximum signed 64 bits int value that can be stored in a Json::Value.
215 : static const Int64 maxInt64;
216 : /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
217 : static const UInt64 maxUInt64;
218 : #endif // defined(JSON_HAS_INT64)
219 :
220 : private:
221 : #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
222 : class CZString {
223 : public:
224 : enum DuplicationPolicy {
225 : noDuplication = 0,
226 : duplicate,
227 : duplicateOnCopy
228 : };
229 : CZString(ArrayIndex index);
230 : CZString(char const* str, unsigned length, DuplicationPolicy allocate);
231 : CZString(CZString const& other);
232 : #if JSON_HAS_RVALUE_REFERENCES
233 : CZString(CZString&& other);
234 : #endif
235 : ~CZString();
236 : CZString& operator=(CZString other);
237 : bool operator<(CZString const& other) const;
238 : bool operator==(CZString const& other) const;
239 : ArrayIndex index() const;
240 : //const char* c_str() const; ///< \deprecated
241 : char const* data() const;
242 : unsigned length() const;
243 : bool isStaticString() const;
244 :
245 : private:
246 : void swap(CZString& other);
247 :
248 : struct StringStorage {
249 : unsigned policy_: 2;
250 : unsigned length_: 30; // 1GB max
251 : };
252 :
253 : char const* cstr_; // actually, a prefixed string, unless policy is noDup
254 : union {
255 : ArrayIndex index_;
256 : StringStorage storage_;
257 : };
258 : };
259 :
260 : public:
261 : #ifndef JSON_USE_CPPTL_SMALLMAP
262 : typedef std::map<CZString, Value> ObjectValues;
263 : #else
264 : typedef CppTL::SmallMap<CZString, Value> ObjectValues;
265 : #endif // ifndef JSON_USE_CPPTL_SMALLMAP
266 : #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
267 :
268 : public:
269 : /** \brief Create a default Value of the given type.
270 :
271 : This is a very useful constructor.
272 : To create an empty array, pass arrayValue.
273 : To create an empty object, pass objectValue.
274 : Another Value can then be set to this one by assignment.
275 : This is useful since clear() and resize() will not alter types.
276 :
277 : Examples:
278 : \code
279 : Json::Value null_value; // null
280 : Json::Value arr_value(Json::arrayValue); // []
281 : Json::Value obj_value(Json::objectValue); // {}
282 : \endcode
283 : */
284 : Value(ValueType type = nullValue);
285 : Value(Int value);
286 : Value(UInt value);
287 : #if defined(JSON_HAS_INT64)
288 : Value(Int64 value);
289 : Value(UInt64 value);
290 : #endif // if defined(JSON_HAS_INT64)
291 : Value(double value);
292 : Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
293 : Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
294 : /** \brief Constructs a value from a static string.
295 :
296 : * Like other value string constructor but do not duplicate the string for
297 : * internal storage. The given string must remain alive after the call to this
298 : * constructor.
299 : * \note This works only for null-terminated strings. (We cannot change the
300 : * size of this class, so we have nowhere to store the length,
301 : * which might be computed later for various operations.)
302 : *
303 : * Example of usage:
304 : * \code
305 : * static StaticString foo("some text");
306 : * Json::Value aValue(foo);
307 : * \endcode
308 : */
309 : Value(const StaticString& value);
310 : Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too.
311 : #ifdef JSON_USE_CPPTL
312 : Value(const CppTL::ConstString& value);
313 : #endif
314 : Value(bool value);
315 : /// Deep copy.
316 : Value(const Value& other);
317 : #if JSON_HAS_RVALUE_REFERENCES
318 : /// Move constructor
319 : Value(Value&& other);
320 : #endif
321 : ~Value();
322 :
323 : /// Deep copy, then swap(other).
324 : /// \note Over-write existing comments. To preserve comments, use #swapPayload().
325 : Value& operator=(Value other);
326 : /// Swap everything.
327 : void swap(Value& other);
328 : /// Swap values but leave comments and source offsets in place.
329 : void swapPayload(Value& other);
330 :
331 : ValueType type() const;
332 :
333 : /// Compare payload only, not comments etc.
334 : bool operator<(const Value& other) const;
335 : bool operator<=(const Value& other) const;
336 : bool operator>=(const Value& other) const;
337 : bool operator>(const Value& other) const;
338 : bool operator==(const Value& other) const;
339 : bool operator!=(const Value& other) const;
340 : int compare(const Value& other) const;
341 :
342 : const char* asCString() const; ///< Embedded zeroes could cause you trouble!
343 : #if JSONCPP_USING_SECURE_MEMORY
344 : unsigned getCStringLength() const; //Allows you to understand the length of the CString
345 : #endif
346 : JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
347 : /** Get raw char* of string-value.
348 : * \return false if !string. (Seg-fault if str or end are NULL.)
349 : */
350 : bool getString(
351 : char const** begin, char const** end) const;
352 : #ifdef JSON_USE_CPPTL
353 : CppTL::ConstString asConstString() const;
354 : #endif
355 : Int asInt() const;
356 : UInt asUInt() const;
357 : #if defined(JSON_HAS_INT64)
358 : Int64 asInt64() const;
359 : UInt64 asUInt64() const;
360 : #endif // if defined(JSON_HAS_INT64)
361 : LargestInt asLargestInt() const;
362 : LargestUInt asLargestUInt() const;
363 : float asFloat() const;
364 : double asDouble() const;
365 : bool asBool() const;
366 :
367 : bool isNull() const;
368 : bool isBool() const;
369 : bool isInt() const;
370 : bool isInt64() const;
371 : bool isUInt() const;
372 : bool isUInt64() const;
373 : bool isIntegral() const;
374 : bool isDouble() const;
375 : bool isNumeric() const;
376 : bool isString() const;
377 : bool isArray() const;
378 : bool isObject() const;
379 :
380 : bool isConvertibleTo(ValueType other) const;
381 :
382 : /// Number of values in array or object
383 : ArrayIndex size() const;
384 :
385 : /// \brief Return true if empty array, empty object, or null;
386 : /// otherwise, false.
387 : bool empty() const;
388 :
389 : /// Return isNull()
390 : bool operator!() const;
391 :
392 : /// Remove all object members and array elements.
393 : /// \pre type() is arrayValue, objectValue, or nullValue
394 : /// \post type() is unchanged
395 : void clear();
396 :
397 : /// Resize the array to size elements.
398 : /// New elements are initialized to null.
399 : /// May only be called on nullValue or arrayValue.
400 : /// \pre type() is arrayValue or nullValue
401 : /// \post type() is arrayValue
402 : void resize(ArrayIndex size);
403 :
404 : /// Access an array element (zero based index ).
405 : /// If the array contains less than index element, then null value are
406 : /// inserted
407 : /// in the array so that its size is index+1.
408 : /// (You may need to say 'value[0u]' to get your compiler to distinguish
409 : /// this from the operator[] which takes a string.)
410 : Value& operator[](ArrayIndex index);
411 :
412 : /// Access an array element (zero based index ).
413 : /// If the array contains less than index element, then null value are
414 : /// inserted
415 : /// in the array so that its size is index+1.
416 : /// (You may need to say 'value[0u]' to get your compiler to distinguish
417 : /// this from the operator[] which takes a string.)
418 : Value& operator[](int index);
419 :
420 : /// Access an array element (zero based index )
421 : /// (You may need to say 'value[0u]' to get your compiler to distinguish
422 : /// this from the operator[] which takes a string.)
423 : const Value& operator[](ArrayIndex index) const;
424 :
425 : /// Access an array element (zero based index )
426 : /// (You may need to say 'value[0u]' to get your compiler to distinguish
427 : /// this from the operator[] which takes a string.)
428 : const Value& operator[](int index) const;
429 :
430 : /// If the array contains at least index+1 elements, returns the element
431 : /// value,
432 : /// otherwise returns defaultValue.
433 : Value get(ArrayIndex index, const Value& defaultValue) const;
434 : /// Return true if index < size().
435 : bool isValidIndex(ArrayIndex index) const;
436 : /// \brief Append value to array at the end.
437 : ///
438 : /// Equivalent to jsonvalue[jsonvalue.size()] = value;
439 : Value& append(const Value& value);
440 :
441 : /// Access an object value by name, create a null member if it does not exist.
442 : /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
443 : /// Exceeding that will cause an exception.
444 : Value& operator[](const char* key);
445 : /// Access an object value by name, returns null if there is no member with
446 : /// that name.
447 : const Value& operator[](const char* key) const;
448 : /// Access an object value by name, create a null member if it does not exist.
449 : /// \param key may contain embedded nulls.
450 : Value& operator[](const JSONCPP_STRING& key);
451 : /// Access an object value by name, returns null if there is no member with
452 : /// that name.
453 : /// \param key may contain embedded nulls.
454 : const Value& operator[](const JSONCPP_STRING& key) const;
455 : /** \brief Access an object value by name, create a null member if it does not
456 : exist.
457 :
458 : * If the object has no entry for that name, then the member name used to store
459 : * the new entry is not duplicated.
460 : * Example of use:
461 : * \code
462 : * Json::Value object;
463 : * static const StaticString code("code");
464 : * object[code] = 1234;
465 : * \endcode
466 : */
467 : Value& operator[](const StaticString& key);
468 : #ifdef JSON_USE_CPPTL
469 : /// Access an object value by name, create a null member if it does not exist.
470 : Value& operator[](const CppTL::ConstString& key);
471 : /// Access an object value by name, returns null if there is no member with
472 : /// that name.
473 : const Value& operator[](const CppTL::ConstString& key) const;
474 : #endif
475 : /// Return the member named key if it exist, defaultValue otherwise.
476 : /// \note deep copy
477 : Value get(const char* key, const Value& defaultValue) const;
478 : /// Return the member named key if it exist, defaultValue otherwise.
479 : /// \note deep copy
480 : /// \note key may contain embedded nulls.
481 : Value get(const char* begin, const char* end, const Value& defaultValue) const;
482 : /// Return the member named key if it exist, defaultValue otherwise.
483 : /// \note deep copy
484 : /// \param key may contain embedded nulls.
485 : Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
486 : #ifdef JSON_USE_CPPTL
487 : /// Return the member named key if it exist, defaultValue otherwise.
488 : /// \note deep copy
489 : Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
490 : #endif
491 : /// Most general and efficient version of isMember()const, get()const,
492 : /// and operator[]const
493 : /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
494 : Value const* find(char const* begin, char const* end) const;
495 : /// Most general and efficient version of object-mutators.
496 : /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
497 : /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
498 : Value const* demand(char const* begin, char const* end);
499 : /// \brief Remove and return the named member.
500 : ///
501 : /// Do nothing if it did not exist.
502 : /// \return the removed Value, or null.
503 : /// \pre type() is objectValue or nullValue
504 : /// \post type() is unchanged
505 : /// \deprecated
506 : Value removeMember(const char* key);
507 : /// Same as removeMember(const char*)
508 : /// \param key may contain embedded nulls.
509 : /// \deprecated
510 : Value removeMember(const JSONCPP_STRING& key);
511 : /// Same as removeMember(const char* begin, const char* end, Value* removed),
512 : /// but 'key' is null-terminated.
513 : bool removeMember(const char* key, Value* removed);
514 : /** \brief Remove the named map member.
515 :
516 : Update 'removed' iff removed.
517 : \param key may contain embedded nulls.
518 : \return true iff removed (no exceptions)
519 : */
520 : bool removeMember(JSONCPP_STRING const& key, Value* removed);
521 : /// Same as removeMember(JSONCPP_STRING const& key, Value* removed)
522 : bool removeMember(const char* begin, const char* end, Value* removed);
523 : /** \brief Remove the indexed array element.
524 :
525 : O(n) expensive operations.
526 : Update 'removed' iff removed.
527 : \return true iff removed (no exceptions)
528 : */
529 : bool removeIndex(ArrayIndex i, Value* removed);
530 :
531 : /// Return true if the object has a member named key.
532 : /// \note 'key' must be null-terminated.
533 : bool isMember(const char* key) const;
534 : /// Return true if the object has a member named key.
535 : /// \param key may contain embedded nulls.
536 : bool isMember(const JSONCPP_STRING& key) const;
537 : /// Same as isMember(JSONCPP_STRING const& key)const
538 : bool isMember(const char* begin, const char* end) const;
539 : #ifdef JSON_USE_CPPTL
540 : /// Return true if the object has a member named key.
541 : bool isMember(const CppTL::ConstString& key) const;
542 : #endif
543 :
544 : /// \brief Return a list of the member names.
545 : ///
546 : /// If null, return an empty list.
547 : /// \pre type() is objectValue or nullValue
548 : /// \post if type() was nullValue, it remains nullValue
549 : Members getMemberNames() const;
550 :
551 : //# ifdef JSON_USE_CPPTL
552 : // EnumMemberNames enumMemberNames() const;
553 : // EnumValues enumValues() const;
554 : //# endif
555 :
556 : /// \deprecated Always pass len.
557 : JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
558 : void setComment(const char* comment, CommentPlacement placement);
559 : /// Comments must be //... or /* ... */
560 : void setComment(const char* comment, size_t len, CommentPlacement placement);
561 : /// Comments must be //... or /* ... */
562 : void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
563 : bool hasComment(CommentPlacement placement) const;
564 : /// Include delimiters and embedded newlines.
565 : JSONCPP_STRING getComment(CommentPlacement placement) const;
566 :
567 : JSONCPP_STRING toStyledString() const;
568 :
569 : const_iterator begin() const;
570 : const_iterator end() const;
571 :
572 : iterator begin();
573 : iterator end();
574 :
575 : // Accessors for the [start, limit) range of bytes within the JSON text from
576 : // which this value was parsed, if any.
577 : void setOffsetStart(ptrdiff_t start);
578 : void setOffsetLimit(ptrdiff_t limit);
579 : ptrdiff_t getOffsetStart() const;
580 : ptrdiff_t getOffsetLimit() const;
581 :
582 : private:
583 : void initBasic(ValueType type, bool allocated = false);
584 :
585 : Value& resolveReference(const char* key);
586 : Value& resolveReference(const char* key, const char* end);
587 :
588 : struct CommentInfo {
589 : CommentInfo();
590 : ~CommentInfo();
591 :
592 : void setComment(const char* text, size_t len);
593 :
594 : char* comment_;
595 : };
596 :
597 : // struct MemberNamesTransform
598 : //{
599 : // typedef const char *result_type;
600 : // const char *operator()( const CZString &name ) const
601 : // {
602 : // return name.c_str();
603 : // }
604 : //};
605 :
606 : union ValueHolder {
607 : LargestInt int_;
608 : LargestUInt uint_;
609 : double real_;
610 : bool bool_;
611 : char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
612 : ObjectValues* map_;
613 : } value_;
614 : ValueType type_ : 8;
615 : unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
616 : // If not allocated_, string_ must be null-terminated.
617 : CommentInfo* comments_;
618 :
619 : // [start, limit) byte offsets in the source JSON text from which this Value
620 : // was extracted.
621 : ptrdiff_t start_;
622 : ptrdiff_t limit_;
623 : };
624 :
625 : /** \brief Experimental and untested: represents an element of the "path" to
626 : * access a node.
627 : */
628 0 : class JSON_API PathArgument {
629 : public:
630 : friend class Path;
631 :
632 : PathArgument();
633 : PathArgument(ArrayIndex index);
634 : PathArgument(const char* key);
635 : PathArgument(const JSONCPP_STRING& key);
636 :
637 : private:
638 : enum Kind {
639 : kindNone = 0,
640 : kindIndex,
641 : kindKey
642 : };
643 : JSONCPP_STRING key_;
644 : ArrayIndex index_;
645 : Kind kind_;
646 : };
647 :
648 : /** \brief Experimental and untested: represents a "path" to access a node.
649 : *
650 : * Syntax:
651 : * - "." => root node
652 : * - ".[n]" => elements at index 'n' of root node (an array value)
653 : * - ".name" => member named 'name' of root node (an object value)
654 : * - ".name1.name2.name3"
655 : * - ".[0][1][2].name1[3]"
656 : * - ".%" => member name is provided as parameter
657 : * - ".[%]" => index is provied as parameter
658 : */
659 : class JSON_API Path {
660 : public:
661 : Path(const JSONCPP_STRING& path,
662 : const PathArgument& a1 = PathArgument(),
663 : const PathArgument& a2 = PathArgument(),
664 : const PathArgument& a3 = PathArgument(),
665 : const PathArgument& a4 = PathArgument(),
666 : const PathArgument& a5 = PathArgument());
667 :
668 : const Value& resolve(const Value& root) const;
669 : Value resolve(const Value& root, const Value& defaultValue) const;
670 : /// Creates the "path" to access the specified node and returns a reference on
671 : /// the node.
672 : Value& make(Value& root) const;
673 :
674 : private:
675 : typedef std::vector<const PathArgument*> InArgs;
676 : typedef std::vector<PathArgument> Args;
677 :
678 : void makePath(const JSONCPP_STRING& path, const InArgs& in);
679 : void addPathInArg(const JSONCPP_STRING& path,
680 : const InArgs& in,
681 : InArgs::const_iterator& itInArg,
682 : PathArgument::Kind kind);
683 : void invalidPath(const JSONCPP_STRING& path, int location);
684 :
685 : Args args_;
686 : };
687 :
688 : /** \brief base class for Value iterators.
689 : *
690 : */
691 : class JSON_API ValueIteratorBase {
692 : public:
693 : typedef std::bidirectional_iterator_tag iterator_category;
694 : typedef unsigned int size_t;
695 : typedef int difference_type;
696 : typedef ValueIteratorBase SelfType;
697 :
698 : bool operator==(const SelfType& other) const { return isEqual(other); }
699 :
700 : bool operator!=(const SelfType& other) const { return !isEqual(other); }
701 :
702 : difference_type operator-(const SelfType& other) const {
703 : return other.computeDistance(*this);
704 : }
705 :
706 : /// Return either the index or the member name of the referenced value as a
707 : /// Value.
708 : Value key() const;
709 :
710 : /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
711 : UInt index() const;
712 :
713 : /// Return the member name of the referenced Value, or "" if it is not an
714 : /// objectValue.
715 : /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
716 : JSONCPP_STRING name() const;
717 :
718 : /// Return the member name of the referenced Value. "" if it is not an
719 : /// objectValue.
720 : /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
721 : JSONCPP_DEPRECATED("Use `key = name();` instead.")
722 : char const* memberName() const;
723 : /// Return the member name of the referenced Value, or NULL if it is not an
724 : /// objectValue.
725 : /// \note Better version than memberName(). Allows embedded nulls.
726 : char const* memberName(char const** end) const;
727 :
728 : protected:
729 : Value& deref() const;
730 :
731 : void increment();
732 :
733 : void decrement();
734 :
735 : difference_type computeDistance(const SelfType& other) const;
736 :
737 : bool isEqual(const SelfType& other) const;
738 :
739 : void copy(const SelfType& other);
740 :
741 : private:
742 : Value::ObjectValues::iterator current_;
743 : // Indicates that iterator is for a null value.
744 : bool isNull_;
745 :
746 : public:
747 : // For some reason, BORLAND needs these at the end, rather
748 : // than earlier. No idea why.
749 : ValueIteratorBase();
750 : explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
751 : };
752 :
753 : /** \brief const iterator for object and array value.
754 : *
755 : */
756 : class JSON_API ValueConstIterator : public ValueIteratorBase {
757 : friend class Value;
758 :
759 : public:
760 : typedef const Value value_type;
761 : //typedef unsigned int size_t;
762 : //typedef int difference_type;
763 : typedef const Value& reference;
764 : typedef const Value* pointer;
765 : typedef ValueConstIterator SelfType;
766 :
767 : ValueConstIterator();
768 : ValueConstIterator(ValueIterator const& other);
769 :
770 : private:
771 : /*! \internal Use by Value to create an iterator.
772 : */
773 : explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
774 : public:
775 : SelfType& operator=(const ValueIteratorBase& other);
776 :
777 : SelfType operator++(int) {
778 : SelfType temp(*this);
779 : ++*this;
780 : return temp;
781 : }
782 :
783 : SelfType operator--(int) {
784 : SelfType temp(*this);
785 : --*this;
786 : return temp;
787 : }
788 :
789 : SelfType& operator--() {
790 : decrement();
791 : return *this;
792 : }
793 :
794 : SelfType& operator++() {
795 : increment();
796 : return *this;
797 : }
798 :
799 : reference operator*() const { return deref(); }
800 :
801 : pointer operator->() const { return &deref(); }
802 : };
803 :
804 : /** \brief Iterator for object and array value.
805 : */
806 : class JSON_API ValueIterator : public ValueIteratorBase {
807 : friend class Value;
808 :
809 : public:
810 : typedef Value value_type;
811 : typedef unsigned int size_t;
812 : typedef int difference_type;
813 : typedef Value& reference;
814 : typedef Value* pointer;
815 : typedef ValueIterator SelfType;
816 :
817 : ValueIterator();
818 : explicit ValueIterator(const ValueConstIterator& other);
819 : ValueIterator(const ValueIterator& other);
820 :
821 : private:
822 : /*! \internal Use by Value to create an iterator.
823 : */
824 : explicit ValueIterator(const Value::ObjectValues::iterator& current);
825 : public:
826 : SelfType& operator=(const SelfType& other);
827 :
828 : SelfType operator++(int) {
829 : SelfType temp(*this);
830 : ++*this;
831 : return temp;
832 : }
833 :
834 : SelfType operator--(int) {
835 : SelfType temp(*this);
836 : --*this;
837 : return temp;
838 : }
839 :
840 : SelfType& operator--() {
841 : decrement();
842 : return *this;
843 : }
844 :
845 : SelfType& operator++() {
846 : increment();
847 : return *this;
848 : }
849 :
850 : reference operator*() const { return deref(); }
851 :
852 : pointer operator->() const { return &deref(); }
853 : };
854 :
855 : } // namespace Json
856 :
857 :
858 : namespace std {
859 : /// Specialize std::swap() for Json::Value.
860 : template<>
861 : inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
862 : }
863 :
864 : #pragma pack(pop)
865 :
866 : #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
867 : #pragma warning(pop)
868 : #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
869 :
870 : #endif // CPPTL_JSON_H_INCLUDED
|