1 // Tencent is pleased to support the open source community by making RapidJSON available. 2 // 3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 // 5 // Licensed under the MIT License (the "License"); you may not use this file except 6 // in compliance with the License. You may obtain a copy of the License at 7 // 8 // http://opensource.org/licenses/MIT 9 // 10 // Unless required by applicable law or agreed to in writing, software distributed 11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 // specific language governing permissions and limitations under the License. 14 15 #ifndef RAPIDJSON_DOCUMENT_H_ 16 #define RAPIDJSON_DOCUMENT_H_ 17 18 /*! \file document.h */ 19 20 #include "reader.h" 21 #include "internal/meta.h" 22 #include "internal/strfunc.h" 23 #include <new> // placement new 24 25 #ifdef _MSC_VER 26 RAPIDJSON_DIAG_PUSH 27 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant 28 #elif defined(__GNUC__) 29 RAPIDJSON_DIAG_PUSH 30 RAPIDJSON_DIAG_OFF(effc++) 31 #endif 32 33 /////////////////////////////////////////////////////////////////////////////// 34 // RAPIDJSON_HAS_STDSTRING 35 36 #ifndef RAPIDJSON_HAS_STDSTRING 37 #ifdef RAPIDJSON_DOXYGEN_RUNNING 38 #define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation 39 #else 40 #define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default 41 #endif 42 /*! \def RAPIDJSON_HAS_STDSTRING 43 \ingroup RAPIDJSON_CONFIG 44 \brief Enable RapidJSON support for \c std::string 45 46 By defining this preprocessor symbol to \c 1, several convenience functions for using 47 \ref rapidjson::GenericValue with \c std::string are enabled, especially 48 for construction and comparison. 49 50 \hideinitializer 51 */ 52 #endif // !defined(RAPIDJSON_HAS_STDSTRING) 53 54 #if RAPIDJSON_HAS_STDSTRING 55 #include <string> 56 #endif // RAPIDJSON_HAS_STDSTRING 57 58 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS 59 #include <iterator> // std::iterator, std::random_access_iterator_tag 60 #endif 61 62 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 63 #include <utility> // std::move 64 #endif 65 66 RAPIDJSON_NAMESPACE_BEGIN 67 68 // Forward declaration. 69 template <typename Encoding, typename Allocator> 70 class GenericValue; 71 72 template <typename Encoding, typename Allocator, typename StackAllocator> 73 class GenericDocument; 74 75 //! Name-value pair in a JSON object value. 76 /*! 77 This class was internal to GenericValue. It used to be a inner struct. 78 But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. 79 https://code.google.com/p/rapidjson/issues/detail?id=64 80 */ 81 template <typename Encoding, typename Allocator> 82 struct GenericMember { 83 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) 84 GenericValue<Encoding, Allocator> value; //!< value of member. 85 }; 86 87 /////////////////////////////////////////////////////////////////////////////// 88 // GenericMemberIterator 89 90 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS 91 92 //! (Constant) member iterator for a JSON object value 93 /*! 94 \tparam Const Is this a constant iterator? 95 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) 96 \tparam Allocator Allocator type for allocating memory of object, array and string. 97 98 This class implements a Random Access Iterator for GenericMember elements 99 of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. 100 101 \note This iterator implementation is mainly intended to avoid implicit 102 conversions from iterator values to \c NULL, 103 e.g. from GenericValue::FindMember. 104 105 \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a 106 pointer-based implementation, if your platform doesn't provide 107 the C++ <iterator> header. 108 109 \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator 110 */ 111 template <bool Const, typename Encoding, typename Allocator> 112 class GenericMemberIterator 113 : public std::iterator<std::random_access_iterator_tag 114 , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> { 115 116 friend class GenericValue<Encoding,Allocator>; 117 template <bool, typename, typename> friend class GenericMemberIterator; 118 119 typedef GenericMember<Encoding,Allocator> PlainType; 120 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; 121 typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType; 122 123 public: 124 //! Iterator type itself 125 typedef GenericMemberIterator Iterator; 126 //! Constant iterator type 127 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator; 128 //! Non-constant iterator type 129 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator; 130 131 //! Pointer to (const) GenericMember 132 typedef typename BaseType::pointer Pointer; 133 //! Reference to (const) GenericMember 134 typedef typename BaseType::reference Reference; 135 //! Signed integer type (e.g. \c ptrdiff_t) 136 typedef typename BaseType::difference_type DifferenceType; 137 138 //! Default constructor (singular value) 139 /*! Creates an iterator pointing to no element. 140 \note All operations, except for comparisons, are undefined on such values. 141 */ GenericMemberIterator()142 GenericMemberIterator() : ptr_() {} 143 144 //! Iterator conversions to more const 145 /*! 146 \param it (Non-const) iterator to copy from 147 148 Allows the creation of an iterator from another GenericMemberIterator 149 that is "less const". Especially, creating a non-constant iterator 150 from a constant iterator are disabled: 151 \li const -> non-const (not ok) 152 \li const -> const (ok) 153 \li non-const -> const (ok) 154 \li non-const -> non-const (ok) 155 156 \note If the \c Const template parameter is already \c false, this 157 constructor effectively defines a regular copy-constructor. 158 Otherwise, the copy constructor is implicitly defined. 159 */ GenericMemberIterator(const NonConstIterator & it)160 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} 161 162 //! @name stepping 163 //@{ 164 Iterator& operator++(){ ++ptr_; return *this; } 165 Iterator& operator--(){ --ptr_; return *this; } 166 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } 167 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } 168 //@} 169 170 //! @name increment/decrement 171 //@{ 172 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } 173 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } 174 175 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } 176 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } 177 //@} 178 179 //! @name relations 180 //@{ 181 bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } 182 bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } 183 bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } 184 bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } 185 bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } 186 bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } 187 //@} 188 189 //! @name dereference 190 //@{ 191 Reference operator*() const { return *ptr_; } 192 Pointer operator->() const { return ptr_; } 193 Reference operator[](DifferenceType n) const { return ptr_[n]; } 194 //@} 195 196 //! Distance 197 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } 198 199 private: 200 //! Internal constructor from plain pointer GenericMemberIterator(Pointer p)201 explicit GenericMemberIterator(Pointer p) : ptr_(p) {} 202 203 Pointer ptr_; //!< raw pointer 204 }; 205 206 #else // RAPIDJSON_NOMEMBERITERATORCLASS 207 208 // class-based member iterator implementation disabled, use plain pointers 209 210 template <bool Const, typename Encoding, typename Allocator> 211 struct GenericMemberIterator; 212 213 //! non-const GenericMemberIterator 214 template <typename Encoding, typename Allocator> 215 struct GenericMemberIterator<false,Encoding,Allocator> { 216 //! use plain pointer as iterator type 217 typedef GenericMember<Encoding,Allocator>* Iterator; 218 }; 219 //! const GenericMemberIterator 220 template <typename Encoding, typename Allocator> 221 struct GenericMemberIterator<true,Encoding,Allocator> { 222 //! use plain const pointer as iterator type 223 typedef const GenericMember<Encoding,Allocator>* Iterator; 224 }; 225 226 #endif // RAPIDJSON_NOMEMBERITERATORCLASS 227 228 /////////////////////////////////////////////////////////////////////////////// 229 // GenericStringRef 230 231 //! Reference to a constant string (not taking a copy) 232 /*! 233 \tparam CharType character type of the string 234 235 This helper class is used to automatically infer constant string 236 references for string literals, especially from \c const \b (!) 237 character arrays. 238 239 The main use is for creating JSON string values without copying the 240 source string via an \ref Allocator. This requires that the referenced 241 string pointers have a sufficient lifetime, which exceeds the lifetime 242 of the associated GenericValue. 243 244 \b Example 245 \code 246 Value v("foo"); // ok, no need to copy & calculate length 247 const char foo[] = "foo"; 248 v.SetString(foo); // ok 249 250 const char* bar = foo; 251 // Value x(bar); // not ok, can't rely on bar's lifetime 252 Value x(StringRef(bar)); // lifetime explicitly guaranteed by user 253 Value y(StringRef(bar, 3)); // ok, explicitly pass length 254 \endcode 255 256 \see StringRef, GenericValue::SetString 257 */ 258 template<typename CharType> 259 struct GenericStringRef { 260 typedef CharType Ch; //!< character type of the string 261 262 //! Create string reference from \c const character array 263 /*! 264 This constructor implicitly creates a constant string reference from 265 a \c const character array. It has better performance than 266 \ref StringRef(const CharType*) by inferring the string \ref length 267 from the array length, and also supports strings containing null 268 characters. 269 270 \tparam N length of the string, automatically inferred 271 272 \param str Constant character array, lifetime assumed to be longer 273 than the use of the string in e.g. a GenericValue 274 275 \post \ref s == str 276 277 \note Constant complexity. 278 \note There is a hidden, private overload to disallow references to 279 non-const character arrays to be created via this constructor. 280 By this, e.g. function-scope arrays used to be filled via 281 \c snprintf are excluded from consideration. 282 In such cases, the referenced string should be \b copied to the 283 GenericValue instead. 284 */ 285 template<SizeType N> 286 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT 287 : s(str), length(N-1) {} 288 289 //! Explicitly create string reference from \c const character pointer 290 /*! 291 This constructor can be used to \b explicitly create a reference to 292 a constant string pointer. 293 294 \see StringRef(const CharType*) 295 296 \param str Constant character pointer, lifetime assumed to be longer 297 than the use of the string in e.g. a GenericValue 298 299 \post \ref s == str 300 301 \note There is a hidden, private overload to disallow references to 302 non-const character arrays to be created via this constructor. 303 By this, e.g. function-scope arrays used to be filled via 304 \c snprintf are excluded from consideration. 305 In such cases, the referenced string should be \b copied to the 306 GenericValue instead. 307 */ 308 explicit GenericStringRef(const CharType* str) 309 : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); } 310 311 //! Create constant string reference from pointer and length 312 /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 313 \param len length of the string, excluding the trailing NULL terminator 314 315 \post \ref s == str && \ref length == len 316 \note Constant complexity. 317 */ 318 GenericStringRef(const CharType* str, SizeType len) 319 : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); } 320 321 //! implicit conversion to plain CharType pointer 322 operator const Ch *() const { return s; } 323 324 const Ch* const s; //!< plain CharType pointer 325 const SizeType length; //!< length of the string (excluding the trailing NULL terminator) 326 327 private: 328 //! Disallow copy-assignment 329 GenericStringRef operator=(const GenericStringRef&); 330 //! Disallow construction from non-const array 331 template<SizeType N> 332 GenericStringRef(CharType (&str)[N]) /* = delete */; 333 }; 334 335 //! Mark a character pointer as constant string 336 /*! Mark a plain character pointer as a "string literal". This function 337 can be used to avoid copying a character string to be referenced as a 338 value in a JSON GenericValue object, if the string's lifetime is known 339 to be valid long enough. 340 \tparam CharType Character type of the string 341 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 342 \return GenericStringRef string reference object 343 \relatesalso GenericStringRef 344 345 \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember 346 */ 347 template<typename CharType> 348 inline GenericStringRef<CharType> StringRef(const CharType* str) { 349 return GenericStringRef<CharType>(str, internal::StrLen(str)); 350 } 351 352 //! Mark a character pointer as constant string 353 /*! Mark a plain character pointer as a "string literal". This function 354 can be used to avoid copying a character string to be referenced as a 355 value in a JSON GenericValue object, if the string's lifetime is known 356 to be valid long enough. 357 358 This version has better performance with supplied length, and also 359 supports string containing null characters. 360 361 \tparam CharType character type of the string 362 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 363 \param length The length of source string. 364 \return GenericStringRef string reference object 365 \relatesalso GenericStringRef 366 */ 367 template<typename CharType> 368 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) { 369 return GenericStringRef<CharType>(str, SizeType(length)); 370 } 371 372 #if RAPIDJSON_HAS_STDSTRING 373 //! Mark a string object as constant string 374 /*! Mark a string object (e.g. \c std::string) as a "string literal". 375 This function can be used to avoid copying a string to be referenced as a 376 value in a JSON GenericValue object, if the string's lifetime is known 377 to be valid long enough. 378 379 \tparam CharType character type of the string 380 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 381 \return GenericStringRef string reference object 382 \relatesalso GenericStringRef 383 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 384 */ 385 template<typename CharType> 386 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) { 387 return GenericStringRef<CharType>(str.data(), SizeType(str.size())); 388 } 389 #endif 390 391 /////////////////////////////////////////////////////////////////////////////// 392 // GenericValue type traits 393 namespace internal { 394 395 template <typename T, typename Encoding = void, typename Allocator = void> 396 struct IsGenericValueImpl : FalseType {}; 397 398 // select candidates according to nested encoding and allocator types 399 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type> 400 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {}; 401 402 // helper to match arbitrary GenericValue instantiations, including derived classes 403 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {}; 404 405 } // namespace internal 406 407 /////////////////////////////////////////////////////////////////////////////// 408 // GenericValue 409 410 //! Represents a JSON value. Use Value for UTF8 encoding and default allocator. 411 /*! 412 A JSON value can be one of 7 types. This class is a variant type supporting 413 these types. 414 415 Use the Value if UTF8 and default allocator 416 417 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) 418 \tparam Allocator Allocator type for allocating memory of object, array and string. 419 */ 420 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 421 class GenericValue { 422 public: 423 //! Name-value pair in an object. 424 typedef GenericMember<Encoding, Allocator> Member; 425 typedef Encoding EncodingType; //!< Encoding type from template parameter. 426 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 427 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 428 typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string 429 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object. 430 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. 431 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. 432 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. 433 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself. 434 435 //!@name Constructors and destructor. 436 //@{ 437 438 //! Default constructor creates a null value. 439 GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {} 440 441 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 442 //! Move constructor in C++11 443 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) { 444 rhs.flags_ = kNullFlag; // give up contents 445 } 446 #endif 447 448 private: 449 //! Copy constructor is not permitted. 450 GenericValue(const GenericValue& rhs); 451 452 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 453 //! Moving from a GenericDocument is not permitted. 454 template <typename StackAllocator> 455 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); 456 457 //! Move assignment from a GenericDocument is not permitted. 458 template <typename StackAllocator> 459 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); 460 #endif 461 462 public: 463 464 //! Constructor with JSON value type. 465 /*! This creates a Value of specified type with default content. 466 \param type Type of the value. 467 \note Default content for number is zero. 468 */ 469 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() { 470 static const unsigned defaultFlags[7] = { 471 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, 472 kNumberAnyFlag 473 }; 474 RAPIDJSON_ASSERT(type <= kNumberType); 475 flags_ = defaultFlags[type]; 476 477 // Use ShortString to store empty string. 478 if (type == kStringType) 479 data_.ss.SetLength(0); 480 } 481 482 //! Explicit copy constructor (with allocator) 483 /*! Creates a copy of a Value by using the given Allocator 484 \tparam SourceAllocator allocator of \c rhs 485 \param rhs Value to copy from (read-only) 486 \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). 487 \see CopyFrom() 488 */ 489 template< typename SourceAllocator > 490 GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator); 491 492 //! Constructor for boolean value. 493 /*! \param b Boolean value 494 \note This constructor is limited to \em real boolean values and rejects 495 implicitly converted types like arbitrary pointers. Use an explicit cast 496 to \c bool, if you want to construct a boolean JSON value in such cases. 497 */ 498 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen 499 template <typename T> 500 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT 501 #else 502 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT 503 #endif 504 : data_(), flags_(b ? kTrueFlag : kFalseFlag) { 505 // safe-guard against failing SFINAE 506 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value)); 507 } 508 509 //! Constructor for int value. 510 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) { 511 data_.n.i64 = i; 512 if (i >= 0) 513 flags_ |= kUintFlag | kUint64Flag; 514 } 515 516 //! Constructor for unsigned value. 517 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) { 518 data_.n.u64 = u; 519 if (!(u & 0x80000000)) 520 flags_ |= kIntFlag | kInt64Flag; 521 } 522 523 //! Constructor for int64_t value. 524 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) { 525 data_.n.i64 = i64; 526 if (i64 >= 0) { 527 flags_ |= kNumberUint64Flag; 528 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) 529 flags_ |= kUintFlag; 530 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 531 flags_ |= kIntFlag; 532 } 533 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 534 flags_ |= kIntFlag; 535 } 536 537 //! Constructor for uint64_t value. 538 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) { 539 data_.n.u64 = u64; 540 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) 541 flags_ |= kInt64Flag; 542 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) 543 flags_ |= kUintFlag; 544 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 545 flags_ |= kIntFlag; 546 } 547 548 //! Constructor for double value. 549 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; } 550 551 //! Constructor for constant string (i.e. do not make a copy of string) 552 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); } 553 554 //! Constructor for constant string (i.e. do not make a copy of string) 555 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); } 556 557 //! Constructor for copy-string (i.e. do make a copy of string) 558 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); } 559 560 //! Constructor for copy-string (i.e. do make a copy of string) 561 GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } 562 563 #if RAPIDJSON_HAS_STDSTRING 564 //! Constructor for copy-string from a string object (i.e. do make a copy of string) 565 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 566 */ 567 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } 568 #endif 569 570 //! Destructor. 571 /*! Need to destruct elements of array, members of object, or copy-string. 572 */ 573 ~GenericValue() { 574 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait 575 switch(flags_) { 576 case kArrayFlag: 577 for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) 578 v->~GenericValue(); 579 Allocator::Free(data_.a.elements); 580 break; 581 582 case kObjectFlag: 583 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) 584 m->~Member(); 585 Allocator::Free(data_.o.members); 586 break; 587 588 case kCopyStringFlag: 589 Allocator::Free(const_cast<Ch*>(data_.s.str)); 590 break; 591 592 default: 593 break; // Do nothing for other types. 594 } 595 } 596 } 597 598 //@} 599 600 //!@name Assignment operators 601 //@{ 602 603 //! Assignment with move semantics. 604 /*! \param rhs Source of the assignment. It will become a null value after assignment. 605 */ 606 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { 607 RAPIDJSON_ASSERT(this != &rhs); 608 this->~GenericValue(); 609 RawAssign(rhs); 610 return *this; 611 } 612 613 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 614 //! Move assignment in C++11 615 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { 616 return *this = rhs.Move(); 617 } 618 #endif 619 620 //! Assignment of constant string reference (no copy) 621 /*! \param str Constant string reference to be assigned 622 \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. 623 \see GenericStringRef, operator=(T) 624 */ 625 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { 626 GenericValue s(str); 627 return *this = s; 628 } 629 630 //! Assignment with primitive types. 631 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 632 \param value The value to be assigned. 633 634 \note The source type \c T explicitly disallows all pointer types, 635 especially (\c const) \ref Ch*. This helps avoiding implicitly 636 referencing character strings with insufficient lifetime, use 637 \ref SetString(const Ch*, Allocator&) (for copying) or 638 \ref StringRef() (to explicitly mark the pointer as constant) instead. 639 All other pointer types would implicitly convert to \c bool, 640 use \ref SetBool() instead. 641 */ 642 template <typename T> 643 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&)) 644 operator=(T value) { 645 GenericValue v(value); 646 return *this = v; 647 } 648 649 //! Deep-copy assignment from Value 650 /*! Assigns a \b copy of the Value to the current Value object 651 \tparam SourceAllocator Allocator type of \c rhs 652 \param rhs Value to copy from (read-only) 653 \param allocator Allocator to use for copying 654 */ 655 template <typename SourceAllocator> 656 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { 657 RAPIDJSON_ASSERT((void*)this != (void const*)&rhs); 658 this->~GenericValue(); 659 new (this) GenericValue(rhs, allocator); 660 return *this; 661 } 662 663 //! Exchange the contents of this value with those of other. 664 /*! 665 \param other Another value. 666 \note Constant complexity. 667 */ 668 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { 669 GenericValue temp; 670 temp.RawAssign(*this); 671 RawAssign(other); 672 other.RawAssign(temp); 673 return *this; 674 } 675 676 //! free-standing swap function helper 677 /*! 678 Helper function to enable support for common swap implementation pattern based on \c std::swap: 679 \code 680 void swap(MyClass& a, MyClass& b) { 681 using std::swap; 682 swap(a.value, b.value); 683 // ... 684 } 685 \endcode 686 \see Swap() 687 */ 688 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } 689 690 //! Prepare Value for move semantics 691 /*! \return *this */ 692 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } 693 //@} 694 695 //!@name Equal-to and not-equal-to operators 696 //@{ 697 //! Equal-to operator 698 /*! 699 \note If an object contains duplicated named member, comparing equality with any object is always \c false. 700 \note Linear time complexity (number of all values in the subtree and total lengths of all strings). 701 */ 702 template <typename SourceAllocator> 703 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const { 704 typedef GenericValue<Encoding, SourceAllocator> RhsType; 705 if (GetType() != rhs.GetType()) 706 return false; 707 708 switch (GetType()) { 709 case kObjectType: // Warning: O(n^2) inner-loop 710 if (data_.o.size != rhs.data_.o.size) 711 return false; 712 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { 713 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); 714 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) 715 return false; 716 } 717 return true; 718 719 case kArrayType: 720 if (data_.a.size != rhs.data_.a.size) 721 return false; 722 for (SizeType i = 0; i < data_.a.size; i++) 723 if ((*this)[i] != rhs[i]) 724 return false; 725 return true; 726 727 case kStringType: 728 return StringEqual(rhs); 729 730 case kNumberType: 731 if (IsDouble() || rhs.IsDouble()) { 732 double a = GetDouble(); // May convert from integer to double. 733 double b = rhs.GetDouble(); // Ditto 734 return a >= b && a <= b; // Prevent -Wfloat-equal 735 } 736 else 737 return data_.n.u64 == rhs.data_.n.u64; 738 739 default: // kTrueType, kFalseType, kNullType 740 return true; 741 } 742 } 743 744 //! Equal-to operator with const C-string pointer 745 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } 746 747 #if RAPIDJSON_HAS_STDSTRING 748 //! Equal-to operator with string object 749 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 750 */ 751 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); } 752 #endif 753 754 //! Equal-to operator with primitive types 755 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false 756 */ 757 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } 758 759 //! Not-equal-to operator 760 /*! \return !(*this == rhs) 761 */ 762 template <typename SourceAllocator> 763 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); } 764 765 //! Not-equal-to operator with const C-string pointer 766 bool operator!=(const Ch* rhs) const { return !(*this == rhs); } 767 768 //! Not-equal-to operator with arbitrary types 769 /*! \return !(*this == rhs) 770 */ 771 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } 772 773 //! Equal-to operator with arbitrary types (symmetric version) 774 /*! \return (rhs == lhs) 775 */ 776 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } 777 778 //! Not-Equal-to operator with arbitrary types (symmetric version) 779 /*! \return !(rhs == lhs) 780 */ 781 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } 782 //@} 783 784 //!@name Type 785 //@{ 786 787 Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); } 788 bool IsNull() const { return flags_ == kNullFlag; } 789 bool IsFalse() const { return flags_ == kFalseFlag; } 790 bool IsTrue() const { return flags_ == kTrueFlag; } 791 bool IsBool() const { return (flags_ & kBoolFlag) != 0; } 792 bool IsObject() const { return flags_ == kObjectFlag; } 793 bool IsArray() const { return flags_ == kArrayFlag; } 794 bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } 795 bool IsInt() const { return (flags_ & kIntFlag) != 0; } 796 bool IsUint() const { return (flags_ & kUintFlag) != 0; } 797 bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } 798 bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } 799 bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } 800 bool IsString() const { return (flags_ & kStringFlag) != 0; } 801 802 //@} 803 804 //!@name Null 805 //@{ 806 807 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } 808 809 //@} 810 811 //!@name Bool 812 //@{ 813 814 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } 815 //!< Set boolean value 816 /*! \post IsBool() == true */ 817 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } 818 819 //@} 820 821 //!@name Object 822 //@{ 823 824 //! Set this value as an empty object. 825 /*! \post IsObject() == true */ 826 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } 827 828 //! Get the number of members in the object. 829 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } 830 831 //! Check whether the object is empty. 832 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } 833 834 //! Get a value from an object associated with the name. 835 /*! \pre IsObject() == true 836 \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) 837 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. 838 Since 0.2, if the name is not correct, it will assert. 839 If user is unsure whether a member exists, user should use HasMember() first. 840 A better approach is to use FindMember(). 841 \note Linear time complexity. 842 */ 843 template <typename T> 844 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) { 845 GenericValue n(StringRef(name)); 846 return (*this)[n]; 847 } 848 template <typename T> 849 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; } 850 851 //! Get a value from an object associated with the name. 852 /*! \pre IsObject() == true 853 \tparam SourceAllocator Allocator of the \c name value 854 855 \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). 856 And it can also handle strings with embedded null characters. 857 858 \note Linear time complexity. 859 */ 860 template <typename SourceAllocator> 861 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) { 862 MemberIterator member = FindMember(name); 863 if (member != MemberEnd()) 864 return member->value; 865 else { 866 RAPIDJSON_ASSERT(false); // see above note 867 static GenericValue NullValue; 868 return NullValue; 869 } 870 } 871 template <typename SourceAllocator> 872 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; } 873 874 #if RAPIDJSON_HAS_STDSTRING 875 //! Get a value from an object associated with name (string object). 876 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; } 877 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; } 878 #endif 879 880 //! Const member iterator 881 /*! \pre IsObject() == true */ 882 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); } 883 //! Const \em past-the-end member iterator 884 /*! \pre IsObject() == true */ 885 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); } 886 //! Member iterator 887 /*! \pre IsObject() == true */ 888 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); } 889 //! \em Past-the-end member iterator 890 /*! \pre IsObject() == true */ 891 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); } 892 893 //! Check whether a member exists in the object. 894 /*! 895 \param name Member name to be searched. 896 \pre IsObject() == true 897 \return Whether a member with that name exists. 898 \note It is better to use FindMember() directly if you need the obtain the value as well. 899 \note Linear time complexity. 900 */ 901 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } 902 903 #if RAPIDJSON_HAS_STDSTRING 904 //! Check whether a member exists in the object with string object. 905 /*! 906 \param name Member name to be searched. 907 \pre IsObject() == true 908 \return Whether a member with that name exists. 909 \note It is better to use FindMember() directly if you need the obtain the value as well. 910 \note Linear time complexity. 911 */ 912 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); } 913 #endif 914 915 //! Check whether a member exists in the object with GenericValue name. 916 /*! 917 This version is faster because it does not need a StrLen(). It can also handle string with null character. 918 \param name Member name to be searched. 919 \pre IsObject() == true 920 \return Whether a member with that name exists. 921 \note It is better to use FindMember() directly if you need the obtain the value as well. 922 \note Linear time complexity. 923 */ 924 template <typename SourceAllocator> 925 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); } 926 927 //! Find member by name. 928 /*! 929 \param name Member name to be searched. 930 \pre IsObject() == true 931 \return Iterator to member, if it exists. 932 Otherwise returns \ref MemberEnd(). 933 934 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case 935 the requested member doesn't exist. For consistency with e.g. 936 \c std::map, this has been changed to MemberEnd() now. 937 \note Linear time complexity. 938 */ 939 MemberIterator FindMember(const Ch* name) { 940 GenericValue n(StringRef(name)); 941 return FindMember(n); 942 } 943 944 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } 945 946 //! Find member by name. 947 /*! 948 This version is faster because it does not need a StrLen(). It can also handle string with null character. 949 \param name Member name to be searched. 950 \pre IsObject() == true 951 \return Iterator to member, if it exists. 952 Otherwise returns \ref MemberEnd(). 953 954 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case 955 the requested member doesn't exist. For consistency with e.g. 956 \c std::map, this has been changed to MemberEnd() now. 957 \note Linear time complexity. 958 */ 959 template <typename SourceAllocator> 960 MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) { 961 RAPIDJSON_ASSERT(IsObject()); 962 RAPIDJSON_ASSERT(name.IsString()); 963 MemberIterator member = MemberBegin(); 964 for ( ; member != MemberEnd(); ++member) 965 if (name.StringEqual(member->name)) 966 break; 967 return member; 968 } 969 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); } 970 971 #if RAPIDJSON_HAS_STDSTRING 972 //! Find member by string object name. 973 /*! 974 \param name Member name to be searched. 975 \pre IsObject() == true 976 \return Iterator to member, if it exists. 977 Otherwise returns \ref MemberEnd(). 978 */ 979 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); } 980 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); } 981 #endif 982 983 //! Add a member (name-value pair) to the object. 984 /*! \param name A string value as name of member. 985 \param value Value of any type. 986 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 987 \return The value itself for fluent API. 988 \note The ownership of \c name and \c value will be transferred to this object on success. 989 \pre IsObject() && name.IsString() 990 \post name.IsNull() && value.IsNull() 991 \note Amortized Constant time complexity. 992 */ 993 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { 994 RAPIDJSON_ASSERT(IsObject()); 995 RAPIDJSON_ASSERT(name.IsString()); 996 997 Object& o = data_.o; 998 if (o.size >= o.capacity) { 999 if (o.capacity == 0) { 1000 o.capacity = kDefaultObjectCapacity; 1001 o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))); 1002 } 1003 else { 1004 SizeType oldCapacity = o.capacity; 1005 o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 1006 o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member))); 1007 } 1008 } 1009 o.members[o.size].name.RawAssign(name); 1010 o.members[o.size].value.RawAssign(value); 1011 o.size++; 1012 return *this; 1013 } 1014 1015 //! Add a constant string value as member (name-value pair) to the object. 1016 /*! \param name A string value as name of member. 1017 \param value constant string reference as value of member. 1018 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1019 \return The value itself for fluent API. 1020 \pre IsObject() 1021 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. 1022 \note Amortized Constant time complexity. 1023 */ 1024 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { 1025 GenericValue v(value); 1026 return AddMember(name, v, allocator); 1027 } 1028 1029 #if RAPIDJSON_HAS_STDSTRING 1030 //! Add a string object as member (name-value pair) to the object. 1031 /*! \param name A string value as name of member. 1032 \param value constant string reference as value of member. 1033 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1034 \return The value itself for fluent API. 1035 \pre IsObject() 1036 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. 1037 \note Amortized Constant time complexity. 1038 */ 1039 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) { 1040 GenericValue v(value, allocator); 1041 return AddMember(name, v, allocator); 1042 } 1043 #endif 1044 1045 //! Add any primitive value as member (name-value pair) to the object. 1046 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 1047 \param name A string value as name of member. 1048 \param value Value of primitive type \c T as value of member 1049 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). 1050 \return The value itself for fluent API. 1051 \pre IsObject() 1052 1053 \note The source type \c T explicitly disallows all pointer types, 1054 especially (\c const) \ref Ch*. This helps avoiding implicitly 1055 referencing character strings with insufficient lifetime, use 1056 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref 1057 AddMember(StringRefType, StringRefType, Allocator&). 1058 All other pointer types would implicitly convert to \c bool, 1059 use an explicit cast instead, if needed. 1060 \note Amortized Constant time complexity. 1061 */ 1062 template <typename T> 1063 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 1064 AddMember(GenericValue& name, T value, Allocator& allocator) { 1065 GenericValue v(value); 1066 return AddMember(name, v, allocator); 1067 } 1068 1069 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1070 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { 1071 return AddMember(name, value, allocator); 1072 } 1073 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { 1074 return AddMember(name, value, allocator); 1075 } 1076 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { 1077 return AddMember(name, value, allocator); 1078 } 1079 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { 1080 GenericValue n(name); 1081 return AddMember(n, value, allocator); 1082 } 1083 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 1084 1085 1086 //! Add a member (name-value pair) to the object. 1087 /*! \param name A constant string reference as name of member. 1088 \param value Value of any type. 1089 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1090 \return The value itself for fluent API. 1091 \note The ownership of \c value will be transferred to this object on success. 1092 \pre IsObject() 1093 \post value.IsNull() 1094 \note Amortized Constant time complexity. 1095 */ 1096 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { 1097 GenericValue n(name); 1098 return AddMember(n, value, allocator); 1099 } 1100 1101 //! Add a constant string value as member (name-value pair) to the object. 1102 /*! \param name A constant string reference as name of member. 1103 \param value constant string reference as value of member. 1104 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1105 \return The value itself for fluent API. 1106 \pre IsObject() 1107 \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. 1108 \note Amortized Constant time complexity. 1109 */ 1110 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { 1111 GenericValue v(value); 1112 return AddMember(name, v, allocator); 1113 } 1114 1115 //! Add any primitive value as member (name-value pair) to the object. 1116 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 1117 \param name A constant string reference as name of member. 1118 \param value Value of primitive type \c T as value of member 1119 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). 1120 \return The value itself for fluent API. 1121 \pre IsObject() 1122 1123 \note The source type \c T explicitly disallows all pointer types, 1124 especially (\c const) \ref Ch*. This helps avoiding implicitly 1125 referencing character strings with insufficient lifetime, use 1126 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref 1127 AddMember(StringRefType, StringRefType, Allocator&). 1128 All other pointer types would implicitly convert to \c bool, 1129 use an explicit cast instead, if needed. 1130 \note Amortized Constant time complexity. 1131 */ 1132 template <typename T> 1133 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 1134 AddMember(StringRefType name, T value, Allocator& allocator) { 1135 GenericValue n(name); 1136 return AddMember(n, value, allocator); 1137 } 1138 1139 //! Remove all members in the object. 1140 /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. 1141 \note Linear time complexity. 1142 */ 1143 void RemoveAllMembers() { 1144 RAPIDJSON_ASSERT(IsObject()); 1145 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) 1146 m->~Member(); 1147 data_.o.size = 0; 1148 } 1149 1150 //! Remove a member in object by its name. 1151 /*! \param name Name of member to be removed. 1152 \return Whether the member existed. 1153 \note This function may reorder the object members. Use \ref 1154 EraseMember(ConstMemberIterator) if you need to preserve the 1155 relative order of the remaining members. 1156 \note Linear time complexity. 1157 */ 1158 bool RemoveMember(const Ch* name) { 1159 GenericValue n(StringRef(name)); 1160 return RemoveMember(n); 1161 } 1162 1163 #if RAPIDJSON_HAS_STDSTRING 1164 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); } 1165 #endif 1166 1167 template <typename SourceAllocator> 1168 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) { 1169 MemberIterator m = FindMember(name); 1170 if (m != MemberEnd()) { 1171 RemoveMember(m); 1172 return true; 1173 } 1174 else 1175 return false; 1176 } 1177 1178 //! Remove a member in object by iterator. 1179 /*! \param m member iterator (obtained by FindMember() or MemberBegin()). 1180 \return the new iterator after removal. 1181 \note This function may reorder the object members. Use \ref 1182 EraseMember(ConstMemberIterator) if you need to preserve the 1183 relative order of the remaining members. 1184 \note Constant time complexity. 1185 */ 1186 MemberIterator RemoveMember(MemberIterator m) { 1187 RAPIDJSON_ASSERT(IsObject()); 1188 RAPIDJSON_ASSERT(data_.o.size > 0); 1189 RAPIDJSON_ASSERT(data_.o.members != 0); 1190 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); 1191 1192 MemberIterator last(data_.o.members + (data_.o.size - 1)); 1193 if (data_.o.size > 1 && m != last) { 1194 // Move the last one to this place 1195 *m = *last; 1196 } 1197 else { 1198 // Only one left, just destroy 1199 m->~Member(); 1200 } 1201 --data_.o.size; 1202 return m; 1203 } 1204 1205 //! Remove a member from an object by iterator. 1206 /*! \param pos iterator to the member to remove 1207 \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() 1208 \return Iterator following the removed element. 1209 If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. 1210 \note This function preserves the relative order of the remaining object 1211 members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). 1212 \note Linear time complexity. 1213 */ 1214 MemberIterator EraseMember(ConstMemberIterator pos) { 1215 return EraseMember(pos, pos +1); 1216 } 1217 1218 //! Remove members in the range [first, last) from an object. 1219 /*! \param first iterator to the first member to remove 1220 \param last iterator following the last member to remove 1221 \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() 1222 \return Iterator following the last removed element. 1223 \note This function preserves the relative order of the remaining object 1224 members. 1225 \note Linear time complexity. 1226 */ 1227 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { 1228 RAPIDJSON_ASSERT(IsObject()); 1229 RAPIDJSON_ASSERT(data_.o.size > 0); 1230 RAPIDJSON_ASSERT(data_.o.members != 0); 1231 RAPIDJSON_ASSERT(first >= MemberBegin()); 1232 RAPIDJSON_ASSERT(first <= last); 1233 RAPIDJSON_ASSERT(last <= MemberEnd()); 1234 1235 MemberIterator pos = MemberBegin() + (first - MemberBegin()); 1236 for (MemberIterator itr = pos; itr != last; ++itr) 1237 itr->~Member(); 1238 std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member)); 1239 data_.o.size -= (last - first); 1240 return pos; 1241 } 1242 1243 //! Erase a member in object by its name. 1244 /*! \param name Name of member to be removed. 1245 \return Whether the member existed. 1246 \note Linear time complexity. 1247 */ 1248 bool EraseMember(const Ch* name) { 1249 GenericValue n(StringRef(name)); 1250 return EraseMember(n); 1251 } 1252 1253 #if RAPIDJSON_HAS_STDSTRING 1254 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); } 1255 #endif 1256 1257 template <typename SourceAllocator> 1258 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) { 1259 MemberIterator m = FindMember(name); 1260 if (m != MemberEnd()) { 1261 EraseMember(m); 1262 return true; 1263 } 1264 else 1265 return false; 1266 } 1267 1268 //@} 1269 1270 //!@name Array 1271 //@{ 1272 1273 //! Set this value as an empty array. 1274 /*! \post IsArray == true */ 1275 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } 1276 1277 //! Get the number of elements in array. 1278 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } 1279 1280 //! Get the capacity of array. 1281 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } 1282 1283 //! Check whether the array is empty. 1284 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } 1285 1286 //! Remove all elements in the array. 1287 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. 1288 \note Linear time complexity. 1289 */ 1290 void Clear() { 1291 RAPIDJSON_ASSERT(IsArray()); 1292 for (SizeType i = 0; i < data_.a.size; ++i) 1293 data_.a.elements[i].~GenericValue(); 1294 data_.a.size = 0; 1295 } 1296 1297 //! Get an element from array by index. 1298 /*! \pre IsArray() == true 1299 \param index Zero-based index of element. 1300 \see operator[](T*) 1301 */ 1302 GenericValue& operator[](SizeType index) { 1303 RAPIDJSON_ASSERT(IsArray()); 1304 RAPIDJSON_ASSERT(index < data_.a.size); 1305 return data_.a.elements[index]; 1306 } 1307 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } 1308 1309 //! Element iterator 1310 /*! \pre IsArray() == true */ 1311 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } 1312 //! \em Past-the-end element iterator 1313 /*! \pre IsArray() == true */ 1314 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } 1315 //! Constant element iterator 1316 /*! \pre IsArray() == true */ 1317 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } 1318 //! Constant \em past-the-end element iterator 1319 /*! \pre IsArray() == true */ 1320 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } 1321 1322 //! Request the array to have enough capacity to store elements. 1323 /*! \param newCapacity The capacity that the array at least need to have. 1324 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1325 \return The value itself for fluent API. 1326 \note Linear time complexity. 1327 */ 1328 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { 1329 RAPIDJSON_ASSERT(IsArray()); 1330 if (newCapacity > data_.a.capacity) { 1331 data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); 1332 data_.a.capacity = newCapacity; 1333 } 1334 return *this; 1335 } 1336 1337 //! Append a GenericValue at the end of the array. 1338 /*! \param value Value to be appended. 1339 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1340 \pre IsArray() == true 1341 \post value.IsNull() == true 1342 \return The value itself for fluent API. 1343 \note The ownership of \c value will be transferred to this array on success. 1344 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 1345 \note Amortized constant time complexity. 1346 */ 1347 GenericValue& PushBack(GenericValue& value, Allocator& allocator) { 1348 RAPIDJSON_ASSERT(IsArray()); 1349 if (data_.a.size >= data_.a.capacity) 1350 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); 1351 data_.a.elements[data_.a.size++].RawAssign(value); 1352 return *this; 1353 } 1354 1355 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1356 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { 1357 return PushBack(value, allocator); 1358 } 1359 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 1360 1361 //! Append a constant string reference at the end of the array. 1362 /*! \param value Constant string reference to be appended. 1363 \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). 1364 \pre IsArray() == true 1365 \return The value itself for fluent API. 1366 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 1367 \note Amortized constant time complexity. 1368 \see GenericStringRef 1369 */ 1370 GenericValue& PushBack(StringRefType value, Allocator& allocator) { 1371 return (*this).template PushBack<StringRefType>(value, allocator); 1372 } 1373 1374 //! Append a primitive value at the end of the array. 1375 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 1376 \param value Value of primitive type T to be appended. 1377 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 1378 \pre IsArray() == true 1379 \return The value itself for fluent API. 1380 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 1381 1382 \note The source type \c T explicitly disallows all pointer types, 1383 especially (\c const) \ref Ch*. This helps avoiding implicitly 1384 referencing character strings with insufficient lifetime, use 1385 \ref PushBack(GenericValue&, Allocator&) or \ref 1386 PushBack(StringRefType, Allocator&). 1387 All other pointer types would implicitly convert to \c bool, 1388 use an explicit cast instead, if needed. 1389 \note Amortized constant time complexity. 1390 */ 1391 template <typename T> 1392 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 1393 PushBack(T value, Allocator& allocator) { 1394 GenericValue v(value); 1395 return PushBack(v, allocator); 1396 } 1397 1398 //! Remove the last element in the array. 1399 /*! 1400 \note Constant time complexity. 1401 */ 1402 GenericValue& PopBack() { 1403 RAPIDJSON_ASSERT(IsArray()); 1404 RAPIDJSON_ASSERT(!Empty()); 1405 data_.a.elements[--data_.a.size].~GenericValue(); 1406 return *this; 1407 } 1408 1409 //! Remove an element of array by iterator. 1410 /*! 1411 \param pos iterator to the element to remove 1412 \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() 1413 \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. 1414 \note Linear time complexity. 1415 */ 1416 ValueIterator Erase(ConstValueIterator pos) { 1417 return Erase(pos, pos + 1); 1418 } 1419 1420 //! Remove elements in the range [first, last) of the array. 1421 /*! 1422 \param first iterator to the first element to remove 1423 \param last iterator following the last element to remove 1424 \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() 1425 \return Iterator following the last removed element. 1426 \note Linear time complexity. 1427 */ 1428 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { 1429 RAPIDJSON_ASSERT(IsArray()); 1430 RAPIDJSON_ASSERT(data_.a.size > 0); 1431 RAPIDJSON_ASSERT(data_.a.elements != 0); 1432 RAPIDJSON_ASSERT(first >= Begin()); 1433 RAPIDJSON_ASSERT(first <= last); 1434 RAPIDJSON_ASSERT(last <= End()); 1435 ValueIterator pos = Begin() + (first - Begin()); 1436 for (ValueIterator itr = pos; itr != last; ++itr) 1437 itr->~GenericValue(); 1438 std::memmove(pos, last, (End() - last) * sizeof(GenericValue)); 1439 data_.a.size -= (last - first); 1440 return pos; 1441 } 1442 1443 //@} 1444 1445 //!@name Number 1446 //@{ 1447 1448 int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } 1449 unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } 1450 int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } 1451 uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } 1452 1453 double GetDouble() const { 1454 RAPIDJSON_ASSERT(IsNumber()); 1455 if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. 1456 if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double 1457 if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double 1458 if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) 1459 RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) 1460 } 1461 1462 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } 1463 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } 1464 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } 1465 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } 1466 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } 1467 1468 //@} 1469 1470 //!@name String 1471 //@{ 1472 1473 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); } 1474 1475 //! Get the length of string. 1476 /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). 1477 */ 1478 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } 1479 1480 //! Set this value as a string without copying source string. 1481 /*! This version has better performance with supplied length, and also support string containing null character. 1482 \param s source string pointer. 1483 \param length The length of source string, excluding the trailing null terminator. 1484 \return The value itself for fluent API. 1485 \post IsString() == true && GetString() == s && GetStringLength() == length 1486 \see SetString(StringRefType) 1487 */ 1488 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } 1489 1490 //! Set this value as a string without copying source string. 1491 /*! \param s source string reference 1492 \return The value itself for fluent API. 1493 \post IsString() == true && GetString() == s && GetStringLength() == s.length 1494 */ 1495 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } 1496 1497 //! Set this value as a string by copying from source string. 1498 /*! This version has better performance with supplied length, and also support string containing null character. 1499 \param s source string. 1500 \param length The length of source string, excluding the trailing null terminator. 1501 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 1502 \return The value itself for fluent API. 1503 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length 1504 */ 1505 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } 1506 1507 //! Set this value as a string by copying from source string. 1508 /*! \param s source string. 1509 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 1510 \return The value itself for fluent API. 1511 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length 1512 */ 1513 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } 1514 1515 #if RAPIDJSON_HAS_STDSTRING 1516 //! Set this value as a string by copying from source string. 1517 /*! \param s source string. 1518 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 1519 \return The value itself for fluent API. 1520 \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() 1521 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 1522 */ 1523 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } 1524 #endif 1525 1526 //@} 1527 1528 //! Generate events of this value to a Handler. 1529 /*! This function adopts the GoF visitor pattern. 1530 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. 1531 It can also be used to deep clone this value via GenericDocument, which is also a Handler. 1532 \tparam Handler type of handler. 1533 \param handler An object implementing concept Handler. 1534 */ 1535 template <typename Handler> 1536 bool Accept(Handler& handler) const { 1537 switch(GetType()) { 1538 case kNullType: return handler.Null(); 1539 case kFalseType: return handler.Bool(false); 1540 case kTrueType: return handler.Bool(true); 1541 1542 case kObjectType: 1543 if (!handler.StartObject()) 1544 return false; 1545 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { 1546 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. 1547 if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0)) 1548 return false; 1549 if (!m->value.Accept(handler)) 1550 return false; 1551 } 1552 return handler.EndObject(data_.o.size); 1553 1554 case kArrayType: 1555 if (!handler.StartArray()) 1556 return false; 1557 for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) 1558 if (!v->Accept(handler)) 1559 return false; 1560 return handler.EndArray(data_.a.size); 1561 1562 case kStringType: 1563 return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0); 1564 1565 default: 1566 RAPIDJSON_ASSERT(GetType() == kNumberType); 1567 if (IsInt()) return handler.Int(data_.n.i.i); 1568 else if (IsUint()) return handler.Uint(data_.n.u.u); 1569 else if (IsInt64()) return handler.Int64(data_.n.i64); 1570 else if (IsUint64()) return handler.Uint64(data_.n.u64); 1571 else return handler.Double(data_.n.d); 1572 } 1573 } 1574 1575 private: 1576 template <typename, typename> friend class GenericValue; 1577 template <typename, typename, typename> friend class GenericDocument; 1578 1579 enum { 1580 kBoolFlag = 0x100, 1581 kNumberFlag = 0x200, 1582 kIntFlag = 0x400, 1583 kUintFlag = 0x800, 1584 kInt64Flag = 0x1000, 1585 kUint64Flag = 0x2000, 1586 kDoubleFlag = 0x4000, 1587 kStringFlag = 0x100000, 1588 kCopyFlag = 0x200000, 1589 kInlineStrFlag = 0x400000, 1590 1591 // Initial flags of different types. 1592 kNullFlag = kNullType, 1593 kTrueFlag = kTrueType | kBoolFlag, 1594 kFalseFlag = kFalseType | kBoolFlag, 1595 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, 1596 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, 1597 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, 1598 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, 1599 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, 1600 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, 1601 kConstStringFlag = kStringType | kStringFlag, 1602 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, 1603 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, 1604 kObjectFlag = kObjectType, 1605 kArrayFlag = kArrayType, 1606 1607 kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler 1608 }; 1609 1610 static const SizeType kDefaultArrayCapacity = 16; 1611 static const SizeType kDefaultObjectCapacity = 16; 1612 1613 struct String { 1614 const Ch* str; 1615 SizeType length; 1616 unsigned hashcode; //!< reserved 1617 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 1618 1619 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars 1620 // (excluding the terminating zero) and store a value to determine the length of the contained 1621 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string 1622 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as 1623 // the string terminator as well. For getting the string length back from that value just use 1624 // "MaxSize - str[LenPos]". 1625 // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode 1626 // inline (for `UTF8`-encoded strings). 1627 struct ShortString { 1628 enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; 1629 Ch str[MaxChars]; 1630 1631 inline static bool Usable(SizeType len) { return (MaxSize >= len); } 1632 inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); } 1633 inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); } 1634 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 1635 1636 // By using proper binary layout, retrieval of different integer types do not need conversions. 1637 union Number { 1638 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN 1639 struct I { 1640 int i; 1641 char padding[4]; 1642 }i; 1643 struct U { 1644 unsigned u; 1645 char padding2[4]; 1646 }u; 1647 #else 1648 struct I { 1649 char padding[4]; 1650 int i; 1651 }i; 1652 struct U { 1653 char padding2[4]; 1654 unsigned u; 1655 }u; 1656 #endif 1657 int64_t i64; 1658 uint64_t u64; 1659 double d; 1660 }; // 8 bytes 1661 1662 struct Object { 1663 Member* members; 1664 SizeType size; 1665 SizeType capacity; 1666 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 1667 1668 struct Array { 1669 GenericValue* elements; 1670 SizeType size; 1671 SizeType capacity; 1672 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 1673 1674 union Data { 1675 String s; 1676 ShortString ss; 1677 Number n; 1678 Object o; 1679 Array a; 1680 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 1681 1682 // Initialize this value as array with initial data, without calling destructor. 1683 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { 1684 flags_ = kArrayFlag; 1685 if (count) { 1686 data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue)); 1687 std::memcpy(data_.a.elements, values, count * sizeof(GenericValue)); 1688 } 1689 else 1690 data_.a.elements = NULL; 1691 data_.a.size = data_.a.capacity = count; 1692 } 1693 1694 //! Initialize this value as object with initial data, without calling destructor. 1695 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { 1696 flags_ = kObjectFlag; 1697 if (count) { 1698 data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member)); 1699 std::memcpy(data_.o.members, members, count * sizeof(Member)); 1700 } 1701 else 1702 data_.o.members = NULL; 1703 data_.o.size = data_.o.capacity = count; 1704 } 1705 1706 //! Initialize this value as constant string, without calling destructor. 1707 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { 1708 flags_ = kConstStringFlag; 1709 data_.s.str = s; 1710 data_.s.length = s.length; 1711 } 1712 1713 //! Initialize this value as copy string with initial data, without calling destructor. 1714 void SetStringRaw(StringRefType s, Allocator& allocator) { 1715 Ch* str = NULL; 1716 if(ShortString::Usable(s.length)) { 1717 flags_ = kShortStringFlag; 1718 data_.ss.SetLength(s.length); 1719 str = data_.ss.str; 1720 } else { 1721 flags_ = kCopyStringFlag; 1722 data_.s.length = s.length; 1723 str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch)); 1724 data_.s.str = str; 1725 } 1726 std::memcpy(str, s, s.length * sizeof(Ch)); 1727 str[s.length] = '\0'; 1728 } 1729 1730 //! Assignment without calling destructor 1731 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { 1732 data_ = rhs.data_; 1733 flags_ = rhs.flags_; 1734 rhs.flags_ = kNullFlag; 1735 } 1736 1737 template <typename SourceAllocator> 1738 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const { 1739 RAPIDJSON_ASSERT(IsString()); 1740 RAPIDJSON_ASSERT(rhs.IsString()); 1741 1742 const SizeType len1 = GetStringLength(); 1743 const SizeType len2 = rhs.GetStringLength(); 1744 if(len1 != len2) { return false; } 1745 1746 const Ch* const str1 = GetString(); 1747 const Ch* const str2 = rhs.GetString(); 1748 if(str1 == str2) { return true; } // fast path for constant string 1749 1750 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); 1751 } 1752 1753 Data data_; 1754 unsigned flags_; 1755 }; 1756 1757 //! GenericValue with UTF8 encoding 1758 typedef GenericValue<UTF8<> > Value; 1759 1760 /////////////////////////////////////////////////////////////////////////////// 1761 // GenericDocument 1762 1763 //! A document for parsing JSON text as DOM. 1764 /*! 1765 \note implements Handler concept 1766 \tparam Encoding Encoding for both parsing and string storage. 1767 \tparam Allocator Allocator for allocating memory for the DOM 1768 \tparam StackAllocator Allocator for allocating memory for stack during parsing. 1769 \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. 1770 */ 1771 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator> 1772 class GenericDocument : public GenericValue<Encoding, Allocator> { 1773 public: 1774 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 1775 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document. 1776 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 1777 1778 //! Constructor 1779 /*! Creates an empty document of specified type. 1780 \param type Mandatory type of object to create. 1781 \param allocator Optional allocator for allocating memory. 1782 \param stackCapacity Optional initial capacity of stack in bytes. 1783 \param stackAllocator Optional allocator for allocating memory for stack. 1784 */ 1785 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 1786 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() 1787 { 1788 if (!allocator_) 1789 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); 1790 } 1791 1792 //! Constructor 1793 /*! Creates an empty document which type is Null. 1794 \param allocator Optional allocator for allocating memory. 1795 \param stackCapacity Optional initial capacity of stack in bytes. 1796 \param stackAllocator Optional allocator for allocating memory for stack. 1797 */ 1798 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 1799 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() 1800 { 1801 if (!allocator_) 1802 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); 1803 } 1804 1805 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1806 //! Move constructor in C++11 1807 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT 1808 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document 1809 allocator_(rhs.allocator_), 1810 ownAllocator_(rhs.ownAllocator_), 1811 stack_(std::move(rhs.stack_)), 1812 parseResult_(rhs.parseResult_) 1813 { 1814 rhs.allocator_ = 0; 1815 rhs.ownAllocator_ = 0; 1816 rhs.parseResult_ = ParseResult(); 1817 } 1818 #endif 1819 1820 ~GenericDocument() { 1821 Destroy(); 1822 } 1823 1824 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1825 //! Move assignment in C++11 1826 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT 1827 { 1828 // The cast to ValueType is necessary here, because otherwise it would 1829 // attempt to call GenericValue's templated assignment operator. 1830 ValueType::operator=(std::forward<ValueType>(rhs)); 1831 1832 // Calling the destructor here would prematurely call stack_'s destructor 1833 Destroy(); 1834 1835 allocator_ = rhs.allocator_; 1836 ownAllocator_ = rhs.ownAllocator_; 1837 stack_ = std::move(rhs.stack_); 1838 parseResult_ = rhs.parseResult_; 1839 1840 rhs.allocator_ = 0; 1841 rhs.ownAllocator_ = 0; 1842 rhs.parseResult_ = ParseResult(); 1843 1844 return *this; 1845 } 1846 #endif 1847 1848 //! Exchange the contents of this document with those of another. 1849 /*! 1850 \param other Another document. 1851 \note Constant complexity. 1852 \see GenericValue::Swap 1853 */ 1854 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { 1855 ValueType::Swap(rhs); 1856 stack_.Swap(rhs.stack_); 1857 internal::Swap(allocator_, rhs.allocator_); 1858 internal::Swap(ownAllocator_, rhs.ownAllocator_); 1859 internal::Swap(parseResult_, rhs.parseResult_); 1860 return *this; 1861 } 1862 1863 //! free-standing swap function helper 1864 /*! 1865 Helper function to enable support for common swap implementation pattern based on \c std::swap: 1866 \code 1867 void swap(MyClass& a, MyClass& b) { 1868 using std::swap; 1869 swap(a.doc, b.doc); 1870 // ... 1871 } 1872 \endcode 1873 \see Swap() 1874 */ 1875 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } 1876 1877 //!@name Parse from stream 1878 //!@{ 1879 1880 //! Parse JSON text from an input stream (with Encoding conversion) 1881 /*! \tparam parseFlags Combination of \ref ParseFlag. 1882 \tparam SourceEncoding Encoding of input stream 1883 \tparam InputStream Type of input stream, implementing Stream concept 1884 \param is Input stream to be parsed. 1885 \return The document itself for fluent API. 1886 */ 1887 template <unsigned parseFlags, typename SourceEncoding, typename InputStream> 1888 GenericDocument& ParseStream(InputStream& is) { 1889 GenericReader<SourceEncoding, Encoding, StackAllocator> reader( 1890 stack_.HasAllocator() ? &stack_.GetAllocator() : 0); 1891 ClearStackOnExit scope(*this); 1892 parseResult_ = reader.template Parse<parseFlags>(is, *this); 1893 if (parseResult_) { 1894 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object 1895 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document 1896 } 1897 return *this; 1898 } 1899 1900 //! Parse JSON text from an input stream 1901 /*! \tparam parseFlags Combination of \ref ParseFlag. 1902 \tparam InputStream Type of input stream, implementing Stream concept 1903 \param is Input stream to be parsed. 1904 \return The document itself for fluent API. 1905 */ 1906 template <unsigned parseFlags, typename InputStream> 1907 GenericDocument& ParseStream(InputStream& is) { 1908 return ParseStream<parseFlags, Encoding, InputStream>(is); 1909 } 1910 1911 //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) 1912 /*! \tparam InputStream Type of input stream, implementing Stream concept 1913 \param is Input stream to be parsed. 1914 \return The document itself for fluent API. 1915 */ 1916 template <typename InputStream> 1917 GenericDocument& ParseStream(InputStream& is) { 1918 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is); 1919 } 1920 //!@} 1921 1922 //!@name Parse in-place from mutable string 1923 //!@{ 1924 1925 //! Parse JSON text from a mutable string 1926 /*! \tparam parseFlags Combination of \ref ParseFlag. 1927 \param str Mutable zero-terminated string to be parsed. 1928 \return The document itself for fluent API. 1929 */ 1930 template <unsigned parseFlags> 1931 GenericDocument& ParseInsitu(Ch* str) { 1932 GenericInsituStringStream<Encoding> s(str); 1933 return ParseStream<parseFlags | kParseInsituFlag>(s); 1934 } 1935 1936 //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) 1937 /*! \param str Mutable zero-terminated string to be parsed. 1938 \return The document itself for fluent API. 1939 */ 1940 GenericDocument& ParseInsitu(Ch* str) { 1941 return ParseInsitu<kParseDefaultFlags>(str); 1942 } 1943 //!@} 1944 1945 //!@name Parse from read-only string 1946 //!@{ 1947 1948 //! Parse JSON text from a read-only string (with Encoding conversion) 1949 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). 1950 \tparam SourceEncoding Transcoding from input Encoding 1951 \param str Read-only zero-terminated string to be parsed. 1952 */ 1953 template <unsigned parseFlags, typename SourceEncoding> 1954 GenericDocument& Parse(const Ch* str) { 1955 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 1956 GenericStringStream<SourceEncoding> s(str); 1957 return ParseStream<parseFlags, SourceEncoding>(s); 1958 } 1959 1960 //! Parse JSON text from a read-only string 1961 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). 1962 \param str Read-only zero-terminated string to be parsed. 1963 */ 1964 template <unsigned parseFlags> 1965 GenericDocument& Parse(const Ch* str) { 1966 return Parse<parseFlags, Encoding>(str); 1967 } 1968 1969 //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) 1970 /*! \param str Read-only zero-terminated string to be parsed. 1971 */ 1972 GenericDocument& Parse(const Ch* str) { 1973 return Parse<kParseDefaultFlags>(str); 1974 } 1975 //!@} 1976 1977 //!@name Handling parse errors 1978 //!@{ 1979 1980 //! Whether a parse error has occured in the last parsing. 1981 bool HasParseError() const { return parseResult_.IsError(); } 1982 1983 //! Get the \ref ParseErrorCode of last parsing. 1984 ParseErrorCode GetParseError() const { return parseResult_.Code(); } 1985 1986 //! Get the position of last parsing error in input, 0 otherwise. 1987 size_t GetErrorOffset() const { return parseResult_.Offset(); } 1988 1989 //!@} 1990 1991 //! Get the allocator of this document. 1992 Allocator& GetAllocator() { 1993 RAPIDJSON_ASSERT(allocator_); 1994 return *allocator_; 1995 } 1996 1997 //! Get the capacity of stack in bytes. 1998 size_t GetStackCapacity() const { return stack_.GetCapacity(); } 1999 2000 private: 2001 // clear stack on any exit from ParseStream, e.g. due to exception 2002 struct ClearStackOnExit { 2003 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} 2004 ~ClearStackOnExit() { d_.ClearStack(); } 2005 private: 2006 ClearStackOnExit(const ClearStackOnExit&); 2007 ClearStackOnExit& operator=(const ClearStackOnExit&); 2008 GenericDocument& d_; 2009 }; 2010 2011 // callers of the following private Handler functions 2012 template <typename,typename,typename> friend class GenericReader; // for parsing 2013 template <typename, typename> friend class GenericValue; // for deep copying 2014 2015 // Implementation of Handler 2016 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; } 2017 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; } 2018 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 2019 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 2020 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 2021 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 2022 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; } 2023 2024 bool String(const Ch* str, SizeType length, bool copy) { 2025 if (copy) 2026 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); 2027 else 2028 new (stack_.template Push<ValueType>()) ValueType(str, length); 2029 return true; 2030 } 2031 2032 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; } 2033 2034 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } 2035 2036 bool EndObject(SizeType memberCount) { 2037 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); 2038 stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); 2039 return true; 2040 } 2041 2042 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; } 2043 2044 bool EndArray(SizeType elementCount) { 2045 ValueType* elements = stack_.template Pop<ValueType>(elementCount); 2046 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); 2047 return true; 2048 } 2049 2050 private: 2051 //! Prohibit copying 2052 GenericDocument(const GenericDocument&); 2053 //! Prohibit assignment 2054 GenericDocument& operator=(const GenericDocument&); 2055 2056 void ClearStack() { 2057 if (Allocator::kNeedFree) 2058 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) 2059 (stack_.template Pop<ValueType>(1))->~ValueType(); 2060 else 2061 stack_.Clear(); 2062 stack_.ShrinkToFit(); 2063 } 2064 2065 void Destroy() { 2066 RAPIDJSON_DELETE(ownAllocator_); 2067 } 2068 2069 static const size_t kDefaultStackCapacity = 1024; 2070 Allocator* allocator_; 2071 Allocator* ownAllocator_; 2072 internal::Stack<StackAllocator> stack_; 2073 ParseResult parseResult_; 2074 }; 2075 2076 //! GenericDocument with UTF8 encoding 2077 typedef GenericDocument<UTF8<> > Document; 2078 2079 // defined here due to the dependency on GenericDocument 2080 template <typename Encoding, typename Allocator> 2081 template <typename SourceAllocator> 2082 inline 2083 GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) 2084 { 2085 switch (rhs.GetType()) { 2086 case kObjectType: 2087 case kArrayType: { // perform deep copy via SAX Handler 2088 GenericDocument<Encoding,Allocator> d(&allocator); 2089 rhs.Accept(d); 2090 RawAssign(*d.stack_.template Pop<GenericValue>(1)); 2091 } 2092 break; 2093 case kStringType: 2094 if (rhs.flags_ == kConstStringFlag) { 2095 flags_ = rhs.flags_; 2096 data_ = *reinterpret_cast<const Data*>(&rhs.data_); 2097 } else { 2098 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); 2099 } 2100 break; 2101 default: // kNumberType, kTrueType, kFalseType, kNullType 2102 flags_ = rhs.flags_; 2103 data_ = *reinterpret_cast<const Data*>(&rhs.data_); 2104 break; 2105 } 2106 } 2107 2108 RAPIDJSON_NAMESPACE_END 2109 2110 #if defined(_MSC_VER) || defined(__GNUC__) 2111 RAPIDJSON_DIAG_POP 2112 #endif 2113 2114 #endif // RAPIDJSON_DOCUMENT_H_ 2115