document.h

Engine/source/persistence/rapidjson/document.h

More...

Classes:

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