document.h
Engine/source/persistence/rapidjson/document.h
Classes:
class
A document for parsing JSON text as DOM.
class
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
class
Name-value pair in an object.
Namespaces:
namespace
Detailed Description
1 2#ifndef RAPIDJSON_DOCUMENT_H_ 3#define RAPIDJSON_DOCUMENT_H_ 4 5#include "reader.h" 6#include "internal/strfunc.h" 7#include <new> // placement new 8 9#ifdef _MSC_VER 10#pragma warning(push) 11#pragma warning(disable : 4127) // conditional expression is constant 12#endif 13 14namespace rapidjson { 15 16/////////////////////////////////////////////////////////////////////////////// 17// GenericValue 18 19//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. 20/*! 21 A JSON value can be one of 7 types. This class is a variant type supporting 22 these types. 23 24 Use the Value if UTF8 and default allocator 25 26 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) 27 \tparam Allocator Allocator type for allocating memory of object, array and string. 28*/ 29#pragma pack (push, 4) 30template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 31class GenericValue { 32public: 33 //! Name-value pair in an object. 34 struct Member { 35 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) 36 GenericValue<Encoding, Allocator> value; //!< value of member. 37 }; 38 39 typedef Encoding EncodingType; //!< Encoding type from template parameter. 40 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 41 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 42 typedef Member* MemberIterator; //!< Member iterator for iterating in object. 43 typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object. 44 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. 45 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. 46 47 //!@name Constructors and destructor. 48 //@{ 49 50 //! Default constructor creates a null value. 51 GenericValue() : flags_(kNullFlag) {} 52 53 //! Copy constructor is not permitted. 54private: 55 GenericValue(const GenericValue& rhs); 56 57public: 58 59 //! Constructor with JSON value type. 60 /*! This creates a Value of specified type with default content. 61 \param type Type of the value. 62 \note Default content for number is zero. 63 */ 64 GenericValue(Type type) { 65 static const unsigned defaultFlags[7] = { 66 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, 67 kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag 68 }; 69 RAPIDJSON_ASSERT(type <= kNumberType); 70 flags_ = defaultFlags[type]; 71 memset(&data_, 0, sizeof(data_)); 72 } 73 74 //! Constructor for boolean value. 75 GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {} 76 77 //! Constructor for int value. 78 GenericValue(int i) : flags_(kNumberIntFlag) { 79 data_.n.i64 = i; 80 if (i >= 0) 81 flags_ |= kUintFlag | kUint64Flag; 82 } 83 84 //! Constructor for unsigned value. 85 GenericValue(unsigned u) : flags_(kNumberUintFlag) { 86 data_.n.u64 = u; 87 if (!(u & 0x80000000)) 88 flags_ |= kIntFlag | kInt64Flag; 89 } 90 91 //! Constructor for int64_t value. 92 GenericValue(int64_t i64) : flags_(kNumberInt64Flag) { 93 data_.n.i64 = i64; 94 if (i64 >= 0) { 95 flags_ |= kNumberUint64Flag; 96 if (!(i64 & 0xFFFFFFFF00000000LL)) 97 flags_ |= kUintFlag; 98 if (!(i64 & 0xFFFFFFFF80000000LL)) 99 flags_ |= kIntFlag; 100 } 101 else if (i64 >= -2147483648LL) 102 flags_ |= kIntFlag; 103 } 104 105 //! Constructor for uint64_t value. 106 GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) { 107 data_.n.u64 = u64; 108 if (!(u64 & 0x8000000000000000ULL)) 109 flags_ |= kInt64Flag; 110 if (!(u64 & 0xFFFFFFFF00000000ULL)) 111 flags_ |= kUintFlag; 112 if (!(u64 & 0xFFFFFFFF80000000ULL)) 113 flags_ |= kIntFlag; 114 } 115 116 //! Constructor for double value. 117 GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; } 118 119 //! Constructor for constant string (i.e. do not make a copy of string) 120 GenericValue(const Ch* s, SizeType length) { 121 RAPIDJSON_ASSERT(s != NULL); 122 flags_ = kConstStringFlag; 123 data_.s.str = s; 124 data_.s.length = length; 125 } 126 127 //! Constructor for constant string (i.e. do not make a copy of string) 128 GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); } 129 130 //! Constructor for copy-string (i.e. do make a copy of string) 131 GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); } 132 133 //! Constructor for copy-string (i.e. do make a copy of string) 134 GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); } 135 136 //! Destructor. 137 /*! Need to destruct elements of array, members of object, or copy-string. 138 */ 139 ~GenericValue() { 140 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait 141 switch(flags_) { 142 case kArrayFlag: 143 for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) 144 v->~GenericValue(); 145 Allocator::Free(data_.a.elements); 146 break; 147 148 case kObjectFlag: 149 for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { 150 m->name.~GenericValue(); 151 m->value.~GenericValue(); 152 } 153 Allocator::Free(data_.o.members); 154 break; 155 156 case kCopyStringFlag: 157 Allocator::Free(const_cast<Ch*>(data_.s.str)); 158 break; 159 } 160 } 161 } 162 163 //@} 164 165 //!@name Assignment operators 166 //@{ 167 168 //! Assignment with move semantics. 169 /*! \param rhs Source of the assignment. It will become a null value after assignment. 170 */ 171 GenericValue& operator=(GenericValue& rhs) { 172 RAPIDJSON_ASSERT(this != &rhs); 173 this->~GenericValue(); 174 memcpy(this, &rhs, sizeof(GenericValue)); 175 rhs.flags_ = kNullFlag; 176 return *this; 177 } 178 179 //! Assignment with primitive types. 180 /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch* 181 \param value The value to be assigned. 182 */ 183 template <typename T> 184 GenericValue& operator=(T value) { 185 this->~GenericValue(); 186 new (this) GenericValue(value); 187 return *this; 188 } 189 //@} 190 191 //!@name Type 192 //@{ 193 194 Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); } 195 bool IsNull() const { return flags_ == kNullFlag; } 196 bool IsFalse() const { return flags_ == kFalseFlag; } 197 bool IsTrue() const { return flags_ == kTrueFlag; } 198 bool IsBool() const { return (flags_ & kBoolFlag) != 0; } 199 bool IsObject() const { return flags_ == kObjectFlag; } 200 bool IsArray() const { return flags_ == kArrayFlag; } 201 bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } 202 bool IsInt() const { return (flags_ & kIntFlag) != 0; } 203 bool IsUint() const { return (flags_ & kUintFlag) != 0; } 204 bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } 205 bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } 206 bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } 207 bool IsString() const { return (flags_ & kStringFlag) != 0; } 208 209 //@} 210 211 //!@name Null 212 //@{ 213 214 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } 215 216 //@} 217 218 //!@name Bool 219 //@{ 220 221 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } 222 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } 223 224 //@} 225 226 //!@name Object 227 //@{ 228 229 //! Set this value as an empty object. 230 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } 231 232 //! Get the value associated with the name. 233 /*! 234 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. 235 Since 0.2, if the name is not correct, it will assert. 236 If user is unsure whether a member exists, user should use HasMember() first. 237 A better approach is to use the now public FindMember(). 238 */ 239 GenericValue& operator[](const Ch* name) { 240 if (Member* member = FindMember(name)) 241 return member->value; 242 else { 243 RAPIDJSON_ASSERT(false); // see above note 244 static GenericValue NullValue; 245 return NullValue; 246 } 247 } 248 const GenericValue& operator[](const Ch* name) const { return const_cast<GenericValue&>(*this)[name]; } 249 250 //! Member iterators. 251 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } 252 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } 253 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } 254 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } 255 256 //! Check whether a member exists in the object. 257 /*! 258 \note It is better to use FindMember() directly if you need the obtain the value as well. 259 */ 260 bool HasMember(const Ch* name) const { return FindMember(name) != 0; } 261 262 //! Find member by name. 263 /*! 264 \return Return the member if exists. Otherwise returns null pointer. 265 */ 266 Member* FindMember(const Ch* name) { 267 RAPIDJSON_ASSERT(name); 268 RAPIDJSON_ASSERT(IsObject()); 269 270 Object& o = data_.o; 271 for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) 272 if (name[member->name.data_.s.length] == '\0' && memcmp(member->name.data_.s.str, name, member->name.data_.s.length * sizeof(Ch)) == 0) 273 return member; 274 275 return 0; 276 } 277 const Member* FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } 278 279 //! Add a member (name-value pair) to the object. 280 /*! \param name A string value as name of member. 281 \param value Value of any type. 282 \param allocator Allocator for reallocating memory. 283 \return The value itself for fluent API. 284 \note The ownership of name and value will be transfered to this object if success. 285 */ 286 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { 287 RAPIDJSON_ASSERT(IsObject()); 288 RAPIDJSON_ASSERT(name.IsString()); 289 Object& o = data_.o; 290 if (o.size >= o.capacity) { 291 if (o.capacity == 0) { 292 o.capacity = kDefaultObjectCapacity; 293 o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member)); 294 } 295 else { 296 SizeType oldCapacity = o.capacity; 297 o.capacity *= 2; 298 o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)); 299 } 300 } 301 o.members[o.size].name.RawAssign(name); 302 o.members[o.size].value.RawAssign(value); 303 o.size++; 304 return *this; 305 } 306 307 GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) { 308 GenericValue n(name, internal::StrLen(name), nameAllocator); 309 return AddMember(n, value, allocator); 310 } 311 312 GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) { 313 GenericValue n(name, internal::StrLen(name)); 314 return AddMember(n, value, allocator); 315 } 316 317 template <typename T> 318 GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) { 319 GenericValue n(name, internal::StrLen(name)); 320 GenericValue v(value); 321 return AddMember(n, v, allocator); 322 } 323 324 //! Remove a member in object by its name. 325 /*! \param name Name of member to be removed. 326 \return Whether the member existed. 327 \note Removing member is implemented by moving the last member. So the ordering of members is changed. 328 */ 329 bool RemoveMember(const Ch* name) { 330 RAPIDJSON_ASSERT(IsObject()); 331 if (Member* m = FindMember(name)) { 332 RAPIDJSON_ASSERT(data_.o.size > 0); 333 RAPIDJSON_ASSERT(data_.o.members != 0); 334 335 Member* last = data_.o.members + (data_.o.size - 1); 336 if (data_.o.size > 1 && m != last) { 337 // Move the last one to this place 338 m->name = last->name; 339 m->value = last->value; 340 } 341 else { 342 // Only one left, just destroy 343 m->name.~GenericValue(); 344 m->value.~GenericValue(); 345 } 346 --data_.o.size; 347 return true; 348 } 349 return false; 350 } 351 352 //@} 353 354 //!@name Array 355 //@{ 356 357 //! Set this value as an empty array. 358 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } 359 360 //! Get the number of elements in array. 361 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } 362 363 //! Get the capacity of array. 364 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } 365 366 //! Check whether the array is empty. 367 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } 368 369 //! Remove all elements in the array. 370 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. 371 */ 372 void Clear() { 373 RAPIDJSON_ASSERT(IsArray()); 374 for (SizeType i = 0; i < data_.a.size; ++i) 375 data_.a.elements[i].~GenericValue(); 376 data_.a.size = 0; 377 } 378 379 //! Get an element from array by index. 380 /*! \param index Zero-based index of element. 381 \note 382\code 383Value a(kArrayType); 384a.PushBack(123); 385int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. 386int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. 387int z = a[0u].GetInt(); // This works too. 388\endcode 389 */ 390 GenericValue& operator[](SizeType index) { 391 RAPIDJSON_ASSERT(IsArray()); 392 RAPIDJSON_ASSERT(index < data_.a.size); 393 return data_.a.elements[index]; 394 } 395 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } 396 397 //! Element iterator 398 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } 399 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } 400 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } 401 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } 402 403 //! Request the array to have enough capacity to store elements. 404 /*! \param newCapacity The capacity that the array at least need to have. 405 \param allocator The allocator for allocating memory. It must be the same one use previously. 406 \return The value itself for fluent API. 407 */ 408 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { 409 RAPIDJSON_ASSERT(IsArray()); 410 if (newCapacity > data_.a.capacity) { 411 data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); 412 data_.a.capacity = newCapacity; 413 } 414 return *this; 415 } 416 417 //! Append a value at the end of the array. 418 /*! \param value The value to be appended. 419 \param allocator The allocator for allocating memory. It must be the same one use previously. 420 \return The value itself for fluent API. 421 \note The ownership of the value will be transfered to this object if success. 422 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 423 */ 424 GenericValue& PushBack(GenericValue& value, Allocator& allocator) { 425 RAPIDJSON_ASSERT(IsArray()); 426 if (data_.a.size >= data_.a.capacity) 427 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); 428 data_.a.elements[data_.a.size++].RawAssign(value); 429 return *this; 430 } 431 432 template <typename T> 433 GenericValue& PushBack(T value, Allocator& allocator) { 434 GenericValue v(value); 435 return PushBack(v, allocator); 436 } 437 438 //! Remove the last element in the array. 439 GenericValue& PopBack() { 440 RAPIDJSON_ASSERT(IsArray()); 441 RAPIDJSON_ASSERT(!Empty()); 442 data_.a.elements[--data_.a.size].~GenericValue(); 443 return *this; 444 } 445 //@} 446 447 //!@name Number 448 //@{ 449 450 int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } 451 unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } 452 int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } 453 uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } 454 455 double GetDouble() const { 456 RAPIDJSON_ASSERT(IsNumber()); 457 if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. 458 if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double 459 if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double 460 if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) 461 RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) 462 } 463 464 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } 465 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } 466 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } 467 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } 468 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } 469 470 //@} 471 472 //!@name String 473 //@{ 474 475 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; } 476 477 //! Get the length of string. 478 /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). 479 */ 480 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; } 481 482 //! Set this value as a string without copying source string. 483 /*! This version has better performance with supplied length, and also support string containing null character. 484 \param s source string pointer. 485 \param length The length of source string, excluding the trailing null terminator. 486 \return The value itself for fluent API. 487 */ 488 GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; } 489 490 //! Set this value as a string without copying source string. 491 /*! \param s source string pointer. 492 \return The value itself for fluent API. 493 */ 494 GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); } 495 496 //! Set this value as a string by copying from source string. 497 /*! This version has better performance with supplied length, and also support string containing null character. 498 \param s source string. 499 \param length The length of source string, excluding the trailing null terminator. 500 \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). 501 \return The value itself for fluent API. 502 */ 503 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; } 504 505 //! Set this value as a string by copying from source string. 506 /*! \param s source string. 507 \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). 508 \return The value itself for fluent API. 509 */ 510 GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; } 511 512 //@} 513 514 //! Generate events of this value to a Handler. 515 /*! This function adopts the GoF visitor pattern. 516 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. 517 It can also be used to deep clone this value via GenericDocument, which is also a Handler. 518 \tparam Handler type of handler. 519 \param handler An object implementing concept Handler. 520 */ 521 template <typename Handler> 522 const GenericValue& Accept(Handler& handler) const { 523 switch(GetType()) { 524 case kNullType: handler.Null(); break; 525 case kFalseType: handler.Bool(false); break; 526 case kTrueType: handler.Bool(true); break; 527 528 case kObjectType: 529 handler.StartObject(); 530 for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { 531 handler.String(m->name.data_.s.str, m->name.data_.s.length, false); 532 m->value.Accept(handler); 533 } 534 handler.EndObject(data_.o.size); 535 break; 536 537 case kArrayType: 538 handler.StartArray(); 539 for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) 540 v->Accept(handler); 541 handler.EndArray(data_.a.size); 542 break; 543 544 case kStringType: 545 handler.String(data_.s.str, data_.s.length, false); 546 break; 547 548 case kNumberType: 549 if (IsInt()) handler.Int(data_.n.i.i); 550 else if (IsUint()) handler.Uint(data_.n.u.u); 551 else if (IsInt64()) handler.Int64(data_.n.i64); 552 else if (IsUint64()) handler.Uint64(data_.n.u64); 553 else handler.Double(data_.n.d); 554 break; 555 } 556 return *this; 557 } 558 559private: 560 template <typename, typename> 561 friend class GenericDocument; 562 563 enum { 564 kBoolFlag = 0x100, 565 kNumberFlag = 0x200, 566 kIntFlag = 0x400, 567 kUintFlag = 0x800, 568 kInt64Flag = 0x1000, 569 kUint64Flag = 0x2000, 570 kDoubleFlag = 0x4000, 571 kStringFlag = 0x100000, 572 kCopyFlag = 0x200000, 573 574 // Initial flags of different types. 575 kNullFlag = kNullType, 576 kTrueFlag = kTrueType | kBoolFlag, 577 kFalseFlag = kFalseType | kBoolFlag, 578 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, 579 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, 580 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, 581 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, 582 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, 583 kConstStringFlag = kStringType | kStringFlag, 584 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, 585 kObjectFlag = kObjectType, 586 kArrayFlag = kArrayType, 587 588 kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler 589 }; 590 591 static const SizeType kDefaultArrayCapacity = 16; 592 static const SizeType kDefaultObjectCapacity = 16; 593 594 struct String { 595 const Ch* str; 596 SizeType length; 597 unsigned hashcode; //!< reserved 598 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 599 600 // By using proper binary layout, retrieval of different integer types do not need conversions. 601 union Number { 602#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN 603 struct I { 604 int i; 605 char padding[4]; 606 }i; 607 struct U { 608 unsigned u; 609 char padding2[4]; 610 }u; 611#else 612 struct I { 613 char padding[4]; 614 int i; 615 }i; 616 struct U { 617 char padding2[4]; 618 unsigned u; 619 }u; 620#endif 621 int64_t i64; 622 uint64_t u64; 623 double d; 624 }; // 8 bytes 625 626 struct Object { 627 Member* members; 628 SizeType size; 629 SizeType capacity; 630 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 631 632 struct Array { 633 GenericValue<Encoding, Allocator>* elements; 634 SizeType size; 635 SizeType capacity; 636 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 637 638 union Data { 639 String s; 640 Number n; 641 Object o; 642 Array a; 643 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 644 645 // Initialize this value as array with initial data, without calling destructor. 646 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) { 647 flags_ = kArrayFlag; 648 data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue)); 649 memcpy(data_.a.elements, values, count * sizeof(GenericValue)); 650 data_.a.size = data_.a.capacity = count; 651 } 652 653 //! Initialize this value as object with initial data, without calling destructor. 654 void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) { 655 flags_ = kObjectFlag; 656 data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member)); 657 memcpy(data_.o.members, members, count * sizeof(Member)); 658 data_.o.size = data_.o.capacity = count; 659 } 660 661 //! Initialize this value as constant string, without calling destructor. 662 void SetStringRaw(const Ch* s, SizeType length) { 663 RAPIDJSON_ASSERT(s != NULL); 664 flags_ = kConstStringFlag; 665 data_.s.str = s; 666 data_.s.length = length; 667 } 668 669 //! Initialize this value as copy string with initial data, without calling destructor. 670 void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) { 671 RAPIDJSON_ASSERT(s != NULL); 672 flags_ = kCopyStringFlag; 673 data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); 674 data_.s.length = length; 675 memcpy(const_cast<Ch*>(data_.s.str), s, length * sizeof(Ch)); 676 const_cast<Ch*>(data_.s.str)[length] = '\0'; 677 } 678 679 //! Assignment without calling destructor 680 void RawAssign(GenericValue& rhs) { 681 memcpy(this, &rhs, sizeof(GenericValue)); 682 rhs.flags_ = kNullFlag; 683 } 684 685 Data data_; 686 unsigned flags_; 687}; 688#pragma pack (pop) 689 690//! Value with UTF8 encoding. 691typedef GenericValue<UTF8<> > Value; 692 693/////////////////////////////////////////////////////////////////////////////// 694// GenericDocument 695 696//! A document for parsing JSON text as DOM. 697/*! 698 \implements Handler 699 \tparam Encoding encoding for both parsing and string storage. 700 \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing. 701*/ 702template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 703class GenericDocument : public GenericValue<Encoding, Allocator> { 704public: 705 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 706 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document. 707 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 708 709 //! Constructor 710 /*! \param allocator Optional allocator for allocating stack memory. 711 \param stackCapacity Initial capacity of stack in bytes. 712 */ 713 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} 714 715 //! Parse JSON text from an input stream. 716 /*! \tparam parseFlags Combination of ParseFlag. 717 \param stream Input stream to be parsed. 718 \return The document itself for fluent API. 719 */ 720 template <unsigned parseFlags, typename SourceEncoding, typename InputStream> 721 GenericDocument& ParseStream(InputStream& is) { 722 ValueType::SetNull(); // Remove existing root if exist 723 GenericReader<SourceEncoding, Encoding, Allocator> reader; 724 if (reader.template Parse<parseFlags>(is, *this)) { 725 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object 726 this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13. 727 parseError_ = 0; 728 errorOffset_ = 0; 729 } 730 else { 731 parseError_ = reader.GetParseError(); 732 errorOffset_ = reader.GetErrorOffset(); 733 ClearStack(); 734 } 735 return *this; 736 } 737 738 //! Parse JSON text from a mutable string. 739 /*! \tparam parseFlags Combination of ParseFlag. 740 \param str Mutable zero-terminated string to be parsed. 741 \return The document itself for fluent API. 742 */ 743 template <unsigned parseFlags, typename SourceEncoding> 744 GenericDocument& ParseInsitu(Ch* str) { 745 GenericInsituStringStream<Encoding> s(str); 746 return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s); 747 } 748 749 template <unsigned parseFlags> 750 GenericDocument& ParseInsitu(Ch* str) { 751 return ParseInsitu<parseFlags, Encoding>(str); 752 } 753 754 //! Parse JSON text from a read-only string. 755 /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). 756 \param str Read-only zero-terminated string to be parsed. 757 */ 758 template <unsigned parseFlags, typename SourceEncoding> 759 GenericDocument& Parse(const Ch* str) { 760 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 761 GenericStringStream<SourceEncoding> s(str); 762 return ParseStream<parseFlags, SourceEncoding>(s); 763 } 764 765 template <unsigned parseFlags> 766 GenericDocument& Parse(const Ch* str) { 767 return Parse<parseFlags, Encoding>(str); 768 } 769 770 //! Whether a parse error was occured in the last parsing. 771 bool HasParseError() const { return parseError_ != 0; } 772 773 //! Get the message of parsing error. 774 const char* GetParseError() const { return parseError_; } 775 776 //! Get the offset in character of the parsing error. 777 size_t GetErrorOffset() const { return errorOffset_; } 778 779 //! Get the allocator of this document. 780 Allocator& GetAllocator() { return stack_.GetAllocator(); } 781 782 //! Get the capacity of stack in bytes. 783 size_t GetStackCapacity() const { return stack_.GetCapacity(); } 784 785//private: 786 //friend class GenericReader<Encoding>; // for Reader to call the following private handler functions 787 788 // Implementation of Handler 789 void Null() { new (stack_.template Push<ValueType>()) ValueType(); } 790 void Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); } 791 void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); } 792 void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); } 793 void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); } 794 void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); } 795 void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); } 796 797 void String(const Ch* str, SizeType length, bool copy) { 798 if (copy) 799 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); 800 else 801 new (stack_.template Push<ValueType>()) ValueType(str, length); 802 } 803 804 void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); } 805 806 void EndObject(SizeType memberCount) { 807 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); 808 stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); 809 } 810 811 void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); } 812 813 void EndArray(SizeType elementCount) { 814 ValueType* elements = stack_.template Pop<ValueType>(elementCount); 815 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); 816 } 817 818private: 819 // Prohibit assignment 820 GenericDocument& operator=(const GenericDocument&); 821 822 void ClearStack() { 823 if (Allocator::kNeedFree) 824 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) 825 (stack_.template Pop<ValueType>(1))->~<a href="/coding/class/classrapidjson_1_1genericdocument/#classrapidjson_1_1genericdocument_1aa9528dbbcc30ba9bad5f95d893caa772">ValueType</a>(); 826 else 827 stack_.Clear(); 828 } 829 830 static const size_t kDefaultStackCapacity = 1024; 831 internal::Stack<Allocator> stack_; 832 const char* parseError_; 833 size_t errorOffset_; 834}; 835 836typedef GenericDocument<UTF8<> > Document; 837 838} // namespace rapidjson 839 840#ifdef _MSC_VER 841#pragma warning(pop) 842#endif 843 844#endif // RAPIDJSON_DOCUMENT_H_ 845
