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