]> granicus.if.org Git - pdns/commitdiff
Convert rapidjson headers to unix LF
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Mon, 29 Sep 2014 18:46:14 +0000 (20:46 +0200)
committerRuben Kerkhof <ruben@rubenkerkhof.com>
Mon, 29 Sep 2014 18:46:14 +0000 (20:46 +0200)
pdns/ext/rapidjson/include/rapidjson/document.h
pdns/ext/rapidjson/include/rapidjson/filestream.h
pdns/ext/rapidjson/include/rapidjson/internal/pow10.h
pdns/ext/rapidjson/include/rapidjson/internal/stack.h
pdns/ext/rapidjson/include/rapidjson/internal/strfunc.h
pdns/ext/rapidjson/include/rapidjson/prettywriter.h
pdns/ext/rapidjson/include/rapidjson/rapidjson.h
pdns/ext/rapidjson/include/rapidjson/reader.h
pdns/ext/rapidjson/include/rapidjson/stringbuffer.h
pdns/ext/rapidjson/include/rapidjson/writer.h
pdns/ext/rapidjson/license.txt

index 402b65d871464b705d281b2ca5de615d374c12ee..83d95a33d08a674e6e9f3215a5b66e824ba9e8bf 100644 (file)
-#ifndef RAPIDJSON_DOCUMENT_H_\r
-#define RAPIDJSON_DOCUMENT_H_\r
-\r
-#include "reader.h"\r
-#include "internal/strfunc.h"\r
-#include <new>         // placement new\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(push)\r
-#pragma warning(disable : 4127) // conditional expression is constant\r
-#endif\r
-\r
-namespace rapidjson {\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// GenericValue\r
-\r
-//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.\r
-/*!\r
-       A JSON value can be one of 7 types. This class is a variant type supporting\r
-       these types.\r
-\r
-       Use the Value if UTF8 and default allocator\r
-\r
-       \tparam Encoding        Encoding of the value. (Even non-string values need to have the same encoding in a document)\r
-       \tparam Allocator       Allocator type for allocating memory of object, array and string.\r
-*/\r
-#pragma pack (push, 4)\r
-template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > \r
-class GenericValue {\r
-public:\r
-       //! Name-value pair in an object.\r
-       struct Member { \r
-               GenericValue<Encoding, Allocator> name;         //!< name of member (must be a string)\r
-               GenericValue<Encoding, Allocator> value;        //!< value of member.\r
-       };\r
-\r
-       typedef Encoding EncodingType;                                  //!< Encoding type from template parameter.\r
-       typedef Allocator AllocatorType;                                //!< Allocator type from template parameter.\r
-       typedef typename Encoding::Ch Ch;                               //!< Character type derived from Encoding.\r
-       typedef Member* MemberIterator;                                 //!< Member iterator for iterating in object.\r
-       typedef const Member* ConstMemberIterator;              //!< Constant member iterator for iterating in object.\r
-       typedef GenericValue* ValueIterator;                    //!< Value iterator for iterating in array.\r
-       typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.\r
-\r
-       //!@name Constructors and destructor.\r
-       //@{\r
-\r
-       //! Default constructor creates a null value.\r
-       GenericValue() : flags_(kNullFlag) {}\r
-\r
-       //! Copy constructor is not permitted.\r
-private:\r
-       GenericValue(const GenericValue& rhs);\r
-\r
-public:\r
-\r
-       //! Constructor with JSON value type.\r
-       /*! This creates a Value of specified type with default content.\r
-               \param type     Type of the value.\r
-               \note Default content for number is zero.\r
-       */\r
-       GenericValue(Type type) {\r
-               static const unsigned defaultFlags[7] = {\r
-                       kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,\r
-                       kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag\r
-               };\r
-               RAPIDJSON_ASSERT(type <= kNumberType);\r
-               flags_ = defaultFlags[type];\r
-               memset(&data_, 0, sizeof(data_));\r
-       }\r
-\r
-       //! Constructor for boolean value.\r
-       GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}\r
-\r
-       //! Constructor for int value.\r
-       GenericValue(int i) : flags_(kNumberIntFlag) { \r
-               data_.n.i64 = i;\r
-               if (i >= 0)\r
-                       flags_ |= kUintFlag | kUint64Flag;\r
-       }\r
-\r
-       //! Constructor for unsigned value.\r
-       GenericValue(unsigned u) : flags_(kNumberUintFlag) {\r
-               data_.n.u64 = u; \r
-               if (!(u & 0x80000000))\r
-                       flags_ |= kIntFlag | kInt64Flag;\r
-       }\r
-\r
-       //! Constructor for int64_t value.\r
-       GenericValue(int64_t i64) : flags_(kNumberInt64Flag) {\r
-               data_.n.i64 = i64;\r
-               if (i64 >= 0) {\r
-                       flags_ |= kNumberUint64Flag;\r
-                       if (!(i64 & 0xFFFFFFFF00000000LL))\r
-                               flags_ |= kUintFlag;\r
-                       if (!(i64 & 0xFFFFFFFF80000000LL))\r
-                               flags_ |= kIntFlag;\r
-               }\r
-               else if (i64 >= -2147483648LL)\r
-                       flags_ |= kIntFlag;\r
-       }\r
-\r
-       //! Constructor for uint64_t value.\r
-       GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) {\r
-               data_.n.u64 = u64;\r
-               if (!(u64 & 0x8000000000000000ULL))\r
-                       flags_ |= kInt64Flag;\r
-               if (!(u64 & 0xFFFFFFFF00000000ULL))\r
-                       flags_ |= kUintFlag;\r
-               if (!(u64 & 0xFFFFFFFF80000000ULL))\r
-                       flags_ |= kIntFlag;\r
-       }\r
-\r
-       //! Constructor for double value.\r
-       GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; }\r
-\r
-       //! Constructor for constant string (i.e. do not make a copy of string)\r
-       GenericValue(const Ch* s, SizeType length) { \r
-               RAPIDJSON_ASSERT(s != NULL);\r
-               flags_ = kConstStringFlag;\r
-               data_.s.str = s;\r
-               data_.s.length = length;\r
-       }\r
-\r
-       //! Constructor for constant string (i.e. do not make a copy of string)\r
-       GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); }\r
-\r
-       //! Constructor for copy-string (i.e. do make a copy of string)\r
-       GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); }\r
-\r
-       //! Constructor for copy-string (i.e. do make a copy of string)\r
-       GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); }\r
-\r
-       //! Destructor.\r
-       /*! Need to destruct elements of array, members of object, or copy-string.\r
-       */\r
-       ~GenericValue() {\r
-               if (Allocator::kNeedFree) {     // Shortcut by Allocator's trait\r
-                       switch(flags_) {\r
-                       case kArrayFlag:\r
-                               for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)\r
-                                       v->~GenericValue();\r
-                               Allocator::Free(data_.a.elements);\r
-                               break;\r
-\r
-                       case kObjectFlag:\r
-                               for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {\r
-                                       m->name.~GenericValue();\r
-                                       m->value.~GenericValue();\r
-                               }\r
-                               Allocator::Free(data_.o.members);\r
-                               break;\r
-\r
-                       case kCopyStringFlag:\r
-                               Allocator::Free(const_cast<Ch*>(data_.s.str));\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-\r
-       //@}\r
-\r
-       //!@name Assignment operators\r
-       //@{\r
-\r
-       //! Assignment with move semantics.\r
-       /*! \param rhs Source of the assignment. It will become a null value after assignment.\r
-       */\r
-       GenericValue& operator=(GenericValue& rhs) {\r
-               RAPIDJSON_ASSERT(this != &rhs);\r
-               this->~GenericValue();\r
-               memcpy(this, &rhs, sizeof(GenericValue));\r
-               rhs.flags_ = kNullFlag;\r
-               return *this;\r
-       }\r
-\r
-       //! Assignment with primitive types.\r
-       /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch*\r
-               \param value The value to be assigned.\r
-       */\r
-       template <typename T>\r
-       GenericValue& operator=(T value) {\r
-               this->~GenericValue();\r
-               new (this) GenericValue(value);\r
-               return *this;\r
-       }\r
-       //@}\r
-\r
-       //!@name Type\r
-       //@{\r
-\r
-       Type GetType()  const { return static_cast<Type>(flags_ & kTypeMask); }\r
-       bool IsNull()   const { return flags_ == kNullFlag; }\r
-       bool IsFalse()  const { return flags_ == kFalseFlag; }\r
-       bool IsTrue()   const { return flags_ == kTrueFlag; }\r
-       bool IsBool()   const { return (flags_ & kBoolFlag) != 0; }\r
-       bool IsObject() const { return flags_ == kObjectFlag; }\r
-       bool IsArray()  const { return flags_ == kArrayFlag; }\r
-       bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }\r
-       bool IsInt()    const { return (flags_ & kIntFlag) != 0; }\r
-       bool IsUint()   const { return (flags_ & kUintFlag) != 0; }\r
-       bool IsInt64()  const { return (flags_ & kInt64Flag) != 0; }\r
-       bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }\r
-       bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }\r
-       bool IsString() const { return (flags_ & kStringFlag) != 0; }\r
-\r
-       //@}\r
-\r
-       //!@name Null\r
-       //@{\r
-\r
-       GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }\r
-\r
-       //@}\r
-\r
-       //!@name Bool\r
-       //@{\r
-\r
-       bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }\r
-       GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }\r
-\r
-       //@}\r
-\r
-       //!@name Object\r
-       //@{\r
-\r
-       //! Set this value as an empty object.\r
-       GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }\r
-\r
-       //! Get the value associated with the object's name.\r
-       GenericValue& operator[](const Ch* name) {\r
-               if (Member* member = FindMember(name))\r
-                       return member->value;\r
-               else {\r
-                       static GenericValue NullValue;\r
-                       return NullValue;\r
-               }\r
-       }\r
-       const GenericValue& operator[](const Ch* name) const { return const_cast<GenericValue&>(*this)[name]; }\r
-\r
-       //! Member iterators.\r
-       ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; }\r
-       ConstMemberIterator MemberEnd() const   { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; }\r
-       MemberIterator MemberBegin()                    { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; }\r
-       MemberIterator MemberEnd()                              { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; }\r
-\r
-       //! Check whether a member exists in the object.\r
-       bool HasMember(const Ch* name) const { return FindMember(name) != 0; }\r
-\r
-       //! Add a member (name-value pair) to the object.\r
-       /*! \param name A string value as name of member.\r
-               \param value Value of any type.\r
-           \param allocator Allocator for reallocating memory.\r
-           \return The value itself for fluent API.\r
-           \note The ownership of name and value will be transfered to this object if success.\r
-       */\r
-       GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {\r
-               RAPIDJSON_ASSERT(IsObject());\r
-               RAPIDJSON_ASSERT(name.IsString());\r
-               Object& o = data_.o;\r
-               if (o.size >= o.capacity) {\r
-                       if (o.capacity == 0) {\r
-                               o.capacity = kDefaultObjectCapacity;\r
-                               o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member));\r
-                       }\r
-                       else {\r
-                               SizeType oldCapacity = o.capacity;\r
-                               o.capacity *= 2;\r
-                               o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member));\r
-                       }\r
-               }\r
-               o.members[o.size].name.RawAssign(name);\r
-               o.members[o.size].value.RawAssign(value);\r
-               o.size++;\r
-               return *this;\r
-       }\r
-\r
-       GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) {\r
-               GenericValue n(name, internal::StrLen(name), nameAllocator);\r
-               return AddMember(n, value, allocator);\r
-       }\r
-\r
-       GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) {\r
-               GenericValue n(name, internal::StrLen(name));\r
-               return AddMember(n, value, allocator);\r
-       }\r
-\r
-       template <typename T>\r
-       GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) {\r
-               GenericValue n(name, internal::StrLen(name));\r
-               GenericValue v(value);\r
-               return AddMember(n, v, allocator);\r
-       }\r
-\r
-       //! Remove a member in object by its name.\r
-       /*! \param name Name of member to be removed.\r
-           \return Whether the member existed.\r
-           \note Removing member is implemented by moving the last member. So the ordering of members is changed.\r
-       */\r
-       bool RemoveMember(const Ch* name) {\r
-               RAPIDJSON_ASSERT(IsObject());\r
-               if (Member* m = FindMember(name)) {\r
-                       RAPIDJSON_ASSERT(data_.o.size > 0);\r
-                       RAPIDJSON_ASSERT(data_.o.members != 0);\r
-\r
-                       Member* last = data_.o.members + (data_.o.size - 1);\r
-                       if (data_.o.size > 1 && m != last) {\r
-                               // Move the last one to this place\r
-                               m->name = last->name;\r
-                               m->value = last->value;\r
-                       }\r
-                       else {\r
-                               // Only one left, just destroy\r
-                               m->name.~GenericValue();\r
-                               m->value.~GenericValue();\r
-                       }\r
-                       --data_.o.size;\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-\r
-       //@}\r
-\r
-       //!@name Array\r
-       //@{\r
-\r
-       //! Set this value as an empty array.\r
-       GenericValue& SetArray() {      this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }\r
-\r
-       //! Get the number of elements in array.\r
-       SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }\r
-\r
-       //! Get the capacity of array.\r
-       SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }\r
-\r
-       //! Check whether the array is empty.\r
-       bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }\r
-\r
-       //! Remove all elements in the array.\r
-       /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.\r
-       */\r
-       void Clear() {\r
-               RAPIDJSON_ASSERT(IsArray()); \r
-               for (SizeType i = 0; i < data_.a.size; ++i)\r
-                       data_.a.elements[i].~GenericValue();\r
-               data_.a.size = 0;\r
-       }\r
-\r
-       //! Get an element from array by index.\r
-       /*! \param index Zero-based index of element.\r
-               \note\r
-\code\r
-Value a(kArrayType);\r
-a.PushBack(123);\r
-int x = a[0].GetInt();                         // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type.\r
-int y = a[SizeType(0)].GetInt();       // Cast to SizeType will work.\r
-int z = a[0u].GetInt();                                // This works too.\r
-\endcode\r
-       */\r
-       GenericValue& operator[](SizeType index) {\r
-               RAPIDJSON_ASSERT(IsArray());\r
-               RAPIDJSON_ASSERT(index < data_.a.size);\r
-               return data_.a.elements[index];\r
-       }\r
-       const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }\r
-\r
-       //! Element iterator\r
-       ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }\r
-       ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; }\r
-       ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }\r
-       ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }\r
-\r
-       //! Request the array to have enough capacity to store elements.\r
-       /*! \param newCapacity  The capacity that the array at least need to have.\r
-               \param allocator        The allocator for allocating memory. It must be the same one use previously.\r
-               \return The value itself for fluent API.\r
-       */\r
-       GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {\r
-               RAPIDJSON_ASSERT(IsArray());\r
-               if (newCapacity > data_.a.capacity) {\r
-                       data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));\r
-                       data_.a.capacity = newCapacity;\r
-               }\r
-               return *this;\r
-       }\r
-\r
-       //! Append a value at the end of the array.\r
-       /*! \param value                The value to be appended.\r
-           \param allocator    The allocator for allocating memory. It must be the same one use previously.\r
-           \return The value itself for fluent API.\r
-           \note The ownership of the value will be transfered to this object if success.\r
-           \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\r
-       */\r
-       GenericValue& PushBack(GenericValue& value, Allocator& allocator) {\r
-               RAPIDJSON_ASSERT(IsArray());\r
-               if (data_.a.size >= data_.a.capacity)\r
-                       Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator);\r
-               data_.a.elements[data_.a.size++].RawAssign(value);\r
-               return *this;\r
-       }\r
-\r
-       template <typename T>\r
-       GenericValue& PushBack(T value, Allocator& allocator) {\r
-               GenericValue v(value);\r
-               return PushBack(v, allocator);\r
-       }\r
-\r
-       //! Remove the last element in the array.\r
-       GenericValue& PopBack() {\r
-               RAPIDJSON_ASSERT(IsArray());\r
-               RAPIDJSON_ASSERT(!Empty());\r
-               data_.a.elements[--data_.a.size].~GenericValue();\r
-               return *this;\r
-       }\r
-       //@}\r
-\r
-       //!@name Number\r
-       //@{\r
-\r
-       int GetInt() const                      { RAPIDJSON_ASSERT(flags_ & kIntFlag);   return data_.n.i.i;   }\r
-       unsigned GetUint() const        { RAPIDJSON_ASSERT(flags_ & kUintFlag);  return data_.n.u.u;   }\r
-       int64_t GetInt64() const        { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }\r
-       uint64_t GetUint64() const      { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }\r
-\r
-       double GetDouble() const {\r
-               RAPIDJSON_ASSERT(IsNumber());\r
-               if ((flags_ & kDoubleFlag) != 0)                                return data_.n.d;       // exact type, no conversion.\r
-               if ((flags_ & kIntFlag) != 0)                                   return data_.n.i.i;     // int -> double\r
-               if ((flags_ & kUintFlag) != 0)                                  return data_.n.u.u;     // unsigned -> double\r
-               if ((flags_ & kInt64Flag) != 0)                                 return (double)data_.n.i64; // int64_t -> double (may lose precision)\r
-               RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);  return (double)data_.n.u64;     // uint64_t -> double (may lose precision)\r
-       }\r
-\r
-       GenericValue& SetInt(int i)                             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }\r
-       GenericValue& SetUint(unsigned u)               { this->~GenericValue(); new (this) GenericValue(u);    return *this; }\r
-       GenericValue& SetInt64(int64_t i64)             { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }\r
-       GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }\r
-       GenericValue& SetDouble(double d)               { this->~GenericValue(); new (this) GenericValue(d);    return *this; }\r
-\r
-       //@}\r
-\r
-       //!@name String\r
-       //@{\r
-\r
-       const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; }\r
-\r
-       //! Get the length of string.\r
-       /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().\r
-       */\r
-       SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; }\r
-\r
-       //! Set this value as a string without copying source string.\r
-       /*! This version has better performance with supplied length, and also support string containing null character.\r
-               \param s source string pointer. \r
-               \param length The length of source string, excluding the trailing null terminator.\r
-               \return The value itself for fluent API.\r
-       */\r
-       GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; }\r
-\r
-       //! Set this value as a string without copying source string.\r
-       /*! \param s source string pointer. \r
-               \return The value itself for fluent API.\r
-       */\r
-       GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); }\r
-\r
-       //! Set this value as a string by copying from source string.\r
-       /*! This version has better performance with supplied length, and also support string containing null character.\r
-               \param s source string. \r
-               \param length The length of source string, excluding the trailing null terminator.\r
-               \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().\r
-               \return The value itself for fluent API.\r
-       */\r
-       GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; }\r
-\r
-       //! Set this value as a string by copying from source string.\r
-       /*!     \param s source string. \r
-               \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().\r
-               \return The value itself for fluent API.\r
-       */\r
-       GenericValue& SetString(const Ch* s, Allocator& allocator) {    SetString(s, internal::StrLen(s), allocator); return *this; }\r
-\r
-       //@}\r
-\r
-       //! Generate events of this value to a Handler.\r
-       /*! This function adopts the GoF visitor pattern.\r
-               Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.\r
-               It can also be used to deep clone this value via GenericDocument, which is also a Handler.\r
-               \tparam Handler type of handler.\r
-               \param handler An object implementing concept Handler.\r
-       */\r
-       template <typename Handler>\r
-       const GenericValue& Accept(Handler& handler) const {\r
-               switch(GetType()) {\r
-               case kNullType:         handler.Null(); break;\r
-               case kFalseType:        handler.Bool(false); break;\r
-               case kTrueType:         handler.Bool(true); break;\r
-\r
-               case kObjectType:\r
-                       handler.StartObject();\r
-                       for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {\r
-                               handler.String(m->name.data_.s.str, m->name.data_.s.length, false);\r
-                               m->value.Accept(handler);\r
-                       }\r
-                       handler.EndObject(data_.o.size);\r
-                       break;\r
-\r
-               case kArrayType:\r
-                       handler.StartArray();\r
-                       for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)\r
-                               v->Accept(handler);\r
-                       handler.EndArray(data_.a.size);\r
-                       break;\r
-\r
-               case kStringType:\r
-                       handler.String(data_.s.str, data_.s.length, false);\r
-                       break;\r
-\r
-               case kNumberType:\r
-                       if (IsInt())                    handler.Int(data_.n.i.i);\r
-                       else if (IsUint())              handler.Uint(data_.n.u.u);\r
-                       else if (IsInt64())             handler.Int64(data_.n.i64);\r
-                       else if (IsUint64())    handler.Uint64(data_.n.u64);\r
-                       else                                    handler.Double(data_.n.d);\r
-                       break;\r
-               }\r
-               return *this;\r
-       }\r
-\r
-private:\r
-       template <typename, typename>\r
-       friend class GenericDocument;\r
-\r
-       enum {\r
-               kBoolFlag = 0x100,\r
-               kNumberFlag = 0x200,\r
-               kIntFlag = 0x400,\r
-               kUintFlag = 0x800,\r
-               kInt64Flag = 0x1000,\r
-               kUint64Flag = 0x2000,\r
-               kDoubleFlag = 0x4000,\r
-               kStringFlag = 0x100000,\r
-               kCopyFlag = 0x200000,\r
-\r
-               // Initial flags of different types.\r
-               kNullFlag = kNullType,\r
-               kTrueFlag = kTrueType | kBoolFlag,\r
-               kFalseFlag = kFalseType | kBoolFlag,\r
-               kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,\r
-               kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,\r
-               kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,\r
-               kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,\r
-               kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,\r
-               kConstStringFlag = kStringType | kStringFlag,\r
-               kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,\r
-               kObjectFlag = kObjectType,\r
-               kArrayFlag = kArrayType,\r
-\r
-               kTypeMask = 0xFF        // bitwise-and with mask of 0xFF can be optimized by compiler\r
-       };\r
-\r
-       static const SizeType kDefaultArrayCapacity = 16;\r
-       static const SizeType kDefaultObjectCapacity = 16;\r
-\r
-       struct String {\r
-               const Ch* str;\r
-               SizeType length;\r
-               unsigned hashcode;      //!< reserved\r
-       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\r
-\r
-       // By using proper binary layout, retrieval of different integer types do not need conversions.\r
-       union Number {\r
-#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN\r
-               struct I {\r
-                       int i;\r
-                       char padding[4];\r
-               }i;\r
-               struct U {\r
-                       unsigned u;\r
-                       char padding2[4];\r
-               }u;\r
-#else\r
-               struct I {\r
-                       char padding[4];\r
-                       int i;\r
-               }i;\r
-               struct U {\r
-                       char padding2[4];\r
-                       unsigned u;\r
-               }u;\r
-#endif\r
-               int64_t i64;\r
-               uint64_t u64;\r
-               double d;\r
-       };      // 8 bytes\r
-\r
-       struct Object {\r
-               Member* members;\r
-               SizeType size;\r
-               SizeType capacity;\r
-       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\r
-\r
-       struct Array {\r
-               GenericValue<Encoding, Allocator>* elements;\r
-               SizeType size;\r
-               SizeType capacity;\r
-       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\r
-\r
-       union Data {\r
-               String s;\r
-               Number n;\r
-               Object o;\r
-               Array a;\r
-       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\r
-\r
-       //! Find member by name.\r
-       Member* FindMember(const Ch* name) {\r
-               RAPIDJSON_ASSERT(name);\r
-               RAPIDJSON_ASSERT(IsObject());\r
-\r
-               SizeType length = internal::StrLen(name);\r
-\r
-               Object& o = data_.o;\r
-               for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member)\r
-                       if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0)\r
-                               return member;\r
-\r
-               return 0;\r
-       }\r
-       const Member* FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }\r
-\r
-       // Initialize this value as array with initial data, without calling destructor.\r
-       void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) {\r
-               flags_ = kArrayFlag;\r
-               data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue));\r
-               memcpy(data_.a.elements, values, count * sizeof(GenericValue));\r
-               data_.a.size = data_.a.capacity = count;\r
-       }\r
-\r
-       //! Initialize this value as object with initial data, without calling destructor.\r
-       void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) {\r
-               flags_ = kObjectFlag;\r
-               data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member));\r
-               memcpy(data_.o.members, members, count * sizeof(Member));\r
-               data_.o.size = data_.o.capacity = count;\r
-       }\r
-\r
-       //! Initialize this value as constant string, without calling destructor.\r
-       void SetStringRaw(const Ch* s, SizeType length) {\r
-               RAPIDJSON_ASSERT(s != NULL);\r
-               flags_ = kConstStringFlag;\r
-               data_.s.str = s;\r
-               data_.s.length = length;\r
-       }\r
-\r
-       //! Initialize this value as copy string with initial data, without calling destructor.\r
-       void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) {\r
-               RAPIDJSON_ASSERT(s != NULL);\r
-               flags_ = kCopyStringFlag;\r
-               data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch));\r
-               data_.s.length = length;\r
-               memcpy(const_cast<Ch*>(data_.s.str), s, length * sizeof(Ch));\r
-               const_cast<Ch*>(data_.s.str)[length] = '\0';\r
-       }\r
-\r
-       //! Assignment without calling destructor\r
-       void RawAssign(GenericValue& rhs) {\r
-               memcpy(this, &rhs, sizeof(GenericValue));\r
-               rhs.flags_ = kNullFlag;\r
-       }\r
-\r
-       Data data_;\r
-       unsigned flags_;\r
-};\r
-#pragma pack (pop)\r
-\r
-//! Value with UTF8 encoding.\r
-typedef GenericValue<UTF8<> > Value;\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// GenericDocument \r
-\r
-//! A document for parsing JSON text as DOM.\r
-/*!\r
-       \implements Handler\r
-       \tparam Encoding encoding for both parsing and string storage.\r
-       \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing.\r
-*/\r
-template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >\r
-class GenericDocument : public GenericValue<Encoding, Allocator> {\r
-public:\r
-       typedef typename Encoding::Ch Ch;                                               //!< Character type derived from Encoding.\r
-       typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.\r
-       typedef Allocator AllocatorType;                                                //!< Allocator type from template parameter.\r
-\r
-       //! Constructor\r
-       /*! \param allocator            Optional allocator for allocating stack memory.\r
-               \param stackCapacity    Initial capacity of stack in bytes.\r
-       */\r
-       GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}\r
-\r
-       //! Parse JSON text from an input stream.\r
-       /*! \tparam parseFlags Combination of ParseFlag.\r
-               \param stream Input stream to be parsed.\r
-               \return The document itself for fluent API.\r
-       */\r
-       template <unsigned parseFlags, typename Stream>\r
-       GenericDocument& ParseStream(Stream& stream) {\r
-               ValueType::SetNull(); // Remove existing root if exist\r
-               GenericReader<Encoding, Allocator> reader;\r
-               if (reader.template Parse<parseFlags>(stream, *this)) {\r
-                       RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object\r
-                       this->RawAssign(*stack_.template Pop<ValueType>(1));    // Add this-> to prevent issue 13.\r
-                       parseError_ = 0;\r
-                       errorOffset_ = 0;\r
-               }\r
-               else {\r
-                       parseError_ = reader.GetParseError();\r
-                       errorOffset_ = reader.GetErrorOffset();\r
-                       ClearStack();\r
-               }\r
-               return *this;\r
-       }\r
-\r
-       //! Parse JSON text from a mutable string.\r
-       /*! \tparam parseFlags Combination of ParseFlag.\r
-               \param str Mutable zero-terminated string to be parsed.\r
-               \return The document itself for fluent API.\r
-       */\r
-       template <unsigned parseFlags>\r
-       GenericDocument& ParseInsitu(Ch* str) {\r
-               GenericInsituStringStream<Encoding> s(str);\r
-               return ParseStream<parseFlags | kParseInsituFlag>(s);\r
-       }\r
-\r
-       //! Parse JSON text from a read-only string.\r
-       /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag).\r
-               \param str Read-only zero-terminated string to be parsed.\r
-       */\r
-       template <unsigned parseFlags>\r
-       GenericDocument& Parse(const Ch* str) {\r
-               RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));\r
-               GenericStringStream<Encoding> s(str);\r
-               return ParseStream<parseFlags>(s);\r
-       }\r
-\r
-       //! Whether a parse error was occured in the last parsing.\r
-       bool HasParseError() const { return parseError_ != 0; }\r
-\r
-       //! Get the message of parsing error.\r
-       const char* GetParseError() const { return parseError_; }\r
-\r
-       //! Get the offset in character of the parsing error.\r
-       size_t GetErrorOffset() const { return errorOffset_; }\r
-\r
-       //! Get the allocator of this document.\r
-       Allocator& GetAllocator() {     return stack_.GetAllocator(); }\r
-\r
-       //! Get the capacity of stack in bytes.\r
-       size_t GetStackCapacity() const { return stack_.GetCapacity(); }\r
-\r
-private:\r
-       // Prohibit assignment\r
-       GenericDocument& operator=(const GenericDocument&);\r
-\r
-       friend class GenericReader<Encoding, Allocator>;        // for Reader to call the following private handler functions\r
-\r
-       // Implementation of Handler\r
-       void Null()     { new (stack_.template Push<ValueType>()) ValueType(); }\r
-       void Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); }\r
-       void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); }\r
-       void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); }\r
-       void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }\r
-       void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }\r
-       void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); }\r
-\r
-       void String(const Ch* str, SizeType length, bool copy) { \r
-               if (copy) \r
-                       new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());\r
-               else\r
-                       new (stack_.template Push<ValueType>()) ValueType(str, length);\r
-       }\r
-\r
-       void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); }\r
-       \r
-       void EndObject(SizeType memberCount) {\r
-               typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);\r
-               stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());\r
-       }\r
-\r
-       void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); }\r
-       \r
-       void EndArray(SizeType elementCount) {\r
-               ValueType* elements = stack_.template Pop<ValueType>(elementCount);\r
-               stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());\r
-       }\r
-\r
-       void ClearStack() {\r
-               if (Allocator::kNeedFree)\r
-                       while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)\r
-                               (stack_.template Pop<ValueType>(1))->~ValueType();\r
-               else\r
-                       stack_.Clear();\r
-       }\r
-\r
-       static const size_t kDefaultStackCapacity = 1024;\r
-       internal::Stack<Allocator> stack_;\r
-       const char* parseError_;\r
-       size_t errorOffset_;\r
-};\r
-\r
-typedef GenericDocument<UTF8<> > Document;\r
-\r
-} // namespace rapidjson\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(pop)\r
-#endif\r
-\r
-#endif // RAPIDJSON_DOCUMENT_H_\r
+#ifndef RAPIDJSON_DOCUMENT_H_
+#define RAPIDJSON_DOCUMENT_H_
+
+#include "reader.h"
+#include "internal/strfunc.h"
+#include <new>         // placement new
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+
+namespace rapidjson {
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericValue
+
+//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
+/*!
+       A JSON value can be one of 7 types. This class is a variant type supporting
+       these types.
+
+       Use the Value if UTF8 and default allocator
+
+       \tparam Encoding        Encoding of the value. (Even non-string values need to have the same encoding in a document)
+       \tparam Allocator       Allocator type for allocating memory of object, array and string.
+*/
+#pragma pack (push, 4)
+template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 
+class GenericValue {
+public:
+       //! Name-value pair in an object.
+       struct Member { 
+               GenericValue<Encoding, Allocator> name;         //!< name of member (must be a string)
+               GenericValue<Encoding, Allocator> value;        //!< value of member.
+       };
+
+       typedef Encoding EncodingType;                                  //!< Encoding type from template parameter.
+       typedef Allocator AllocatorType;                                //!< Allocator type from template parameter.
+       typedef typename Encoding::Ch Ch;                               //!< Character type derived from Encoding.
+       typedef Member* MemberIterator;                                 //!< Member iterator for iterating in object.
+       typedef const Member* ConstMemberIterator;              //!< Constant member iterator for iterating in object.
+       typedef GenericValue* ValueIterator;                    //!< Value iterator for iterating in array.
+       typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
+
+       //!@name Constructors and destructor.
+       //@{
+
+       //! Default constructor creates a null value.
+       GenericValue() : flags_(kNullFlag) {}
+
+       //! Copy constructor is not permitted.
+private:
+       GenericValue(const GenericValue& rhs);
+
+public:
+
+       //! Constructor with JSON value type.
+       /*! This creates a Value of specified type with default content.
+               \param type     Type of the value.
+               \note Default content for number is zero.
+       */
+       GenericValue(Type type) {
+               static const unsigned defaultFlags[7] = {
+                       kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
+                       kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag
+               };
+               RAPIDJSON_ASSERT(type <= kNumberType);
+               flags_ = defaultFlags[type];
+               memset(&data_, 0, sizeof(data_));
+       }
+
+       //! Constructor for boolean value.
+       GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {}
+
+       //! Constructor for int value.
+       GenericValue(int i) : flags_(kNumberIntFlag) { 
+               data_.n.i64 = i;
+               if (i >= 0)
+                       flags_ |= kUintFlag | kUint64Flag;
+       }
+
+       //! Constructor for unsigned value.
+       GenericValue(unsigned u) : flags_(kNumberUintFlag) {
+               data_.n.u64 = u; 
+               if (!(u & 0x80000000))
+                       flags_ |= kIntFlag | kInt64Flag;
+       }
+
+       //! Constructor for int64_t value.
+       GenericValue(int64_t i64) : flags_(kNumberInt64Flag) {
+               data_.n.i64 = i64;
+               if (i64 >= 0) {
+                       flags_ |= kNumberUint64Flag;
+                       if (!(i64 & 0xFFFFFFFF00000000LL))
+                               flags_ |= kUintFlag;
+                       if (!(i64 & 0xFFFFFFFF80000000LL))
+                               flags_ |= kIntFlag;
+               }
+               else if (i64 >= -2147483648LL)
+                       flags_ |= kIntFlag;
+       }
+
+       //! Constructor for uint64_t value.
+       GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) {
+               data_.n.u64 = u64;
+               if (!(u64 & 0x8000000000000000ULL))
+                       flags_ |= kInt64Flag;
+               if (!(u64 & 0xFFFFFFFF00000000ULL))
+                       flags_ |= kUintFlag;
+               if (!(u64 & 0xFFFFFFFF80000000ULL))
+                       flags_ |= kIntFlag;
+       }
+
+       //! Constructor for double value.
+       GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; }
+
+       //! Constructor for constant string (i.e. do not make a copy of string)
+       GenericValue(const Ch* s, SizeType length) { 
+               RAPIDJSON_ASSERT(s != NULL);
+               flags_ = kConstStringFlag;
+               data_.s.str = s;
+               data_.s.length = length;
+       }
+
+       //! Constructor for constant string (i.e. do not make a copy of string)
+       GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); }
+
+       //! Constructor for copy-string (i.e. do make a copy of string)
+       GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); }
+
+       //! Constructor for copy-string (i.e. do make a copy of string)
+       GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); }
+
+       //! Destructor.
+       /*! Need to destruct elements of array, members of object, or copy-string.
+       */
+       ~GenericValue() {
+               if (Allocator::kNeedFree) {     // Shortcut by Allocator's trait
+                       switch(flags_) {
+                       case kArrayFlag:
+                               for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
+                                       v->~GenericValue();
+                               Allocator::Free(data_.a.elements);
+                               break;
+
+                       case kObjectFlag:
+                               for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {
+                                       m->name.~GenericValue();
+                                       m->value.~GenericValue();
+                               }
+                               Allocator::Free(data_.o.members);
+                               break;
+
+                       case kCopyStringFlag:
+                               Allocator::Free(const_cast<Ch*>(data_.s.str));
+                               break;
+                       }
+               }
+       }
+
+       //@}
+
+       //!@name Assignment operators
+       //@{
+
+       //! Assignment with move semantics.
+       /*! \param rhs Source of the assignment. It will become a null value after assignment.
+       */
+       GenericValue& operator=(GenericValue& rhs) {
+               RAPIDJSON_ASSERT(this != &rhs);
+               this->~GenericValue();
+               memcpy(this, &rhs, sizeof(GenericValue));
+               rhs.flags_ = kNullFlag;
+               return *this;
+       }
+
+       //! Assignment with primitive types.
+       /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch*
+               \param value The value to be assigned.
+       */
+       template <typename T>
+       GenericValue& operator=(T value) {
+               this->~GenericValue();
+               new (this) GenericValue(value);
+               return *this;
+       }
+       //@}
+
+       //!@name Type
+       //@{
+
+       Type GetType()  const { return static_cast<Type>(flags_ & kTypeMask); }
+       bool IsNull()   const { return flags_ == kNullFlag; }
+       bool IsFalse()  const { return flags_ == kFalseFlag; }
+       bool IsTrue()   const { return flags_ == kTrueFlag; }
+       bool IsBool()   const { return (flags_ & kBoolFlag) != 0; }
+       bool IsObject() const { return flags_ == kObjectFlag; }
+       bool IsArray()  const { return flags_ == kArrayFlag; }
+       bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }
+       bool IsInt()    const { return (flags_ & kIntFlag) != 0; }
+       bool IsUint()   const { return (flags_ & kUintFlag) != 0; }
+       bool IsInt64()  const { return (flags_ & kInt64Flag) != 0; }
+       bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }
+       bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }
+       bool IsString() const { return (flags_ & kStringFlag) != 0; }
+
+       //@}
+
+       //!@name Null
+       //@{
+
+       GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
+
+       //@}
+
+       //!@name Bool
+       //@{
+
+       bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }
+       GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
+
+       //@}
+
+       //!@name Object
+       //@{
+
+       //! Set this value as an empty object.
+       GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
+
+       //! Get the value associated with the object's name.
+       GenericValue& operator[](const Ch* name) {
+               if (Member* member = FindMember(name))
+                       return member->value;
+               else {
+                       static GenericValue NullValue;
+                       return NullValue;
+               }
+       }
+       const GenericValue& operator[](const Ch* name) const { return const_cast<GenericValue&>(*this)[name]; }
+
+       //! Member iterators.
+       ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; }
+       ConstMemberIterator MemberEnd() const   { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; }
+       MemberIterator MemberBegin()                    { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; }
+       MemberIterator MemberEnd()                              { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; }
+
+       //! Check whether a member exists in the object.
+       bool HasMember(const Ch* name) const { return FindMember(name) != 0; }
+
+       //! Add a member (name-value pair) to the object.
+       /*! \param name A string value as name of member.
+               \param value Value of any type.
+           \param allocator Allocator for reallocating memory.
+           \return The value itself for fluent API.
+           \note The ownership of name and value will be transfered to this object if success.
+       */
+       GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
+               RAPIDJSON_ASSERT(IsObject());
+               RAPIDJSON_ASSERT(name.IsString());
+               Object& o = data_.o;
+               if (o.size >= o.capacity) {
+                       if (o.capacity == 0) {
+                               o.capacity = kDefaultObjectCapacity;
+                               o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member));
+                       }
+                       else {
+                               SizeType oldCapacity = o.capacity;
+                               o.capacity *= 2;
+                               o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member));
+                       }
+               }
+               o.members[o.size].name.RawAssign(name);
+               o.members[o.size].value.RawAssign(value);
+               o.size++;
+               return *this;
+       }
+
+       GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) {
+               GenericValue n(name, internal::StrLen(name), nameAllocator);
+               return AddMember(n, value, allocator);
+       }
+
+       GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) {
+               GenericValue n(name, internal::StrLen(name));
+               return AddMember(n, value, allocator);
+       }
+
+       template <typename T>
+       GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) {
+               GenericValue n(name, internal::StrLen(name));
+               GenericValue v(value);
+               return AddMember(n, v, allocator);
+       }
+
+       //! Remove a member in object by its name.
+       /*! \param name Name of member to be removed.
+           \return Whether the member existed.
+           \note Removing member is implemented by moving the last member. So the ordering of members is changed.
+       */
+       bool RemoveMember(const Ch* name) {
+               RAPIDJSON_ASSERT(IsObject());
+               if (Member* m = FindMember(name)) {
+                       RAPIDJSON_ASSERT(data_.o.size > 0);
+                       RAPIDJSON_ASSERT(data_.o.members != 0);
+
+                       Member* last = data_.o.members + (data_.o.size - 1);
+                       if (data_.o.size > 1 && m != last) {
+                               // Move the last one to this place
+                               m->name = last->name;
+                               m->value = last->value;
+                       }
+                       else {
+                               // Only one left, just destroy
+                               m->name.~GenericValue();
+                               m->value.~GenericValue();
+                       }
+                       --data_.o.size;
+                       return true;
+               }
+               return false;
+       }
+
+       //@}
+
+       //!@name Array
+       //@{
+
+       //! Set this value as an empty array.
+       GenericValue& SetArray() {      this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
+
+       //! Get the number of elements in array.
+       SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
+
+       //! Get the capacity of array.
+       SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
+
+       //! Check whether the array is empty.
+       bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
+
+       //! Remove all elements in the array.
+       /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
+       */
+       void Clear() {
+               RAPIDJSON_ASSERT(IsArray()); 
+               for (SizeType i = 0; i < data_.a.size; ++i)
+                       data_.a.elements[i].~GenericValue();
+               data_.a.size = 0;
+       }
+
+       //! Get an element from array by index.
+       /*! \param index Zero-based index of element.
+               \note
+\code
+Value a(kArrayType);
+a.PushBack(123);
+int x = a[0].GetInt();                         // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type.
+int y = a[SizeType(0)].GetInt();       // Cast to SizeType will work.
+int z = a[0u].GetInt();                                // This works too.
+\endcode
+       */
+       GenericValue& operator[](SizeType index) {
+               RAPIDJSON_ASSERT(IsArray());
+               RAPIDJSON_ASSERT(index < data_.a.size);
+               return data_.a.elements[index];
+       }
+       const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
+
+       //! Element iterator
+       ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
+       ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; }
+       ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
+       ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
+
+       //! Request the array to have enough capacity to store elements.
+       /*! \param newCapacity  The capacity that the array at least need to have.
+               \param allocator        The allocator for allocating memory. It must be the same one use previously.
+               \return The value itself for fluent API.
+       */
+       GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
+               RAPIDJSON_ASSERT(IsArray());
+               if (newCapacity > data_.a.capacity) {
+                       data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
+                       data_.a.capacity = newCapacity;
+               }
+               return *this;
+       }
+
+       //! Append a value at the end of the array.
+       /*! \param value                The value to be appended.
+           \param allocator    The allocator for allocating memory. It must be the same one use previously.
+           \return The value itself for fluent API.
+           \note The ownership of the value will be transfered to this object if success.
+           \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
+       */
+       GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
+               RAPIDJSON_ASSERT(IsArray());
+               if (data_.a.size >= data_.a.capacity)
+                       Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator);
+               data_.a.elements[data_.a.size++].RawAssign(value);
+               return *this;
+       }
+
+       template <typename T>
+       GenericValue& PushBack(T value, Allocator& allocator) {
+               GenericValue v(value);
+               return PushBack(v, allocator);
+       }
+
+       //! Remove the last element in the array.
+       GenericValue& PopBack() {
+               RAPIDJSON_ASSERT(IsArray());
+               RAPIDJSON_ASSERT(!Empty());
+               data_.a.elements[--data_.a.size].~GenericValue();
+               return *this;
+       }
+       //@}
+
+       //!@name Number
+       //@{
+
+       int GetInt() const                      { RAPIDJSON_ASSERT(flags_ & kIntFlag);   return data_.n.i.i;   }
+       unsigned GetUint() const        { RAPIDJSON_ASSERT(flags_ & kUintFlag);  return data_.n.u.u;   }
+       int64_t GetInt64() const        { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }
+       uint64_t GetUint64() const      { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }
+
+       double GetDouble() const {
+               RAPIDJSON_ASSERT(IsNumber());
+               if ((flags_ & kDoubleFlag) != 0)                                return data_.n.d;       // exact type, no conversion.
+               if ((flags_ & kIntFlag) != 0)                                   return data_.n.i.i;     // int -> double
+               if ((flags_ & kUintFlag) != 0)                                  return data_.n.u.u;     // unsigned -> double
+               if ((flags_ & kInt64Flag) != 0)                                 return (double)data_.n.i64; // int64_t -> double (may lose precision)
+               RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);  return (double)data_.n.u64;     // uint64_t -> double (may lose precision)
+       }
+
+       GenericValue& SetInt(int i)                             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }
+       GenericValue& SetUint(unsigned u)               { this->~GenericValue(); new (this) GenericValue(u);    return *this; }
+       GenericValue& SetInt64(int64_t i64)             { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }
+       GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }
+       GenericValue& SetDouble(double d)               { this->~GenericValue(); new (this) GenericValue(d);    return *this; }
+
+       //@}
+
+       //!@name String
+       //@{
+
+       const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; }
+
+       //! Get the length of string.
+       /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
+       */
+       SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; }
+
+       //! Set this value as a string without copying source string.
+       /*! This version has better performance with supplied length, and also support string containing null character.
+               \param s source string pointer. 
+               \param length The length of source string, excluding the trailing null terminator.
+               \return The value itself for fluent API.
+       */
+       GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; }
+
+       //! Set this value as a string without copying source string.
+       /*! \param s source string pointer. 
+               \return The value itself for fluent API.
+       */
+       GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); }
+
+       //! Set this value as a string by copying from source string.
+       /*! This version has better performance with supplied length, and also support string containing null character.
+               \param s source string. 
+               \param length The length of source string, excluding the trailing null terminator.
+               \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().
+               \return The value itself for fluent API.
+       */
+       GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; }
+
+       //! Set this value as a string by copying from source string.
+       /*!     \param s source string. 
+               \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator().
+               \return The value itself for fluent API.
+       */
+       GenericValue& SetString(const Ch* s, Allocator& allocator) {    SetString(s, internal::StrLen(s), allocator); return *this; }
+
+       //@}
+
+       //! Generate events of this value to a Handler.
+       /*! This function adopts the GoF visitor pattern.
+               Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
+               It can also be used to deep clone this value via GenericDocument, which is also a Handler.
+               \tparam Handler type of handler.
+               \param handler An object implementing concept Handler.
+       */
+       template <typename Handler>
+       const GenericValue& Accept(Handler& handler) const {
+               switch(GetType()) {
+               case kNullType:         handler.Null(); break;
+               case kFalseType:        handler.Bool(false); break;
+               case kTrueType:         handler.Bool(true); break;
+
+               case kObjectType:
+                       handler.StartObject();
+                       for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {
+                               handler.String(m->name.data_.s.str, m->name.data_.s.length, false);
+                               m->value.Accept(handler);
+                       }
+                       handler.EndObject(data_.o.size);
+                       break;
+
+               case kArrayType:
+                       handler.StartArray();
+                       for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
+                               v->Accept(handler);
+                       handler.EndArray(data_.a.size);
+                       break;
+
+               case kStringType:
+                       handler.String(data_.s.str, data_.s.length, false);
+                       break;
+
+               case kNumberType:
+                       if (IsInt())                    handler.Int(data_.n.i.i);
+                       else if (IsUint())              handler.Uint(data_.n.u.u);
+                       else if (IsInt64())             handler.Int64(data_.n.i64);
+                       else if (IsUint64())    handler.Uint64(data_.n.u64);
+                       else                                    handler.Double(data_.n.d);
+                       break;
+               }
+               return *this;
+       }
+
+private:
+       template <typename, typename>
+       friend class GenericDocument;
+
+       enum {
+               kBoolFlag = 0x100,
+               kNumberFlag = 0x200,
+               kIntFlag = 0x400,
+               kUintFlag = 0x800,
+               kInt64Flag = 0x1000,
+               kUint64Flag = 0x2000,
+               kDoubleFlag = 0x4000,
+               kStringFlag = 0x100000,
+               kCopyFlag = 0x200000,
+
+               // Initial flags of different types.
+               kNullFlag = kNullType,
+               kTrueFlag = kTrueType | kBoolFlag,
+               kFalseFlag = kFalseType | kBoolFlag,
+               kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
+               kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
+               kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
+               kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
+               kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
+               kConstStringFlag = kStringType | kStringFlag,
+               kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
+               kObjectFlag = kObjectType,
+               kArrayFlag = kArrayType,
+
+               kTypeMask = 0xFF        // bitwise-and with mask of 0xFF can be optimized by compiler
+       };
+
+       static const SizeType kDefaultArrayCapacity = 16;
+       static const SizeType kDefaultObjectCapacity = 16;
+
+       struct String {
+               const Ch* str;
+               SizeType length;
+               unsigned hashcode;      //!< reserved
+       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
+
+       // By using proper binary layout, retrieval of different integer types do not need conversions.
+       union Number {
+#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
+               struct I {
+                       int i;
+                       char padding[4];
+               }i;
+               struct U {
+                       unsigned u;
+                       char padding2[4];
+               }u;
+#else
+               struct I {
+                       char padding[4];
+                       int i;
+               }i;
+               struct U {
+                       char padding2[4];
+                       unsigned u;
+               }u;
+#endif
+               int64_t i64;
+               uint64_t u64;
+               double d;
+       };      // 8 bytes
+
+       struct Object {
+               Member* members;
+               SizeType size;
+               SizeType capacity;
+       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
+
+       struct Array {
+               GenericValue<Encoding, Allocator>* elements;
+               SizeType size;
+               SizeType capacity;
+       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
+
+       union Data {
+               String s;
+               Number n;
+               Object o;
+               Array a;
+       };      // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
+
+       //! Find member by name.
+       Member* FindMember(const Ch* name) {
+               RAPIDJSON_ASSERT(name);
+               RAPIDJSON_ASSERT(IsObject());
+
+               SizeType length = internal::StrLen(name);
+
+               Object& o = data_.o;
+               for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member)
+                       if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0)
+                               return member;
+
+               return 0;
+       }
+       const Member* FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
+
+       // Initialize this value as array with initial data, without calling destructor.
+       void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) {
+               flags_ = kArrayFlag;
+               data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue));
+               memcpy(data_.a.elements, values, count * sizeof(GenericValue));
+               data_.a.size = data_.a.capacity = count;
+       }
+
+       //! Initialize this value as object with initial data, without calling destructor.
+       void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) {
+               flags_ = kObjectFlag;
+               data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member));
+               memcpy(data_.o.members, members, count * sizeof(Member));
+               data_.o.size = data_.o.capacity = count;
+       }
+
+       //! Initialize this value as constant string, without calling destructor.
+       void SetStringRaw(const Ch* s, SizeType length) {
+               RAPIDJSON_ASSERT(s != NULL);
+               flags_ = kConstStringFlag;
+               data_.s.str = s;
+               data_.s.length = length;
+       }
+
+       //! Initialize this value as copy string with initial data, without calling destructor.
+       void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) {
+               RAPIDJSON_ASSERT(s != NULL);
+               flags_ = kCopyStringFlag;
+               data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch));
+               data_.s.length = length;
+               memcpy(const_cast<Ch*>(data_.s.str), s, length * sizeof(Ch));
+               const_cast<Ch*>(data_.s.str)[length] = '\0';
+       }
+
+       //! Assignment without calling destructor
+       void RawAssign(GenericValue& rhs) {
+               memcpy(this, &rhs, sizeof(GenericValue));
+               rhs.flags_ = kNullFlag;
+       }
+
+       Data data_;
+       unsigned flags_;
+};
+#pragma pack (pop)
+
+//! Value with UTF8 encoding.
+typedef GenericValue<UTF8<> > Value;
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericDocument 
+
+//! A document for parsing JSON text as DOM.
+/*!
+       \implements Handler
+       \tparam Encoding encoding for both parsing and string storage.
+       \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing.
+*/
+template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
+class GenericDocument : public GenericValue<Encoding, Allocator> {
+public:
+       typedef typename Encoding::Ch Ch;                                               //!< Character type derived from Encoding.
+       typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.
+       typedef Allocator AllocatorType;                                                //!< Allocator type from template parameter.
+
+       //! Constructor
+       /*! \param allocator            Optional allocator for allocating stack memory.
+               \param stackCapacity    Initial capacity of stack in bytes.
+       */
+       GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
+
+       //! Parse JSON text from an input stream.
+       /*! \tparam parseFlags Combination of ParseFlag.
+               \param stream Input stream to be parsed.
+               \return The document itself for fluent API.
+       */
+       template <unsigned parseFlags, typename Stream>
+       GenericDocument& ParseStream(Stream& stream) {
+               ValueType::SetNull(); // Remove existing root if exist
+               GenericReader<Encoding, Allocator> reader;
+               if (reader.template Parse<parseFlags>(stream, *this)) {
+                       RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
+                       this->RawAssign(*stack_.template Pop<ValueType>(1));    // Add this-> to prevent issue 13.
+                       parseError_ = 0;
+                       errorOffset_ = 0;
+               }
+               else {
+                       parseError_ = reader.GetParseError();
+                       errorOffset_ = reader.GetErrorOffset();
+                       ClearStack();
+               }
+               return *this;
+       }
+
+       //! Parse JSON text from a mutable string.
+       /*! \tparam parseFlags Combination of ParseFlag.
+               \param str Mutable zero-terminated string to be parsed.
+               \return The document itself for fluent API.
+       */
+       template <unsigned parseFlags>
+       GenericDocument& ParseInsitu(Ch* str) {
+               GenericInsituStringStream<Encoding> s(str);
+               return ParseStream<parseFlags | kParseInsituFlag>(s);
+       }
+
+       //! Parse JSON text from a read-only string.
+       /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag).
+               \param str Read-only zero-terminated string to be parsed.
+       */
+       template <unsigned parseFlags>
+       GenericDocument& Parse(const Ch* str) {
+               RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
+               GenericStringStream<Encoding> s(str);
+               return ParseStream<parseFlags>(s);
+       }
+
+       //! Whether a parse error was occured in the last parsing.
+       bool HasParseError() const { return parseError_ != 0; }
+
+       //! Get the message of parsing error.
+       const char* GetParseError() const { return parseError_; }
+
+       //! Get the offset in character of the parsing error.
+       size_t GetErrorOffset() const { return errorOffset_; }
+
+       //! Get the allocator of this document.
+       Allocator& GetAllocator() {     return stack_.GetAllocator(); }
+
+       //! Get the capacity of stack in bytes.
+       size_t GetStackCapacity() const { return stack_.GetCapacity(); }
+
+private:
+       // Prohibit assignment
+       GenericDocument& operator=(const GenericDocument&);
+
+       friend class GenericReader<Encoding, Allocator>;        // for Reader to call the following private handler functions
+
+       // Implementation of Handler
+       void Null()     { new (stack_.template Push<ValueType>()) ValueType(); }
+       void Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); }
+       void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); }
+       void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); }
+       void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
+       void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
+       void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); }
+
+       void String(const Ch* str, SizeType length, bool copy) { 
+               if (copy) 
+                       new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
+               else
+                       new (stack_.template Push<ValueType>()) ValueType(str, length);
+       }
+
+       void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); }
+       
+       void EndObject(SizeType memberCount) {
+               typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
+               stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
+       }
+
+       void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); }
+       
+       void EndArray(SizeType elementCount) {
+               ValueType* elements = stack_.template Pop<ValueType>(elementCount);
+               stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
+       }
+
+       void ClearStack() {
+               if (Allocator::kNeedFree)
+                       while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
+                               (stack_.template Pop<ValueType>(1))->~ValueType();
+               else
+                       stack_.Clear();
+       }
+
+       static const size_t kDefaultStackCapacity = 1024;
+       internal::Stack<Allocator> stack_;
+       const char* parseError_;
+       size_t errorOffset_;
+};
+
+typedef GenericDocument<UTF8<> > Document;
+
+} // namespace rapidjson
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // RAPIDJSON_DOCUMENT_H_
index 24573aa48269e268f2eb846ba8375281b9172e59..885894963f6716d1caceac8ae9a633b59d687b76 100644 (file)
@@ -1,46 +1,46 @@
-#ifndef RAPIDJSON_FILESTREAM_H_\r
-#define RAPIDJSON_FILESTREAM_H_\r
-\r
-#include <cstdio>\r
-\r
-namespace rapidjson {\r
-\r
-//! Wrapper of C file stream for input or output.\r
-/*!\r
-       This simple wrapper does not check the validity of the stream.\r
-       \implements Stream\r
-*/\r
-class FileStream {\r
-public:\r
-       typedef char Ch;        //!< Character type. Only support char.\r
-\r
-       FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); }\r
-       char Peek() const { return current_; }\r
-       char Take() { char c = current_; Read(); return c; }\r
-       size_t Tell() const { return count_; }\r
-       void Put(char c) { fputc(c, fp_); }\r
-\r
-       // Not implemented\r
-       char* PutBegin() { return 0; }\r
-       size_t PutEnd(char*) { return 0; }\r
-\r
-private:\r
-       void Read() {\r
-               RAPIDJSON_ASSERT(fp_ != 0);\r
-               int c = fgetc(fp_);\r
-               if (c != EOF) {\r
-                       current_ = (char)c;\r
-                       count_++;\r
-               }\r
-               else\r
-                       current_ = '\0';\r
-       }\r
-\r
-       FILE* fp_;\r
-       char current_;\r
-       size_t count_;\r
-};\r
-\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_FILESTREAM_H_\r
+#ifndef RAPIDJSON_FILESTREAM_H_
+#define RAPIDJSON_FILESTREAM_H_
+
+#include <cstdio>
+
+namespace rapidjson {
+
+//! Wrapper of C file stream for input or output.
+/*!
+       This simple wrapper does not check the validity of the stream.
+       \implements Stream
+*/
+class FileStream {
+public:
+       typedef char Ch;        //!< Character type. Only support char.
+
+       FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); }
+       char Peek() const { return current_; }
+       char Take() { char c = current_; Read(); return c; }
+       size_t Tell() const { return count_; }
+       void Put(char c) { fputc(c, fp_); }
+
+       // Not implemented
+       char* PutBegin() { return 0; }
+       size_t PutEnd(char*) { return 0; }
+
+private:
+       void Read() {
+               RAPIDJSON_ASSERT(fp_ != 0);
+               int c = fgetc(fp_);
+               if (c != EOF) {
+                       current_ = (char)c;
+                       count_++;
+               }
+               else
+                       current_ = '\0';
+       }
+
+       FILE* fp_;
+       char current_;
+       size_t count_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_FILESTREAM_H_
index 0852539e77c7115c8cfcf1e848c093610ae4a3e1..bf3a9afb041125ae429c585ac45ac3577a68dee0 100644 (file)
@@ -1,54 +1,54 @@
-#ifndef RAPIDJSON_POW10_\r
-#define RAPIDJSON_POW10_\r
-\r
-namespace rapidjson {\r
-namespace internal {\r
-\r
-//! Computes integer powers of 10 in double (10.0^n).\r
-/*! This function uses lookup table for fast and accurate results.\r
-       \param n positive/negative exponent. Must <= 308.\r
-       \return 10.0^n\r
-*/\r
-inline double Pow10(int n) {\r
-       static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes\r
-               1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300,\r
-               1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280,\r
-               1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260,\r
-               1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240,\r
-               1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220,\r
-               1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200,\r
-               1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180,\r
-               1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160,\r
-               1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140,\r
-               1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120,\r
-               1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100,\r
-               1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, \r
-               1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, \r
-               1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, \r
-               1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, \r
-               1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,  1e-8,  1e-7,  1e-6,  1e-5,  1e-4,  1e-3,  1e-2,  1e-1,  1e+0,  \r
-               1e+1,  1e+2,  1e+3,  1e+4,  1e+5,  1e+6,  1e+7,  1e+8,  1e+9,  1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, \r
-               1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,\r
-               1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,\r
-               1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,\r
-               1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,\r
-               1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,\r
-               1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,\r
-               1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,\r
-               1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,\r
-               1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,\r
-               1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,\r
-               1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,\r
-               1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,\r
-               1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,\r
-               1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,\r
-               1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308\r
-       };\r
-       RAPIDJSON_ASSERT(n <= 308);\r
-       return n < -308 ? 0.0 : e[n + 308];\r
-}\r
-\r
-} // namespace internal\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_POW10_\r
+#ifndef RAPIDJSON_POW10_
+#define RAPIDJSON_POW10_
+
+namespace rapidjson {
+namespace internal {
+
+//! Computes integer powers of 10 in double (10.0^n).
+/*! This function uses lookup table for fast and accurate results.
+       \param n positive/negative exponent. Must <= 308.
+       \return 10.0^n
+*/
+inline double Pow10(int n) {
+       static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes
+               1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300,
+               1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280,
+               1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260,
+               1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240,
+               1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220,
+               1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200,
+               1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180,
+               1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160,
+               1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140,
+               1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120,
+               1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100,
+               1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 
+               1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 
+               1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 
+               1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 
+               1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,  1e-8,  1e-7,  1e-6,  1e-5,  1e-4,  1e-3,  1e-2,  1e-1,  1e+0,  
+               1e+1,  1e+2,  1e+3,  1e+4,  1e+5,  1e+6,  1e+7,  1e+8,  1e+9,  1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 
+               1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
+               1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
+               1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
+               1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
+               1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
+               1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
+               1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
+               1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
+               1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
+               1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
+               1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
+               1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
+               1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
+               1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
+               1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
+       };
+       RAPIDJSON_ASSERT(n <= 308);
+       return n < -308 ? 0.0 : e[n + 308];
+}
+
+} // namespace internal
+} // namespace rapidjson
+
+#endif // RAPIDJSON_POW10_
index 3138b961f3960a635fd7a1bcee3a2227b61e340c..966893b3fc01ecf5a80752926a4b6b621e694ca6 100644 (file)
@@ -1,82 +1,82 @@
-#ifndef RAPIDJSON_INTERNAL_STACK_H_\r
-#define RAPIDJSON_INTERNAL_STACK_H_\r
-\r
-namespace rapidjson {\r
-namespace internal {\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Stack\r
-\r
-//! A type-unsafe stack for storing different types of data.\r
-/*! \tparam Allocator Allocator for allocating stack memory.\r
-*/\r
-template <typename Allocator>\r
-class Stack {\r
-public:\r
-       Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {\r
-               RAPIDJSON_ASSERT(stack_capacity_ > 0);\r
-               if (!allocator_)\r
-                       own_allocator_ = allocator_ = new Allocator();\r
-               stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);\r
-               stack_end_ = stack_ + stack_capacity_;\r
-       }\r
-\r
-       ~Stack() {\r
-               Allocator::Free(stack_);\r
-               delete own_allocator_; // Only delete if it is owned by the stack\r
-       }\r
-\r
-       void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }\r
-\r
-       template<typename T>\r
-       T* Push(size_t count = 1) {\r
-                // Expand the stack if needed\r
-               if (stack_top_ + sizeof(T) * count >= stack_end_) {\r
-                       size_t new_capacity = stack_capacity_ * 2;\r
-                       size_t size = GetSize();\r
-                       size_t new_size = GetSize() + sizeof(T) * count;\r
-                       if (new_capacity < new_size)\r
-                               new_capacity = new_size;\r
-                       stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);\r
-                       stack_capacity_ = new_capacity;\r
-                       stack_top_ = stack_ + size;\r
-                       stack_end_ = stack_ + stack_capacity_;\r
-               }\r
-               T* ret = (T*)stack_top_;\r
-               stack_top_ += sizeof(T) * count;\r
-               return ret;\r
-       }\r
-\r
-       template<typename T>\r
-       T* Pop(size_t count) {\r
-               RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));\r
-               stack_top_ -= count * sizeof(T);\r
-               return (T*)stack_top_;\r
-       }\r
-\r
-       template<typename T>\r
-       T* Top() { \r
-               RAPIDJSON_ASSERT(GetSize() >= sizeof(T));\r
-               return (T*)(stack_top_ - sizeof(T));\r
-       }\r
-\r
-       template<typename T>\r
-       T* Bottom() { return (T*)stack_; }\r
-\r
-       Allocator& GetAllocator() { return *allocator_; }\r
-       size_t GetSize() const { return stack_top_ - stack_; }\r
-       size_t GetCapacity() const { return stack_capacity_; }\r
-\r
-private:\r
-       Allocator* allocator_;\r
-       Allocator* own_allocator_;\r
-       char *stack_;\r
-       char *stack_top_;\r
-       char *stack_end_;\r
-       size_t stack_capacity_;\r
-};\r
-\r
-} // namespace internal\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_STACK_H_\r
+#ifndef RAPIDJSON_INTERNAL_STACK_H_
+#define RAPIDJSON_INTERNAL_STACK_H_
+
+namespace rapidjson {
+namespace internal {
+
+///////////////////////////////////////////////////////////////////////////////
+// Stack
+
+//! A type-unsafe stack for storing different types of data.
+/*! \tparam Allocator Allocator for allocating stack memory.
+*/
+template <typename Allocator>
+class Stack {
+public:
+       Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {
+               RAPIDJSON_ASSERT(stack_capacity_ > 0);
+               if (!allocator_)
+                       own_allocator_ = allocator_ = new Allocator();
+               stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);
+               stack_end_ = stack_ + stack_capacity_;
+       }
+
+       ~Stack() {
+               Allocator::Free(stack_);
+               delete own_allocator_; // Only delete if it is owned by the stack
+       }
+
+       void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
+
+       template<typename T>
+       T* Push(size_t count = 1) {
+                // Expand the stack if needed
+               if (stack_top_ + sizeof(T) * count >= stack_end_) {
+                       size_t new_capacity = stack_capacity_ * 2;
+                       size_t size = GetSize();
+                       size_t new_size = GetSize() + sizeof(T) * count;
+                       if (new_capacity < new_size)
+                               new_capacity = new_size;
+                       stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
+                       stack_capacity_ = new_capacity;
+                       stack_top_ = stack_ + size;
+                       stack_end_ = stack_ + stack_capacity_;
+               }
+               T* ret = (T*)stack_top_;
+               stack_top_ += sizeof(T) * count;
+               return ret;
+       }
+
+       template<typename T>
+       T* Pop(size_t count) {
+               RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
+               stack_top_ -= count * sizeof(T);
+               return (T*)stack_top_;
+       }
+
+       template<typename T>
+       T* Top() { 
+               RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
+               return (T*)(stack_top_ - sizeof(T));
+       }
+
+       template<typename T>
+       T* Bottom() { return (T*)stack_; }
+
+       Allocator& GetAllocator() { return *allocator_; }
+       size_t GetSize() const { return stack_top_ - stack_; }
+       size_t GetCapacity() const { return stack_capacity_; }
+
+private:
+       Allocator* allocator_;
+       Allocator* own_allocator_;
+       char *stack_;
+       char *stack_top_;
+       char *stack_end_;
+       size_t stack_capacity_;
+};
+
+} // namespace internal
+} // namespace rapidjson
+
+#endif // RAPIDJSON_STACK_H_
index 47b8ac07571c129a2c65c4d641f84514bbf278d5..bbf444fe6df2e26d5ba438f2e827c3782c1af831 100644 (file)
@@ -1,24 +1,24 @@
-#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_\r
-#define RAPIDJSON_INTERNAL_STRFUNC_H_\r
-\r
-namespace rapidjson {\r
-namespace internal {\r
-\r
-//! Custom strlen() which works on different character types.\r
-/*!    \tparam Ch Character type (e.g. char, wchar_t, short)\r
-       \param s Null-terminated input string.\r
-       \return Number of characters in the string. \r
-       \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.\r
-*/\r
-template <typename Ch>\r
-inline SizeType StrLen(const Ch* s) {\r
-       const Ch* p = s;\r
-       while (*p != '\0')\r
-               ++p;\r
-       return SizeType(p - s);\r
-}\r
-\r
-} // namespace internal\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_INTERNAL_STRFUNC_H_\r
+#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
+#define RAPIDJSON_INTERNAL_STRFUNC_H_
+
+namespace rapidjson {
+namespace internal {
+
+//! Custom strlen() which works on different character types.
+/*!    \tparam Ch Character type (e.g. char, wchar_t, short)
+       \param s Null-terminated input string.
+       \return Number of characters in the string. 
+       \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
+*/
+template <typename Ch>
+inline SizeType StrLen(const Ch* s) {
+       const Ch* p = s;
+       while (*p != '\0')
+               ++p;
+       return SizeType(p - s);
+}
+
+} // namespace internal
+} // namespace rapidjson
+
+#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
index 662b3929da416da4627693b03ae2c263642a56b1..238ff5ff629aa29ca9bd6dde1ea9dddd24ff9c4d 100644 (file)
-#ifndef RAPIDJSON_PRETTYWRITER_H_\r
-#define RAPIDJSON_PRETTYWRITER_H_\r
-\r
-#include "writer.h"\r
-\r
-namespace rapidjson {\r
-\r
-//! Writer with indentation and spacing.\r
-/*!\r
-       \tparam Stream Type of ouptut stream.\r
-       \tparam Encoding Encoding of both source strings and output.\r
-       \tparam Allocator Type of allocator for allocating memory of stack.\r
-*/\r
-template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >\r
-class PrettyWriter : public Writer<Stream, Encoding, Allocator> {\r
-public:\r
-       typedef Writer<Stream, Encoding, Allocator> Base;\r
-       typedef typename Base::Ch Ch;\r
-\r
-       //! Constructor\r
-       /*! \param stream Output stream.\r
-               \param allocator User supplied allocator. If it is null, it will create a private one.\r
-               \param levelDepth Initial capacity of \r
-       */\r
-       PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : \r
-               Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}\r
-\r
-       //! Set custom indentation.\r
-       /*! \param indentChar           Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r').\r
-               \param indentCharCount  Number of indent characters for each indentation level.\r
-               \note The default indentation is 4 spaces.\r
-       */\r
-       PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {\r
-               RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');\r
-               indentChar_ = indentChar;\r
-               indentCharCount_ = indentCharCount;\r
-               return *this;\r
-       }\r
-\r
-       //@name Implementation of Handler.\r
-       //@{\r
-\r
-       PrettyWriter& Null()                            { PrettyPrefix(kNullType);   Base::WriteNull();                 return *this; }\r
-       PrettyWriter& Bool(bool b)                      { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; }\r
-       PrettyWriter& Int(int i)                        { PrettyPrefix(kNumberType); Base::WriteInt(i);                 return *this; }\r
-       PrettyWriter& Uint(unsigned u)          { PrettyPrefix(kNumberType); Base::WriteUint(u);                return *this; }\r
-       PrettyWriter& Int64(int64_t i64)        { PrettyPrefix(kNumberType); Base::WriteInt64(i64);             return *this; }\r
-       PrettyWriter& Uint64(uint64_t u64)      { PrettyPrefix(kNumberType); Base::WriteUint64(u64);    return *this; }\r
-       PrettyWriter& Double(double d)          { PrettyPrefix(kNumberType); Base::WriteDouble(d);              return *this; }\r
-\r
-       PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {\r
-               (void)copy;\r
-               PrettyPrefix(kStringType);\r
-               Base::WriteString(str, length);\r
-               return *this;\r
-       }\r
-\r
-       PrettyWriter& StartObject() {\r
-               PrettyPrefix(kObjectType);\r
-               new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);\r
-               Base::WriteStartObject();\r
-               return *this;\r
-       }\r
-\r
-       PrettyWriter& EndObject(SizeType memberCount = 0) {\r
-               (void)memberCount;\r
-               RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));\r
-               RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);\r
-               bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\r
-\r
-               if (!empty) {\r
-                       Base::stream_.Put('\n');\r
-                       WriteIndent();\r
-               }\r
-               Base::WriteEndObject();\r
-               return *this;\r
-       }\r
-\r
-       PrettyWriter& StartArray() {\r
-               PrettyPrefix(kArrayType);\r
-               new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);\r
-               Base::WriteStartArray();\r
-               return *this;\r
-       }\r
-\r
-       PrettyWriter& EndArray(SizeType memberCount = 0) {\r
-               (void)memberCount;\r
-               RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));\r
-               RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);\r
-               bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\r
-\r
-               if (!empty) {\r
-                       Base::stream_.Put('\n');\r
-                       WriteIndent();\r
-               }\r
-               Base::WriteEndArray();\r
-               return *this;\r
-       }\r
-\r
-       //@}\r
-\r
-       //! Simpler but slower overload.\r
-       PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); }\r
-\r
-protected:\r
-       void PrettyPrefix(Type type) {\r
-               (void)type;\r
-               if (Base::level_stack_.GetSize() != 0) { // this value is not at root\r
-                       typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();\r
-\r
-                       if (level->inArray) {\r
-                               if (level->valueCount > 0) {\r
-                                       Base::stream_.Put(','); // add comma if it is not the first element in array\r
-                                       Base::stream_.Put('\n');\r
-                               }\r
-                               else\r
-                                       Base::stream_.Put('\n');\r
-                               WriteIndent();\r
-                       }\r
-                       else {  // in object\r
-                               if (level->valueCount > 0) {\r
-                                       if (level->valueCount % 2 == 0) {\r
-                                               Base::stream_.Put(',');\r
-                                               Base::stream_.Put('\n');\r
-                                       }\r
-                                       else {\r
-                                               Base::stream_.Put(':');\r
-                                               Base::stream_.Put(' ');\r
-                                       }\r
-                               }\r
-                               else\r
-                                       Base::stream_.Put('\n');\r
-\r
-                               if (level->valueCount % 2 == 0)\r
-                                       WriteIndent();\r
-                       }\r
-                       if (!level->inArray && level->valueCount % 2 == 0)\r
-                               RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\r
-                       level->valueCount++;\r
-               }\r
-               else\r
-                       RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);\r
-       }\r
-\r
-       void WriteIndent()  {\r
-               size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;\r
-               PutN(Base::stream_, indentChar_, count);\r
-       }\r
-\r
-       Ch indentChar_;\r
-       unsigned indentCharCount_;\r
-};\r
-\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_RAPIDJSON_H_\r
+#ifndef RAPIDJSON_PRETTYWRITER_H_
+#define RAPIDJSON_PRETTYWRITER_H_
+
+#include "writer.h"
+
+namespace rapidjson {
+
+//! Writer with indentation and spacing.
+/*!
+       \tparam Stream Type of ouptut stream.
+       \tparam Encoding Encoding of both source strings and output.
+       \tparam Allocator Type of allocator for allocating memory of stack.
+*/
+template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
+class PrettyWriter : public Writer<Stream, Encoding, Allocator> {
+public:
+       typedef Writer<Stream, Encoding, Allocator> Base;
+       typedef typename Base::Ch Ch;
+
+       //! Constructor
+       /*! \param stream Output stream.
+               \param allocator User supplied allocator. If it is null, it will create a private one.
+               \param levelDepth Initial capacity of 
+       */
+       PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
+               Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
+
+       //! Set custom indentation.
+       /*! \param indentChar           Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r').
+               \param indentCharCount  Number of indent characters for each indentation level.
+               \note The default indentation is 4 spaces.
+       */
+       PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
+               RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
+               indentChar_ = indentChar;
+               indentCharCount_ = indentCharCount;
+               return *this;
+       }
+
+       //@name Implementation of Handler.
+       //@{
+
+       PrettyWriter& Null()                            { PrettyPrefix(kNullType);   Base::WriteNull();                 return *this; }
+       PrettyWriter& Bool(bool b)                      { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; }
+       PrettyWriter& Int(int i)                        { PrettyPrefix(kNumberType); Base::WriteInt(i);                 return *this; }
+       PrettyWriter& Uint(unsigned u)          { PrettyPrefix(kNumberType); Base::WriteUint(u);                return *this; }
+       PrettyWriter& Int64(int64_t i64)        { PrettyPrefix(kNumberType); Base::WriteInt64(i64);             return *this; }
+       PrettyWriter& Uint64(uint64_t u64)      { PrettyPrefix(kNumberType); Base::WriteUint64(u64);    return *this; }
+       PrettyWriter& Double(double d)          { PrettyPrefix(kNumberType); Base::WriteDouble(d);              return *this; }
+
+       PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {
+               (void)copy;
+               PrettyPrefix(kStringType);
+               Base::WriteString(str, length);
+               return *this;
+       }
+
+       PrettyWriter& StartObject() {
+               PrettyPrefix(kObjectType);
+               new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
+               Base::WriteStartObject();
+               return *this;
+       }
+
+       PrettyWriter& EndObject(SizeType memberCount = 0) {
+               (void)memberCount;
+               RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
+               RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
+               bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
+
+               if (!empty) {
+                       Base::stream_.Put('\n');
+                       WriteIndent();
+               }
+               Base::WriteEndObject();
+               return *this;
+       }
+
+       PrettyWriter& StartArray() {
+               PrettyPrefix(kArrayType);
+               new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
+               Base::WriteStartArray();
+               return *this;
+       }
+
+       PrettyWriter& EndArray(SizeType memberCount = 0) {
+               (void)memberCount;
+               RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
+               RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
+               bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
+
+               if (!empty) {
+                       Base::stream_.Put('\n');
+                       WriteIndent();
+               }
+               Base::WriteEndArray();
+               return *this;
+       }
+
+       //@}
+
+       //! Simpler but slower overload.
+       PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); }
+
+protected:
+       void PrettyPrefix(Type type) {
+               (void)type;
+               if (Base::level_stack_.GetSize() != 0) { // this value is not at root
+                       typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
+
+                       if (level->inArray) {
+                               if (level->valueCount > 0) {
+                                       Base::stream_.Put(','); // add comma if it is not the first element in array
+                                       Base::stream_.Put('\n');
+                               }
+                               else
+                                       Base::stream_.Put('\n');
+                               WriteIndent();
+                       }
+                       else {  // in object
+                               if (level->valueCount > 0) {
+                                       if (level->valueCount % 2 == 0) {
+                                               Base::stream_.Put(',');
+                                               Base::stream_.Put('\n');
+                                       }
+                                       else {
+                                               Base::stream_.Put(':');
+                                               Base::stream_.Put(' ');
+                                       }
+                               }
+                               else
+                                       Base::stream_.Put('\n');
+
+                               if (level->valueCount % 2 == 0)
+                                       WriteIndent();
+                       }
+                       if (!level->inArray && level->valueCount % 2 == 0)
+                               RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name
+                       level->valueCount++;
+               }
+               else
+                       RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
+       }
+
+       void WriteIndent()  {
+               size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
+               PutN(Base::stream_, indentChar_, count);
+       }
+
+       Ch indentChar_;
+       unsigned indentCharCount_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_RAPIDJSON_H_
index 357eab453d8c16979ac065d58bc6e8d4e252bb87..7acb2aa4fd01579f015346095889ac7c5341f821 100644 (file)
-#ifndef RAPIDJSON_RAPIDJSON_H_\r
-#define RAPIDJSON_RAPIDJSON_H_\r
-\r
-// Copyright (c) 2011-2012 Milo Yip (miloyip@gmail.com)\r
-// Version 0.11\r
-\r
-#include <cstdlib>     // malloc(), realloc(), free()\r
-#include <cstring>     // memcpy()\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// RAPIDJSON_NO_INT64DEFINE\r
-\r
-// Here defines int64_t and uint64_t types in global namespace.\r
-// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.\r
-#ifndef RAPIDJSON_NO_INT64DEFINE\r
-#ifdef _MSC_VER\r
-typedef __int64 int64_t;\r
-typedef unsigned __int64 uint64_t;\r
-#else\r
-#include <inttypes.h>\r
-#endif\r
-#endif // RAPIDJSON_NO_INT64TYPEDEF\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// RAPIDJSON_ENDIAN\r
-#define RAPIDJSON_LITTLEENDIAN 0       //!< Little endian machine\r
-#define RAPIDJSON_BIGENDIAN            1       //!< Big endian machine\r
-\r
-//! Endianness of the machine.\r
-/*!    GCC provided macro for detecting endianness of the target machine. But other\r
-       compilers may not have this. User can define RAPIDJSON_ENDIAN to either\r
-       RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.\r
-*/\r
-#ifndef RAPIDJSON_ENDIAN\r
-#ifdef __BYTE_ORDER__\r
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\r
-#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\r
-#else\r
-#define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\r
-#endif // __BYTE_ORDER__\r
-#else\r
-#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN        // Assumes little endian otherwise.\r
-#endif\r
-#endif // RAPIDJSON_ENDIAN\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD\r
-\r
-// Enable SSE2 optimization.\r
-//#define RAPIDJSON_SSE2\r
-\r
-// Enable SSE4.2 optimization.\r
-//#define RAPIDJSON_SSE42\r
-\r
-#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\r
-#define RAPIDJSON_SIMD\r
-#endif\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// RAPIDJSON_NO_SIZETYPEDEFINE\r
-\r
-#ifndef RAPIDJSON_NO_SIZETYPEDEFINE\r
-namespace rapidjson {\r
-//! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.\r
-/*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.\r
-*/\r
-typedef unsigned SizeType;\r
-} // namespace rapidjson\r
-#endif\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// RAPIDJSON_ASSERT\r
-\r
-//! Assertion.\r
-/*! By default, rapidjson uses C assert() for assertion.\r
-       User can override it by defining RAPIDJSON_ASSERT(x) macro.\r
-*/\r
-#ifndef RAPIDJSON_ASSERT\r
-#include <cassert>\r
-#define RAPIDJSON_ASSERT(x) assert(x)\r
-#endif // RAPIDJSON_ASSERT\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Helpers\r
-\r
-#define RAPIDJSON_MULTILINEMACRO_BEGIN do {  \r
-#define RAPIDJSON_MULTILINEMACRO_END \\r
-} while((void)0, 0)\r
-\r
-namespace rapidjson {\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Allocator\r
-\r
-/*! \class rapidjson::Allocator\r
-       \brief Concept for allocating, resizing and freeing memory block.\r
-       \r
-       Note that Malloc() and Realloc() are non-static but Free() is static.\r
-       \r
-       So if an allocator need to support Free(), it needs to put its pointer in \r
-       the header of memory block.\r
-\r
-\code\r
-concept Allocator {\r
-       static const bool kNeedFree;    //!< Whether this allocator needs to call Free().\r
-\r
-       // Allocate a memory block.\r
-       // \param size of the memory block in bytes.\r
-       // \returns pointer to the memory block.\r
-       void* Malloc(size_t size);\r
-\r
-       // Resize a memory block.\r
-       // \param originalPtr The pointer to current memory block. Null pointer is permitted.\r
-       // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)\r
-       // \param newSize the new size in bytes.\r
-       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);\r
-\r
-       // Free a memory block.\r
-       // \param pointer to the memory block. Null pointer is permitted.\r
-       static void Free(void *ptr);\r
-};\r
-\endcode\r
-*/\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// CrtAllocator\r
-\r
-//! C-runtime library allocator.\r
-/*! This class is just wrapper for standard C library memory routines.\r
-       \implements Allocator\r
-*/\r
-class CrtAllocator {\r
-public:\r
-       static const bool kNeedFree = true;\r
-       void* Malloc(size_t size) { return malloc(size); }\r
-       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }\r
-       static void Free(void *ptr) { free(ptr); }\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// MemoryPoolAllocator\r
-\r
-//! Default memory allocator used by the parser and DOM.\r
-/*! This allocator allocate memory blocks from pre-allocated memory chunks. \r
-\r
-    It does not free memory blocks. And Realloc() only allocate new memory.\r
-\r
-    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.\r
-\r
-    User may also supply a buffer as the first chunk.\r
-\r
-    If the user-buffer is full then additional chunks are allocated by BaseAllocator.\r
-\r
-    The user-buffer is not deallocated by this allocator.\r
-\r
-    \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.\r
-       \implements Allocator\r
-*/\r
-template <typename BaseAllocator = CrtAllocator>\r
-class MemoryPoolAllocator {\r
-public:\r
-       static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)\r
-\r
-       //! Constructor with chunkSize.\r
-       /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\r
-               \param baseAllocator The allocator for allocating memory chunks.\r
-       */\r
-       MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : \r
-               chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\r
-       {\r
-               if (!baseAllocator_)\r
-                       ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();\r
-               AddChunk(chunk_capacity_);\r
-       }\r
-\r
-       //! Constructor with user-supplied buffer.\r
-       /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.\r
-\r
-               The user buffer will not be deallocated when this allocator is destructed.\r
-\r
-               \param buffer User supplied buffer.\r
-               \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).\r
-               \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\r
-               \param baseAllocator The allocator for allocating memory chunks.\r
-       */\r
-       MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :\r
-               chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\r
-       {\r
-               RAPIDJSON_ASSERT(buffer != 0);\r
-               RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));\r
-               chunkHead_ = (ChunkHeader*)buffer;\r
-               chunkHead_->capacity = size - sizeof(ChunkHeader);\r
-               chunkHead_->size = 0;\r
-               chunkHead_->next = 0;\r
-       }\r
-\r
-       //! Destructor.\r
-       /*! This deallocates all memory chunks, excluding the user-supplied buffer.\r
-       */\r
-       ~MemoryPoolAllocator() {\r
-               Clear();\r
-               delete ownBaseAllocator_;\r
-       }\r
-\r
-       //! Deallocates all memory chunks, excluding the user-supplied buffer.\r
-       void Clear() {\r
-               while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) {\r
-                       ChunkHeader* next = chunkHead_->next;\r
-                       baseAllocator_->Free(chunkHead_);\r
-                       chunkHead_ = next;\r
-               }\r
-       }\r
-\r
-       //! Computes the total capacity of allocated memory chunks.\r
-       /*! \return total capacity in bytes.\r
-       */\r
-       size_t Capacity() {\r
-               size_t capacity = 0;\r
-               for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\r
-                       capacity += c->capacity;\r
-               return capacity;\r
-       }\r
-\r
-       //! Computes the memory blocks allocated.\r
-       /*! \return total used bytes.\r
-       */\r
-       size_t Size() {\r
-               size_t size = 0;\r
-               for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\r
-                       size += c->size;\r
-               return size;\r
-       }\r
-\r
-       //! Allocates a memory block. (concept Allocator)\r
-       void* Malloc(size_t size) {\r
-               size = (size + 3) & ~3; // Force aligning size to 4\r
-\r
-               if (chunkHead_->size + size > chunkHead_->capacity)\r
-                       AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);\r
-\r
-               char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;\r
-               RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4\r
-               chunkHead_->size += size;\r
-\r
-               return buffer;\r
-       }\r
-\r
-       //! Resizes a memory block (concept Allocator)\r
-       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {\r
-               if (originalPtr == 0)\r
-                       return Malloc(newSize);\r
-\r
-               // Do not shrink if new size is smaller than original\r
-               if (originalSize >= newSize)\r
-                       return originalPtr;\r
-\r
-               // Simply expand it if it is the last allocation and there is sufficient space\r
-               if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {\r
-                       size_t increment = newSize - originalSize;\r
-                       increment = (increment + 3) & ~3;       // Force aligning size to 4\r
-                       if (chunkHead_->size + increment <= chunkHead_->capacity) {\r
-                               chunkHead_->size += increment;\r
-                               RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0);    // returned buffer is aligned to 4\r
-                               return originalPtr;\r
-                       }\r
-               }\r
-\r
-               // Realloc process: allocate and copy memory, do not free original buffer.\r
-               void* newBuffer = Malloc(newSize);\r
-               RAPIDJSON_ASSERT(newBuffer != 0);       // Do not handle out-of-memory explicitly.\r
-               return memcpy(newBuffer, originalPtr, originalSize);\r
-       }\r
-\r
-       //! Frees a memory block (concept Allocator)\r
-       static void Free(void *) {} // Do nothing\r
-\r
-private:\r
-       //! Creates a new chunk.\r
-       /*! \param capacity Capacity of the chunk in bytes.\r
-       */\r
-       void AddChunk(size_t capacity) {\r
-               ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity);\r
-               chunk->capacity = capacity;\r
-               chunk->size = 0;\r
-               chunk->next = chunkHead_;\r
-               chunkHead_ =  chunk;\r
-       }\r
-\r
-       static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.\r
-\r
-       //! Chunk header for perpending to each chunk.\r
-       /*! Chunks are stored as a singly linked list.\r
-       */\r
-       struct ChunkHeader {\r
-               size_t capacity;        //!< Capacity of the chunk in bytes (excluding the header itself).\r
-               size_t size;            //!< Current size of allocated memory in bytes.\r
-               ChunkHeader *next;      //!< Next chunk in the linked list.\r
-       };\r
-\r
-       ChunkHeader *chunkHead_;        //!< Head of the chunk linked-list. Only the head chunk serves allocation.\r
-       size_t chunk_capacity_;         //!< The minimum capacity of chunk when they are allocated.\r
-       char *userBuffer_;                      //!< User supplied buffer.\r
-       BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.\r
-       BaseAllocator* ownBaseAllocator_;       //!< base allocator created by this object.\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Encoding\r
-\r
-/*! \class rapidjson::Encoding\r
-       \brief Concept for encoding of Unicode characters.\r
-\r
-\code\r
-concept Encoding {\r
-       typename Ch;    //! Type of character.\r
-\r
-       //! \brief Encode a Unicode codepoint to a buffer.\r
-       //! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character.\r
-       //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.\r
-       //! \returns the pointer to the next character after the encoded data.\r
-       static Ch* Encode(Ch *buffer, unsigned codepoint);\r
-};\r
-\endcode\r
-*/\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// UTF8\r
-\r
-//! UTF-8 encoding.\r
-/*! http://en.wikipedia.org/wiki/UTF-8\r
-       \tparam CharType Type for storing 8-bit UTF-8 data. Default is char.\r
-       \implements Encoding\r
-*/\r
-template<typename CharType = char>\r
-struct UTF8 {\r
-       typedef CharType Ch;\r
-\r
-       static Ch* Encode(Ch *buffer, unsigned codepoint) {\r
-               if (codepoint <= 0x7F) \r
-                       *buffer++ = codepoint & 0xFF;\r
-               else if (codepoint <= 0x7FF) {\r
-                       *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);\r
-                       *buffer++ = 0x80 | ((codepoint & 0x3F));\r
-               }\r
-               else if (codepoint <= 0xFFFF) {\r
-                       *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);\r
-                       *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);\r
-                       *buffer++ = 0x80 | (codepoint & 0x3F);\r
-               }\r
-               else {\r
-                       RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\r
-                       *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);\r
-                       *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);\r
-                       *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);\r
-                       *buffer++ = 0x80 | (codepoint & 0x3F);\r
-               }\r
-               return buffer;\r
-       }\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// UTF16\r
-\r
-//! UTF-16 encoding.\r
-/*! http://en.wikipedia.org/wiki/UTF-16\r
-       \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.\r
-       \implements Encoding\r
-*/\r
-template<typename CharType = wchar_t>\r
-struct UTF16 {\r
-       typedef CharType Ch;\r
-\r
-       static Ch* Encode(Ch* buffer, unsigned codepoint) {\r
-               if (codepoint <= 0xFFFF) {\r
-                       RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair \r
-                       *buffer++ = static_cast<Ch>(codepoint);\r
-               }\r
-               else {\r
-                       RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\r
-                       unsigned v = codepoint - 0x10000;\r
-                       *buffer++ = static_cast<Ch>((v >> 10) + 0xD800);\r
-                       *buffer++ = (v & 0x3FF) + 0xDC00;\r
-               }\r
-               return buffer;\r
-       }\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// UTF32\r
-\r
-//! UTF-32 encoding. \r
-/*! http://en.wikipedia.org/wiki/UTF-32\r
-       \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.\r
-       \implements Encoding\r
-*/\r
-template<typename CharType = unsigned>\r
-struct UTF32 {\r
-       typedef CharType Ch;\r
-\r
-       static Ch *Encode(Ch* buffer, unsigned codepoint) {\r
-               RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\r
-               *buffer++ = codepoint;\r
-               return buffer;\r
-       }\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-//  Stream\r
-\r
-/*! \class rapidjson::Stream\r
-       \brief Concept for reading and writing characters.\r
-\r
-       For read-only stream, no need to implement PutBegin(), Put() and PutEnd().\r
-\r
-       For write-only stream, only need to implement Put().\r
-\r
-\code\r
-concept Stream {\r
-       typename Ch;    //!< Character type of the stream.\r
-\r
-       //! Read the current character from stream without moving the read cursor.\r
-       Ch Peek() const;\r
-\r
-       //! Read the current character from stream and moving the read cursor to next character.\r
-       Ch Take();\r
-\r
-       //! Get the current read cursor.\r
-       //! \return Number of characters read from start.\r
-       size_t Tell();\r
-\r
-       //! Begin writing operation at the current read pointer.\r
-       //! \return The begin writer pointer.\r
-       Ch* PutBegin();\r
-\r
-       //! Write a character.\r
-       void Put(Ch c);\r
-\r
-       //! End the writing operation.\r
-       //! \param begin The begin write pointer returned by PutBegin().\r
-       //! \return Number of characters written.\r
-       size_t PutEnd(Ch* begin);\r
-}\r
-\endcode\r
-*/\r
-\r
-//! Put N copies of a character to a stream.\r
-template<typename Stream, typename Ch>\r
-inline void PutN(Stream& stream, Ch c, size_t n) {\r
-       for (size_t i = 0; i < n; i++)\r
-               stream.Put(c);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// StringStream\r
-\r
-//! Read-only string stream.\r
-/*! \implements Stream\r
-*/\r
-template <typename Encoding>\r
-struct GenericStringStream {\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       GenericStringStream(const Ch *src) : src_(src), head_(src) {}\r
-\r
-       Ch Peek() const { return *src_; }\r
-       Ch Take() { return *src_++; }\r
-       size_t Tell() const { return src_ - head_; }\r
-\r
-       Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\r
-       void Put(Ch) { RAPIDJSON_ASSERT(false); }\r
-       size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\r
-\r
-       const Ch* src_;         //!< Current read position.\r
-       const Ch* head_;        //!< Original head of the string.\r
-};\r
-\r
-typedef GenericStringStream<UTF8<> > StringStream;\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// InsituStringStream\r
-\r
-//! A read-write string stream.\r
-/*! This string stream is particularly designed for in-situ parsing.\r
-       \implements Stream\r
-*/\r
-template <typename Encoding>\r
-struct GenericInsituStringStream {\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}\r
-\r
-       // Read\r
-       Ch Peek() { return *src_; }\r
-       Ch Take() { return *src_++; }\r
-       size_t Tell() { return src_ - head_; }\r
-\r
-       // Write\r
-       Ch* PutBegin() { return dst_ = src_; }\r
-       void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }\r
-       size_t PutEnd(Ch* begin) { return dst_ - begin; }\r
-\r
-       Ch* src_;\r
-       Ch* dst_;\r
-       Ch* head_;\r
-};\r
-\r
-typedef GenericInsituStringStream<UTF8<> > InsituStringStream;\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Type\r
-\r
-//! Type of JSON value\r
-enum Type {\r
-       kNullType = 0,          //!< null\r
-       kFalseType = 1,         //!< false\r
-       kTrueType = 2,          //!< true\r
-       kObjectType = 3,        //!< object\r
-       kArrayType = 4,         //!< array \r
-       kStringType = 5,        //!< string\r
-       kNumberType = 6,        //!< number\r
-};\r
-\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_RAPIDJSON_H_\r
+#ifndef RAPIDJSON_RAPIDJSON_H_
+#define RAPIDJSON_RAPIDJSON_H_
+
+// Copyright (c) 2011-2012 Milo Yip (miloyip@gmail.com)
+// Version 0.11
+
+#include <cstdlib>     // malloc(), realloc(), free()
+#include <cstring>     // memcpy()
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_NO_INT64DEFINE
+
+// Here defines int64_t and uint64_t types in global namespace.
+// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
+#ifndef RAPIDJSON_NO_INT64DEFINE
+#ifdef _MSC_VER
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <inttypes.h>
+#endif
+#endif // RAPIDJSON_NO_INT64TYPEDEF
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_ENDIAN
+#define RAPIDJSON_LITTLEENDIAN 0       //!< Little endian machine
+#define RAPIDJSON_BIGENDIAN            1       //!< Big endian machine
+
+//! Endianness of the machine.
+/*!    GCC provided macro for detecting endianness of the target machine. But other
+       compilers may not have this. User can define RAPIDJSON_ENDIAN to either
+       RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.
+*/
+#ifndef RAPIDJSON_ENDIAN
+#ifdef __BYTE_ORDER__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
+#else
+#define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
+#endif // __BYTE_ORDER__
+#else
+#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN        // Assumes little endian otherwise.
+#endif
+#endif // RAPIDJSON_ENDIAN
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
+
+// Enable SSE2 optimization.
+//#define RAPIDJSON_SSE2
+
+// Enable SSE4.2 optimization.
+//#define RAPIDJSON_SSE42
+
+#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
+#define RAPIDJSON_SIMD
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_NO_SIZETYPEDEFINE
+
+#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
+namespace rapidjson {
+//! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
+/*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
+*/
+typedef unsigned SizeType;
+} // namespace rapidjson
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_ASSERT
+
+//! Assertion.
+/*! By default, rapidjson uses C assert() for assertion.
+       User can override it by defining RAPIDJSON_ASSERT(x) macro.
+*/
+#ifndef RAPIDJSON_ASSERT
+#include <cassert>
+#define RAPIDJSON_ASSERT(x) assert(x)
+#endif // RAPIDJSON_ASSERT
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+
+#define RAPIDJSON_MULTILINEMACRO_BEGIN do {  
+#define RAPIDJSON_MULTILINEMACRO_END \
+} while((void)0, 0)
+
+namespace rapidjson {
+
+///////////////////////////////////////////////////////////////////////////////
+// Allocator
+
+/*! \class rapidjson::Allocator
+       \brief Concept for allocating, resizing and freeing memory block.
+       
+       Note that Malloc() and Realloc() are non-static but Free() is static.
+       
+       So if an allocator need to support Free(), it needs to put its pointer in 
+       the header of memory block.
+
+\code
+concept Allocator {
+       static const bool kNeedFree;    //!< Whether this allocator needs to call Free().
+
+       // Allocate a memory block.
+       // \param size of the memory block in bytes.
+       // \returns pointer to the memory block.
+       void* Malloc(size_t size);
+
+       // Resize a memory block.
+       // \param originalPtr The pointer to current memory block. Null pointer is permitted.
+       // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
+       // \param newSize the new size in bytes.
+       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
+
+       // Free a memory block.
+       // \param pointer to the memory block. Null pointer is permitted.
+       static void Free(void *ptr);
+};
+\endcode
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// CrtAllocator
+
+//! C-runtime library allocator.
+/*! This class is just wrapper for standard C library memory routines.
+       \implements Allocator
+*/
+class CrtAllocator {
+public:
+       static const bool kNeedFree = true;
+       void* Malloc(size_t size) { return malloc(size); }
+       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }
+       static void Free(void *ptr) { free(ptr); }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// MemoryPoolAllocator
+
+//! Default memory allocator used by the parser and DOM.
+/*! This allocator allocate memory blocks from pre-allocated memory chunks. 
+
+    It does not free memory blocks. And Realloc() only allocate new memory.
+
+    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
+
+    User may also supply a buffer as the first chunk.
+
+    If the user-buffer is full then additional chunks are allocated by BaseAllocator.
+
+    The user-buffer is not deallocated by this allocator.
+
+    \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
+       \implements Allocator
+*/
+template <typename BaseAllocator = CrtAllocator>
+class MemoryPoolAllocator {
+public:
+       static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
+
+       //! Constructor with chunkSize.
+       /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+               \param baseAllocator The allocator for allocating memory chunks.
+       */
+       MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 
+               chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+       {
+               if (!baseAllocator_)
+                       ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
+               AddChunk(chunk_capacity_);
+       }
+
+       //! Constructor with user-supplied buffer.
+       /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
+
+               The user buffer will not be deallocated when this allocator is destructed.
+
+               \param buffer User supplied buffer.
+               \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
+               \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+               \param baseAllocator The allocator for allocating memory chunks.
+       */
+       MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+               chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+       {
+               RAPIDJSON_ASSERT(buffer != 0);
+               RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
+               chunkHead_ = (ChunkHeader*)buffer;
+               chunkHead_->capacity = size - sizeof(ChunkHeader);
+               chunkHead_->size = 0;
+               chunkHead_->next = 0;
+       }
+
+       //! Destructor.
+       /*! This deallocates all memory chunks, excluding the user-supplied buffer.
+       */
+       ~MemoryPoolAllocator() {
+               Clear();
+               delete ownBaseAllocator_;
+       }
+
+       //! Deallocates all memory chunks, excluding the user-supplied buffer.
+       void Clear() {
+               while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) {
+                       ChunkHeader* next = chunkHead_->next;
+                       baseAllocator_->Free(chunkHead_);
+                       chunkHead_ = next;
+               }
+       }
+
+       //! Computes the total capacity of allocated memory chunks.
+       /*! \return total capacity in bytes.
+       */
+       size_t Capacity() {
+               size_t capacity = 0;
+               for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+                       capacity += c->capacity;
+               return capacity;
+       }
+
+       //! Computes the memory blocks allocated.
+       /*! \return total used bytes.
+       */
+       size_t Size() {
+               size_t size = 0;
+               for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+                       size += c->size;
+               return size;
+       }
+
+       //! Allocates a memory block. (concept Allocator)
+       void* Malloc(size_t size) {
+               size = (size + 3) & ~3; // Force aligning size to 4
+
+               if (chunkHead_->size + size > chunkHead_->capacity)
+                       AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
+
+               char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;
+               RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4
+               chunkHead_->size += size;
+
+               return buffer;
+       }
+
+       //! Resizes a memory block (concept Allocator)
+       void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+               if (originalPtr == 0)
+                       return Malloc(newSize);
+
+               // Do not shrink if new size is smaller than original
+               if (originalSize >= newSize)
+                       return originalPtr;
+
+               // Simply expand it if it is the last allocation and there is sufficient space
+               if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
+                       size_t increment = newSize - originalSize;
+                       increment = (increment + 3) & ~3;       // Force aligning size to 4
+                       if (chunkHead_->size + increment <= chunkHead_->capacity) {
+                               chunkHead_->size += increment;
+                               RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0);    // returned buffer is aligned to 4
+                               return originalPtr;
+                       }
+               }
+
+               // Realloc process: allocate and copy memory, do not free original buffer.
+               void* newBuffer = Malloc(newSize);
+               RAPIDJSON_ASSERT(newBuffer != 0);       // Do not handle out-of-memory explicitly.
+               return memcpy(newBuffer, originalPtr, originalSize);
+       }
+
+       //! Frees a memory block (concept Allocator)
+       static void Free(void *) {} // Do nothing
+
+private:
+       //! Creates a new chunk.
+       /*! \param capacity Capacity of the chunk in bytes.
+       */
+       void AddChunk(size_t capacity) {
+               ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity);
+               chunk->capacity = capacity;
+               chunk->size = 0;
+               chunk->next = chunkHead_;
+               chunkHead_ =  chunk;
+       }
+
+       static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
+
+       //! Chunk header for perpending to each chunk.
+       /*! Chunks are stored as a singly linked list.
+       */
+       struct ChunkHeader {
+               size_t capacity;        //!< Capacity of the chunk in bytes (excluding the header itself).
+               size_t size;            //!< Current size of allocated memory in bytes.
+               ChunkHeader *next;      //!< Next chunk in the linked list.
+       };
+
+       ChunkHeader *chunkHead_;        //!< Head of the chunk linked-list. Only the head chunk serves allocation.
+       size_t chunk_capacity_;         //!< The minimum capacity of chunk when they are allocated.
+       char *userBuffer_;                      //!< User supplied buffer.
+       BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.
+       BaseAllocator* ownBaseAllocator_;       //!< base allocator created by this object.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Encoding
+
+/*! \class rapidjson::Encoding
+       \brief Concept for encoding of Unicode characters.
+
+\code
+concept Encoding {
+       typename Ch;    //! Type of character.
+
+       //! \brief Encode a Unicode codepoint to a buffer.
+       //! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character.
+       //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
+       //! \returns the pointer to the next character after the encoded data.
+       static Ch* Encode(Ch *buffer, unsigned codepoint);
+};
+\endcode
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// UTF8
+
+//! UTF-8 encoding.
+/*! http://en.wikipedia.org/wiki/UTF-8
+       \tparam CharType Type for storing 8-bit UTF-8 data. Default is char.
+       \implements Encoding
+*/
+template<typename CharType = char>
+struct UTF8 {
+       typedef CharType Ch;
+
+       static Ch* Encode(Ch *buffer, unsigned codepoint) {
+               if (codepoint <= 0x7F) 
+                       *buffer++ = codepoint & 0xFF;
+               else if (codepoint <= 0x7FF) {
+                       *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
+                       *buffer++ = 0x80 | ((codepoint & 0x3F));
+               }
+               else if (codepoint <= 0xFFFF) {
+                       *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
+                       *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
+                       *buffer++ = 0x80 | (codepoint & 0x3F);
+               }
+               else {
+                       RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+                       *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
+                       *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
+                       *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
+                       *buffer++ = 0x80 | (codepoint & 0x3F);
+               }
+               return buffer;
+       }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// UTF16
+
+//! UTF-16 encoding.
+/*! http://en.wikipedia.org/wiki/UTF-16
+       \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
+       \implements Encoding
+*/
+template<typename CharType = wchar_t>
+struct UTF16 {
+       typedef CharType Ch;
+
+       static Ch* Encode(Ch* buffer, unsigned codepoint) {
+               if (codepoint <= 0xFFFF) {
+                       RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair 
+                       *buffer++ = static_cast<Ch>(codepoint);
+               }
+               else {
+                       RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+                       unsigned v = codepoint - 0x10000;
+                       *buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
+                       *buffer++ = (v & 0x3FF) + 0xDC00;
+               }
+               return buffer;
+       }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// UTF32
+
+//! UTF-32 encoding. 
+/*! http://en.wikipedia.org/wiki/UTF-32
+       \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
+       \implements Encoding
+*/
+template<typename CharType = unsigned>
+struct UTF32 {
+       typedef CharType Ch;
+
+       static Ch *Encode(Ch* buffer, unsigned codepoint) {
+               RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+               *buffer++ = codepoint;
+               return buffer;
+       }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  Stream
+
+/*! \class rapidjson::Stream
+       \brief Concept for reading and writing characters.
+
+       For read-only stream, no need to implement PutBegin(), Put() and PutEnd().
+
+       For write-only stream, only need to implement Put().
+
+\code
+concept Stream {
+       typename Ch;    //!< Character type of the stream.
+
+       //! Read the current character from stream without moving the read cursor.
+       Ch Peek() const;
+
+       //! Read the current character from stream and moving the read cursor to next character.
+       Ch Take();
+
+       //! Get the current read cursor.
+       //! \return Number of characters read from start.
+       size_t Tell();
+
+       //! Begin writing operation at the current read pointer.
+       //! \return The begin writer pointer.
+       Ch* PutBegin();
+
+       //! Write a character.
+       void Put(Ch c);
+
+       //! End the writing operation.
+       //! \param begin The begin write pointer returned by PutBegin().
+       //! \return Number of characters written.
+       size_t PutEnd(Ch* begin);
+}
+\endcode
+*/
+
+//! Put N copies of a character to a stream.
+template<typename Stream, typename Ch>
+inline void PutN(Stream& stream, Ch c, size_t n) {
+       for (size_t i = 0; i < n; i++)
+               stream.Put(c);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// StringStream
+
+//! Read-only string stream.
+/*! \implements Stream
+*/
+template <typename Encoding>
+struct GenericStringStream {
+       typedef typename Encoding::Ch Ch;
+
+       GenericStringStream(const Ch *src) : src_(src), head_(src) {}
+
+       Ch Peek() const { return *src_; }
+       Ch Take() { return *src_++; }
+       size_t Tell() const { return src_ - head_; }
+
+       Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+       void Put(Ch) { RAPIDJSON_ASSERT(false); }
+       size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+       const Ch* src_;         //!< Current read position.
+       const Ch* head_;        //!< Original head of the string.
+};
+
+typedef GenericStringStream<UTF8<> > StringStream;
+
+///////////////////////////////////////////////////////////////////////////////
+// InsituStringStream
+
+//! A read-write string stream.
+/*! This string stream is particularly designed for in-situ parsing.
+       \implements Stream
+*/
+template <typename Encoding>
+struct GenericInsituStringStream {
+       typedef typename Encoding::Ch Ch;
+
+       GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
+
+       // Read
+       Ch Peek() { return *src_; }
+       Ch Take() { return *src_++; }
+       size_t Tell() { return src_ - head_; }
+
+       // Write
+       Ch* PutBegin() { return dst_ = src_; }
+       void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
+       size_t PutEnd(Ch* begin) { return dst_ - begin; }
+
+       Ch* src_;
+       Ch* dst_;
+       Ch* head_;
+};
+
+typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
+
+///////////////////////////////////////////////////////////////////////////////
+// Type
+
+//! Type of JSON value
+enum Type {
+       kNullType = 0,          //!< null
+       kFalseType = 1,         //!< false
+       kTrueType = 2,          //!< true
+       kObjectType = 3,        //!< object
+       kArrayType = 4,         //!< array 
+       kStringType = 5,        //!< string
+       kNumberType = 6,        //!< number
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_RAPIDJSON_H_
index cb3e826a54deb23a381189041728ee9a1557c786..96bbc6eb5995f35c674811f198315180623f4315 100644 (file)
-#ifndef RAPIDJSON_READER_H_\r
-#define RAPIDJSON_READER_H_\r
-\r
-// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)\r
-// Version 0.1\r
-\r
-#include "rapidjson.h"\r
-#include "internal/pow10.h"\r
-#include "internal/stack.h"\r
-#include <csetjmp>\r
-\r
-#ifdef RAPIDJSON_SSE42\r
-#include <nmmintrin.h>\r
-#elif defined(RAPIDJSON_SSE2)\r
-#include <emmintrin.h>\r
-#endif\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(push)\r
-#pragma warning(disable : 4127) // conditional expression is constant\r
-#endif\r
-\r
-#ifndef RAPIDJSON_PARSE_ERROR\r
-#define RAPIDJSON_PARSE_ERROR(msg, offset) \\r
-       RAPIDJSON_MULTILINEMACRO_BEGIN \\r
-       parseError_ = msg; \\r
-       errorOffset_ = offset; \\r
-       longjmp(jmpbuf_, 1); \\r
-       RAPIDJSON_MULTILINEMACRO_END\r
-#endif\r
-\r
-namespace rapidjson {\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// ParseFlag\r
-\r
-//! Combination of parseFlags\r
-enum ParseFlag {\r
-       kParseDefaultFlags = 0,                 //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.\r
-       kParseInsituFlag = 1                    //!< In-situ(destructive) parsing.\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// Handler\r
-\r
-/*!    \class rapidjson::Handler\r
-       \brief Concept for receiving events from GenericReader upon parsing.\r
-\code\r
-concept Handler {\r
-       typename Ch;\r
-\r
-       void Null();\r
-       void Bool(bool b);\r
-       void Int(int i);\r
-       void Uint(unsigned i);\r
-       void Int64(int64_t i);\r
-       void Uint64(uint64_t i);\r
-       void Double(double d);\r
-       void String(const Ch* str, SizeType length, bool copy);\r
-       void StartObject();\r
-       void EndObject(SizeType memberCount);\r
-       void StartArray();\r
-       void EndArray(SizeType elementCount);\r
-};\r
-\endcode\r
-*/\r
-///////////////////////////////////////////////////////////////////////////////\r
-// BaseReaderHandler\r
-\r
-//! Default implementation of Handler.\r
-/*! This can be used as base class of any reader handler.\r
-       \implements Handler\r
-*/\r
-template<typename Encoding = UTF8<> >\r
-struct BaseReaderHandler {\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       void Default() {}\r
-       void Null() { Default(); }\r
-       void Bool(bool) { Default(); }\r
-       void Int(int) { Default(); }\r
-       void Uint(unsigned) { Default(); }\r
-       void Int64(int64_t) { Default(); }\r
-       void Uint64(uint64_t) { Default(); }\r
-       void Double(double) { Default(); }\r
-       void String(const Ch*, SizeType, bool) { Default(); }\r
-       void StartObject() { Default(); }\r
-       void EndObject(SizeType) { Default(); }\r
-       void StartArray() { Default(); }\r
-       void EndArray(SizeType) { Default(); }\r
-};\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// SkipWhitespace\r
-\r
-//! Skip the JSON white spaces in a stream.\r
-/*! \param stream A input stream for skipping white spaces.\r
-       \note This function has SSE2/SSE4.2 specialization.\r
-*/\r
-template<typename Stream>\r
-void SkipWhitespace(Stream& stream) {\r
-       Stream s = stream;      // Use a local copy for optimization\r
-       while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')\r
-               s.Take();\r
-       stream = s;\r
-}\r
-\r
-#ifdef RAPIDJSON_SSE42\r
-//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.\r
-inline const char *SkipWhitespace_SIMD(const char* p) {\r
-       static const char whitespace[16] = " \n\r\t";\r
-       __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);\r
-\r
-       for (;;) {\r
-               __m128i s = _mm_loadu_si128((const __m128i *)p);\r
-               unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));\r
-               if (r == 0)     // all 16 characters are whitespace\r
-                       p += 16;\r
-               else {          // some of characters may be non-whitespace\r
-#ifdef _MSC_VER                // Find the index of first non-whitespace\r
-                       unsigned long offset;\r
-                       if (_BitScanForward(&offset, r))\r
-                               return p + offset;\r
-#else\r
-                       if (r != 0)\r
-                               return p + __builtin_ffs(r) - 1;\r
-#endif\r
-               }\r
-       }\r
-}\r
-\r
-#elif defined(RAPIDJSON_SSE2)\r
-\r
-//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.\r
-inline const char *SkipWhitespace_SIMD(const char* p) {\r
-       static const char whitespaces[4][17] = {\r
-               "                ",\r
-               "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",\r
-               "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",\r
-               "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};\r
-\r
-       __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);\r
-       __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);\r
-       __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);\r
-       __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);\r
-\r
-       for (;;) {\r
-               __m128i s = _mm_loadu_si128((const __m128i *)p);\r
-               __m128i x = _mm_cmpeq_epi8(s, w0);\r
-               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));\r
-               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));\r
-               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));\r
-               unsigned short r = ~_mm_movemask_epi8(x);\r
-               if (r == 0)     // all 16 characters are whitespace\r
-                       p += 16;\r
-               else {          // some of characters may be non-whitespace\r
-#ifdef _MSC_VER                // Find the index of first non-whitespace\r
-                       unsigned long offset;\r
-                       if (_BitScanForward(&offset, r))\r
-                               return p + offset;\r
-#else\r
-                       if (r != 0)\r
-                               return p + __builtin_ffs(r) - 1;\r
-#endif\r
-               }\r
-       }\r
-}\r
-\r
-#endif // RAPIDJSON_SSE2\r
-\r
-#ifdef RAPIDJSON_SIMD\r
-//! Template function specialization for InsituStringStream\r
-template<> inline void SkipWhitespace(InsituStringStream& stream) { \r
-       stream.src_ = const_cast<char*>(SkipWhitespace_SIMD(stream.src_));\r
-}\r
-\r
-//! Template function specialization for StringStream\r
-template<> inline void SkipWhitespace(StringStream& stream) {\r
-       stream.src_ = SkipWhitespace_SIMD(stream.src_);\r
-}\r
-#endif // RAPIDJSON_SIMD\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
-// GenericReader\r
-\r
-//! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.\r
-/*! GenericReader parses JSON text from a stream, and send events synchronously to an \r
-    object implementing Handler concept.\r
-\r
-    It needs to allocate a stack for storing a single decoded string during \r
-    non-destructive parsing.\r
-\r
-    For in-situ parsing, the decoded string is directly written to the source \r
-    text string, no temporary buffer is required.\r
-\r
-    A GenericReader object can be reused for parsing multiple JSON text.\r
-    \r
-    \tparam Encoding Encoding of both the stream and the parse output.\r
-    \tparam Allocator Allocator type for stack.\r
-*/\r
-template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >\r
-class GenericReader {\r
-public:\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       //! Constructor.\r
-       /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)\r
-               \param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)\r
-       */\r
-       GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}\r
-\r
-       //! Parse JSON text.\r
-       /*! \tparam parseFlags Combination of ParseFlag. \r
-                \tparam Stream Type of input stream.\r
-                \tparam Handler Type of handler which must implement Handler concept.\r
-                \param stream Input stream to be parsed.\r
-                \param handler The handler to receive events.\r
-                \return Whether the parsing is successful.\r
-       */\r
-       template <unsigned parseFlags, typename Stream, typename Handler>\r
-       bool Parse(Stream& stream, Handler& handler) {\r
-               parseError_ = 0;\r
-               errorOffset_ = 0;\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(push)\r
-#pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable\r
-#endif\r
-               if (setjmp(jmpbuf_)) {\r
-#ifdef _MSC_VER\r
-#pragma warning(pop)\r
-#endif\r
-                       stack_.Clear();\r
-                       return false;\r
-               }\r
-\r
-               SkipWhitespace(stream);\r
-\r
-               if (stream.Peek() == '\0')\r
-                       RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell());\r
-               else {\r
-                       switch (stream.Peek()) {\r
-                               case '{': ParseObject<parseFlags>(stream, handler); break;\r
-                               case '[': ParseArray<parseFlags>(stream, handler); break;\r
-                               default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell());\r
-                       }\r
-                       SkipWhitespace(stream);\r
-\r
-                       if (stream.Peek() != '\0')\r
-                               RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell());\r
-               }\r
-\r
-               return true;\r
-       }\r
-\r
-       bool HasParseError() const { return parseError_ != 0; }\r
-       const char* GetParseError() const { return parseError_; }\r
-       size_t GetErrorOffset() const { return errorOffset_; }\r
-\r
-private:\r
-       // Parse object: { string : value, ... }\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseObject(Stream& stream, Handler& handler) {\r
-               RAPIDJSON_ASSERT(stream.Peek() == '{');\r
-               stream.Take();  // Skip '{'\r
-               handler.StartObject();\r
-               SkipWhitespace(stream);\r
-\r
-               if (stream.Peek() == '}') {\r
-                       stream.Take();\r
-                       handler.EndObject(0);   // empty object\r
-                       return;\r
-               }\r
-\r
-               for (SizeType memberCount = 0;;) {\r
-                       if (stream.Peek() != '"') {\r
-                               RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell());\r
-                               break;\r
-                       }\r
-\r
-                       ParseString<parseFlags>(stream, handler);\r
-                       SkipWhitespace(stream);\r
-\r
-                       if (stream.Take() != ':') {\r
-                               RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell());\r
-                               break;\r
-                       }\r
-                       SkipWhitespace(stream);\r
-\r
-                       ParseValue<parseFlags>(stream, handler);\r
-                       SkipWhitespace(stream);\r
-\r
-                       ++memberCount;\r
-\r
-                       switch(stream.Take()) {\r
-                               case ',': SkipWhitespace(stream); break;\r
-                               case '}': handler.EndObject(memberCount); return;\r
-                               default:  RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell());\r
-                       }\r
-               }\r
-       }\r
-\r
-       // Parse array: [ value, ... ]\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseArray(Stream& stream, Handler& handler) {\r
-               RAPIDJSON_ASSERT(stream.Peek() == '[');\r
-               stream.Take();  // Skip '['\r
-               handler.StartArray();\r
-               SkipWhitespace(stream);\r
-\r
-               if (stream.Peek() == ']') {\r
-                       stream.Take();\r
-                       handler.EndArray(0); // empty array\r
-                       return;\r
-               }\r
-\r
-               for (SizeType elementCount = 0;;) {\r
-                       ParseValue<parseFlags>(stream, handler);\r
-                       ++elementCount;\r
-                       SkipWhitespace(stream);\r
-\r
-                       switch (stream.Take()) {\r
-                               case ',': SkipWhitespace(stream); break;\r
-                               case ']': handler.EndArray(elementCount); return;\r
-                               default:  RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell());\r
-                       }\r
-               }\r
-       }\r
-\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseNull(Stream& stream, Handler& handler) {\r
-               RAPIDJSON_ASSERT(stream.Peek() == 'n');\r
-               stream.Take();\r
-\r
-               if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l')\r
-                       handler.Null();\r
-               else\r
-                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);\r
-       }\r
-\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseTrue(Stream& stream, Handler& handler) {\r
-               RAPIDJSON_ASSERT(stream.Peek() == 't');\r
-               stream.Take();\r
-\r
-               if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e')\r
-                       handler.Bool(true);\r
-               else\r
-                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell());\r
-       }\r
-\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseFalse(Stream& stream, Handler& handler) {\r
-               RAPIDJSON_ASSERT(stream.Peek() == 'f');\r
-               stream.Take();\r
-\r
-               if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e')\r
-                       handler.Bool(false);\r
-               else\r
-                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);\r
-       }\r
-\r
-       // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().\r
-       template<typename Stream>\r
-       unsigned ParseHex4(Stream& stream) {\r
-               Stream s = stream;      // Use a local copy for optimization\r
-               unsigned codepoint = 0;\r
-               for (int i = 0; i < 4; i++) {\r
-                       Ch c = s.Take();\r
-                       codepoint <<= 4;\r
-                       codepoint += c;\r
-                       if (c >= '0' && c <= '9')\r
-                               codepoint -= '0';\r
-                       else if (c >= 'A' && c <= 'F')\r
-                               codepoint -= 'A' - 10;\r
-                       else if (c >= 'a' && c <= 'f')\r
-                               codepoint -= 'a' - 10;\r
-                       else \r
-                               RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1);\r
-               }\r
-               stream = s; // Restore stream\r
-               return codepoint;\r
-       }\r
-\r
-       // Parse string, handling the prefix and suffix double quotes and escaping.\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseString(Stream& stream, Handler& handler) {\r
-#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\r
-               static const Ch escape[256] = {\r
-                       Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', \r
-                       Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, \r
-                       0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, \r
-                       0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \r
-                       Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16\r
-               };\r
-#undef Z16\r
-\r
-               Stream s = stream;      // Use a local copy for optimization\r
-               RAPIDJSON_ASSERT(s.Peek() == '\"');\r
-               s.Take();       // Skip '\"'\r
-               Ch *head;\r
-               SizeType len;\r
-               if (parseFlags & kParseInsituFlag)\r
-                       head = s.PutBegin();\r
-               else\r
-                       len = 0;\r
-\r
-#define RAPIDJSON_PUT(x) \\r
-       do { \\r
-               if (parseFlags & kParseInsituFlag) \\r
-                       s.Put(x); \\r
-               else { \\r
-                       *stack_.template Push<Ch>() = x; \\r
-                       ++len; \\r
-               } \\r
-       } while(false)\r
-\r
-               for (;;) {\r
-                       Ch c = s.Take();\r
-                       if (c == '\\') {        // Escape\r
-                               Ch e = s.Take();\r
-                               if ((sizeof(Ch) == 1 || e < 256) && escape[(unsigned char)e])\r
-                                       RAPIDJSON_PUT(escape[(unsigned char)e]);\r
-                               else if (e == 'u') {    // Unicode\r
-                                       unsigned codepoint = ParseHex4(s);\r
-                                       if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair\r
-                                               if (s.Take() != '\\' || s.Take() != 'u') {\r
-                                                       RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2);\r
-                                                       return;\r
-                                               }\r
-                                               unsigned codepoint2 = ParseHex4(s);\r
-                                               if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {\r
-                                                       RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2);\r
-                                                       return;\r
-                                               }\r
-                                               codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;\r
-                                       }\r
-\r
-                                       Ch buffer[4];\r
-                                       SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);\r
-\r
-                                       if (parseFlags & kParseInsituFlag) \r
-                                               for (SizeType i = 0; i < count; i++)\r
-                                                       s.Put(buffer[i]);\r
-                                       else {\r
-                                               memcpy(stack_.template Push<Ch>(count), buffer, count * sizeof(Ch));\r
-                                               len += count;\r
-                                       }\r
-                               }\r
-                               else {\r
-                                       RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1);\r
-                                       return;\r
-                               }\r
-                       }\r
-                       else if (c == '"') {    // Closing double quote\r
-                               if (parseFlags & kParseInsituFlag) {\r
-                                       size_t length = s.PutEnd(head);\r
-                                       RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);\r
-                                       RAPIDJSON_PUT('\0');    // null-terminate the string\r
-                                       handler.String(head, SizeType(length), false);\r
-                               }\r
-                               else {\r
-                                       RAPIDJSON_PUT('\0');\r
-                                       handler.String(stack_.template Pop<Ch>(len), len - 1, true);\r
-                               }\r
-                               stream = s;     // restore stream\r
-                               return;\r
-                       }\r
-                       else if (c == '\0') {\r
-                               RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1);\r
-                               return;\r
-                       }\r
-                       else if ((unsigned)c < 0x20) {  // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF\r
-                               RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1);\r
-                               return;\r
-                       }\r
-                       else\r
-                               RAPIDJSON_PUT(c);       // Normal character, just copy\r
-               }\r
-#undef RAPIDJSON_PUT\r
-       }\r
-\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseNumber(Stream& stream, Handler& handler) {\r
-               Stream s = stream; // Local copy for optimization\r
-               // Parse minus\r
-               bool minus = false;\r
-               if (s.Peek() == '-') {\r
-                       minus = true;\r
-                       s.Take();\r
-               }\r
-\r
-               // Parse int: zero / ( digit1-9 *DIGIT )\r
-               unsigned i;\r
-               bool try64bit = false;\r
-               if (s.Peek() == '0') {\r
-                       i = 0;\r
-                       s.Take();\r
-               }\r
-               else if (s.Peek() >= '1' && s.Peek() <= '9') {\r
-                       i = s.Take() - '0';\r
-\r
-                       if (minus)\r
-                               while (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                                       if (i >= 214748364) { // 2^31 = 2147483648\r
-                                               if (i != 214748364 || s.Peek() > '8') {\r
-                                                       try64bit = true;\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                                       i = i * 10 + (s.Take() - '0');\r
-                               }\r
-                       else\r
-                               while (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                                       if (i >= 429496729) { // 2^32 - 1 = 4294967295\r
-                                               if (i != 429496729 || s.Peek() > '5') {\r
-                                                       try64bit = true;\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                                       i = i * 10 + (s.Take() - '0');\r
-                               }\r
-               }\r
-               else {\r
-                       RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell());\r
-                       return;\r
-               }\r
-\r
-               // Parse 64bit int\r
-               uint64_t i64 = 0;\r
-               bool useDouble = false;\r
-               if (try64bit) {\r
-                       i64 = i;\r
-                       if (minus) \r
-                               while (s.Peek() >= '0' && s.Peek() <= '9') {                                    \r
-                                       if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808\r
-                                               if (i64 != 922337203685477580uLL || s.Peek() > '8') {\r
-                                                       useDouble = true;\r
-                                                       break;\r
-                                               }\r
-                                       i64 = i64 * 10 + (s.Take() - '0');\r
-                               }\r
-                       else\r
-                               while (s.Peek() >= '0' && s.Peek() <= '9') {                                    \r
-                                       if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615\r
-                                               if (i64 != 1844674407370955161uLL || s.Peek() > '5') {\r
-                                                       useDouble = true;\r
-                                                       break;\r
-                                               }\r
-                                       i64 = i64 * 10 + (s.Take() - '0');\r
-                               }\r
-               }\r
-\r
-               // Force double for big integer\r
-               double d = 0.0;\r
-               if (useDouble) {\r
-                       d = (double)i64;\r
-                       while (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                               if (d >= 1E307) {\r
-                                       RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());\r
-                                       return;\r
-                               }\r
-                               d = d * 10 + (s.Take() - '0');\r
-                       }\r
-               }\r
-\r
-               // Parse frac = decimal-point 1*DIGIT\r
-               int expFrac = 0;\r
-               if (s.Peek() == '.') {\r
-                       if (!useDouble) {\r
-                               d = try64bit ? (double)i64 : (double)i;\r
-                               useDouble = true;\r
-                       }\r
-                       s.Take();\r
-\r
-                       if (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                               d = d * 10 + (s.Take() - '0');\r
-                               --expFrac;\r
-                       }\r
-                       else {\r
-                               RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell());\r
-                               return;\r
-                       }\r
-\r
-                       while (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                               if (expFrac > -16) {\r
-                                       d = d * 10 + (s.Peek() - '0');\r
-                                       --expFrac;\r
-                               }\r
-                               s.Take();\r
-                       }\r
-               }\r
-\r
-               // Parse exp = e [ minus / plus ] 1*DIGIT\r
-               int exp = 0;\r
-               if (s.Peek() == 'e' || s.Peek() == 'E') {\r
-                       if (!useDouble) {\r
-                               d = try64bit ? (double)i64 : (double)i;\r
-                               useDouble = true;\r
-                       }\r
-                       s.Take();\r
-\r
-                       bool expMinus = false;\r
-                       if (s.Peek() == '+')\r
-                               s.Take();\r
-                       else if (s.Peek() == '-') {\r
-                               s.Take();\r
-                               expMinus = true;\r
-                       }\r
-\r
-                       if (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                               exp = s.Take() - '0';\r
-                               while (s.Peek() >= '0' && s.Peek() <= '9') {\r
-                                       exp = exp * 10 + (s.Take() - '0');\r
-                                       if (exp > 308) {\r
-                                               RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());\r
-                                               return;\r
-                                       }\r
-                               }\r
-                       }\r
-                       else {\r
-                               RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell());\r
-                               return;\r
-                       }\r
-\r
-                       if (expMinus)\r
-                               exp = -exp;\r
-               }\r
-\r
-               // Finish parsing, call event according to the type of number.\r
-               if (useDouble) {\r
-                       d *= internal::Pow10(exp + expFrac);\r
-                       handler.Double(minus ? -d : d);\r
-               }\r
-               else {\r
-                       if (try64bit) {\r
-                               if (minus)\r
-                                       handler.Int64(-(int64_t)i64);\r
-                               else\r
-                                       handler.Uint64(i64);\r
-                       }\r
-                       else {\r
-                               if (minus)\r
-                                       handler.Int(-(int)i);\r
-                               else\r
-                                       handler.Uint(i);\r
-                       }\r
-               }\r
-\r
-               stream = s; // restore stream\r
-       }\r
-\r
-       // Parse any JSON value\r
-       template<unsigned parseFlags, typename Stream, typename Handler>\r
-       void ParseValue(Stream& stream, Handler& handler) {\r
-               switch (stream.Peek()) {\r
-                       case 'n': ParseNull  <parseFlags>(stream, handler); break;\r
-                       case 't': ParseTrue  <parseFlags>(stream, handler); break;\r
-                       case 'f': ParseFalse <parseFlags>(stream, handler); break;\r
-                       case '"': ParseString<parseFlags>(stream, handler); break;\r
-                       case '{': ParseObject<parseFlags>(stream, handler); break;\r
-                       case '[': ParseArray <parseFlags>(stream, handler); break;\r
-                       default : ParseNumber<parseFlags>(stream, handler);\r
-               }\r
-       }\r
-\r
-       static const size_t kDefaultStackCapacity = 256;        //!< Default stack capacity in bytes for storing a single decoded string. \r
-       internal::Stack<Allocator> stack_;      //!< A stack for storing decoded string temporarily during non-destructive parsing.\r
-       jmp_buf jmpbuf_;                                        //!< setjmp buffer for fast exit from nested parsing function calls.\r
-       const char* parseError_;\r
-       size_t errorOffset_;\r
-}; // class GenericReader\r
-\r
-//! Reader with UTF8 encoding and default allocator.\r
-typedef GenericReader<UTF8<> > Reader;\r
-\r
-} // namespace rapidjson\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(pop)\r
-#endif\r
-\r
-#endif // RAPIDJSON_READER_H_\r
+#ifndef RAPIDJSON_READER_H_
+#define RAPIDJSON_READER_H_
+
+// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
+// Version 0.1
+
+#include "rapidjson.h"
+#include "internal/pow10.h"
+#include "internal/stack.h"
+#include <csetjmp>
+
+#ifdef RAPIDJSON_SSE42
+#include <nmmintrin.h>
+#elif defined(RAPIDJSON_SSE2)
+#include <emmintrin.h>
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+
+#ifndef RAPIDJSON_PARSE_ERROR
+#define RAPIDJSON_PARSE_ERROR(msg, offset) \
+       RAPIDJSON_MULTILINEMACRO_BEGIN \
+       parseError_ = msg; \
+       errorOffset_ = offset; \
+       longjmp(jmpbuf_, 1); \
+       RAPIDJSON_MULTILINEMACRO_END
+#endif
+
+namespace rapidjson {
+
+///////////////////////////////////////////////////////////////////////////////
+// ParseFlag
+
+//! Combination of parseFlags
+enum ParseFlag {
+       kParseDefaultFlags = 0,                 //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
+       kParseInsituFlag = 1                    //!< In-situ(destructive) parsing.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Handler
+
+/*!    \class rapidjson::Handler
+       \brief Concept for receiving events from GenericReader upon parsing.
+\code
+concept Handler {
+       typename Ch;
+
+       void Null();
+       void Bool(bool b);
+       void Int(int i);
+       void Uint(unsigned i);
+       void Int64(int64_t i);
+       void Uint64(uint64_t i);
+       void Double(double d);
+       void String(const Ch* str, SizeType length, bool copy);
+       void StartObject();
+       void EndObject(SizeType memberCount);
+       void StartArray();
+       void EndArray(SizeType elementCount);
+};
+\endcode
+*/
+///////////////////////////////////////////////////////////////////////////////
+// BaseReaderHandler
+
+//! Default implementation of Handler.
+/*! This can be used as base class of any reader handler.
+       \implements Handler
+*/
+template<typename Encoding = UTF8<> >
+struct BaseReaderHandler {
+       typedef typename Encoding::Ch Ch;
+
+       void Default() {}
+       void Null() { Default(); }
+       void Bool(bool) { Default(); }
+       void Int(int) { Default(); }
+       void Uint(unsigned) { Default(); }
+       void Int64(int64_t) { Default(); }
+       void Uint64(uint64_t) { Default(); }
+       void Double(double) { Default(); }
+       void String(const Ch*, SizeType, bool) { Default(); }
+       void StartObject() { Default(); }
+       void EndObject(SizeType) { Default(); }
+       void StartArray() { Default(); }
+       void EndArray(SizeType) { Default(); }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// SkipWhitespace
+
+//! Skip the JSON white spaces in a stream.
+/*! \param stream A input stream for skipping white spaces.
+       \note This function has SSE2/SSE4.2 specialization.
+*/
+template<typename Stream>
+void SkipWhitespace(Stream& stream) {
+       Stream s = stream;      // Use a local copy for optimization
+       while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
+               s.Take();
+       stream = s;
+}
+
+#ifdef RAPIDJSON_SSE42
+//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
+inline const char *SkipWhitespace_SIMD(const char* p) {
+       static const char whitespace[16] = " \n\r\t";
+       __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
+
+       for (;;) {
+               __m128i s = _mm_loadu_si128((const __m128i *)p);
+               unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
+               if (r == 0)     // all 16 characters are whitespace
+                       p += 16;
+               else {          // some of characters may be non-whitespace
+#ifdef _MSC_VER                // Find the index of first non-whitespace
+                       unsigned long offset;
+                       if (_BitScanForward(&offset, r))
+                               return p + offset;
+#else
+                       if (r != 0)
+                               return p + __builtin_ffs(r) - 1;
+#endif
+               }
+       }
+}
+
+#elif defined(RAPIDJSON_SSE2)
+
+//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
+inline const char *SkipWhitespace_SIMD(const char* p) {
+       static const char whitespaces[4][17] = {
+               "                ",
+               "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
+               "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
+               "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
+
+       __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
+       __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
+       __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
+       __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
+
+       for (;;) {
+               __m128i s = _mm_loadu_si128((const __m128i *)p);
+               __m128i x = _mm_cmpeq_epi8(s, w0);
+               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
+               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
+               x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
+               unsigned short r = ~_mm_movemask_epi8(x);
+               if (r == 0)     // all 16 characters are whitespace
+                       p += 16;
+               else {          // some of characters may be non-whitespace
+#ifdef _MSC_VER                // Find the index of first non-whitespace
+                       unsigned long offset;
+                       if (_BitScanForward(&offset, r))
+                               return p + offset;
+#else
+                       if (r != 0)
+                               return p + __builtin_ffs(r) - 1;
+#endif
+               }
+       }
+}
+
+#endif // RAPIDJSON_SSE2
+
+#ifdef RAPIDJSON_SIMD
+//! Template function specialization for InsituStringStream
+template<> inline void SkipWhitespace(InsituStringStream& stream) { 
+       stream.src_ = const_cast<char*>(SkipWhitespace_SIMD(stream.src_));
+}
+
+//! Template function specialization for StringStream
+template<> inline void SkipWhitespace(StringStream& stream) {
+       stream.src_ = SkipWhitespace_SIMD(stream.src_);
+}
+#endif // RAPIDJSON_SIMD
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericReader
+
+//! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
+/*! GenericReader parses JSON text from a stream, and send events synchronously to an 
+    object implementing Handler concept.
+
+    It needs to allocate a stack for storing a single decoded string during 
+    non-destructive parsing.
+
+    For in-situ parsing, the decoded string is directly written to the source 
+    text string, no temporary buffer is required.
+
+    A GenericReader object can be reused for parsing multiple JSON text.
+    
+    \tparam Encoding Encoding of both the stream and the parse output.
+    \tparam Allocator Allocator type for stack.
+*/
+template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
+class GenericReader {
+public:
+       typedef typename Encoding::Ch Ch;
+
+       //! Constructor.
+       /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
+               \param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)
+       */
+       GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
+
+       //! Parse JSON text.
+       /*! \tparam parseFlags Combination of ParseFlag. 
+                \tparam Stream Type of input stream.
+                \tparam Handler Type of handler which must implement Handler concept.
+                \param stream Input stream to be parsed.
+                \param handler The handler to receive events.
+                \return Whether the parsing is successful.
+       */
+       template <unsigned parseFlags, typename Stream, typename Handler>
+       bool Parse(Stream& stream, Handler& handler) {
+               parseError_ = 0;
+               errorOffset_ = 0;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#endif
+               if (setjmp(jmpbuf_)) {
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+                       stack_.Clear();
+                       return false;
+               }
+
+               SkipWhitespace(stream);
+
+               if (stream.Peek() == '\0')
+                       RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell());
+               else {
+                       switch (stream.Peek()) {
+                               case '{': ParseObject<parseFlags>(stream, handler); break;
+                               case '[': ParseArray<parseFlags>(stream, handler); break;
+                               default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell());
+                       }
+                       SkipWhitespace(stream);
+
+                       if (stream.Peek() != '\0')
+                               RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell());
+               }
+
+               return true;
+       }
+
+       bool HasParseError() const { return parseError_ != 0; }
+       const char* GetParseError() const { return parseError_; }
+       size_t GetErrorOffset() const { return errorOffset_; }
+
+private:
+       // Parse object: { string : value, ... }
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseObject(Stream& stream, Handler& handler) {
+               RAPIDJSON_ASSERT(stream.Peek() == '{');
+               stream.Take();  // Skip '{'
+               handler.StartObject();
+               SkipWhitespace(stream);
+
+               if (stream.Peek() == '}') {
+                       stream.Take();
+                       handler.EndObject(0);   // empty object
+                       return;
+               }
+
+               for (SizeType memberCount = 0;;) {
+                       if (stream.Peek() != '"') {
+                               RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell());
+                               break;
+                       }
+
+                       ParseString<parseFlags>(stream, handler);
+                       SkipWhitespace(stream);
+
+                       if (stream.Take() != ':') {
+                               RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell());
+                               break;
+                       }
+                       SkipWhitespace(stream);
+
+                       ParseValue<parseFlags>(stream, handler);
+                       SkipWhitespace(stream);
+
+                       ++memberCount;
+
+                       switch(stream.Take()) {
+                               case ',': SkipWhitespace(stream); break;
+                               case '}': handler.EndObject(memberCount); return;
+                               default:  RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell());
+                       }
+               }
+       }
+
+       // Parse array: [ value, ... ]
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseArray(Stream& stream, Handler& handler) {
+               RAPIDJSON_ASSERT(stream.Peek() == '[');
+               stream.Take();  // Skip '['
+               handler.StartArray();
+               SkipWhitespace(stream);
+
+               if (stream.Peek() == ']') {
+                       stream.Take();
+                       handler.EndArray(0); // empty array
+                       return;
+               }
+
+               for (SizeType elementCount = 0;;) {
+                       ParseValue<parseFlags>(stream, handler);
+                       ++elementCount;
+                       SkipWhitespace(stream);
+
+                       switch (stream.Take()) {
+                               case ',': SkipWhitespace(stream); break;
+                               case ']': handler.EndArray(elementCount); return;
+                               default:  RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell());
+                       }
+               }
+       }
+
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseNull(Stream& stream, Handler& handler) {
+               RAPIDJSON_ASSERT(stream.Peek() == 'n');
+               stream.Take();
+
+               if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l')
+                       handler.Null();
+               else
+                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
+       }
+
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseTrue(Stream& stream, Handler& handler) {
+               RAPIDJSON_ASSERT(stream.Peek() == 't');
+               stream.Take();
+
+               if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e')
+                       handler.Bool(true);
+               else
+                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell());
+       }
+
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseFalse(Stream& stream, Handler& handler) {
+               RAPIDJSON_ASSERT(stream.Peek() == 'f');
+               stream.Take();
+
+               if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e')
+                       handler.Bool(false);
+               else
+                       RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
+       }
+
+       // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
+       template<typename Stream>
+       unsigned ParseHex4(Stream& stream) {
+               Stream s = stream;      // Use a local copy for optimization
+               unsigned codepoint = 0;
+               for (int i = 0; i < 4; i++) {
+                       Ch c = s.Take();
+                       codepoint <<= 4;
+                       codepoint += c;
+                       if (c >= '0' && c <= '9')
+                               codepoint -= '0';
+                       else if (c >= 'A' && c <= 'F')
+                               codepoint -= 'A' - 10;
+                       else if (c >= 'a' && c <= 'f')
+                               codepoint -= 'a' - 10;
+                       else 
+                               RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1);
+               }
+               stream = s; // Restore stream
+               return codepoint;
+       }
+
+       // Parse string, handling the prefix and suffix double quotes and escaping.
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseString(Stream& stream, Handler& handler) {
+#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+               static const Ch escape[256] = {
+                       Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', 
+                       Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, 
+                       0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, 
+                       0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+                       Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
+               };
+#undef Z16
+
+               Stream s = stream;      // Use a local copy for optimization
+               RAPIDJSON_ASSERT(s.Peek() == '\"');
+               s.Take();       // Skip '\"'
+               Ch *head;
+               SizeType len;
+               if (parseFlags & kParseInsituFlag)
+                       head = s.PutBegin();
+               else
+                       len = 0;
+
+#define RAPIDJSON_PUT(x) \
+       do { \
+               if (parseFlags & kParseInsituFlag) \
+                       s.Put(x); \
+               else { \
+                       *stack_.template Push<Ch>() = x; \
+                       ++len; \
+               } \
+       } while(false)
+
+               for (;;) {
+                       Ch c = s.Take();
+                       if (c == '\\') {        // Escape
+                               Ch e = s.Take();
+                               if ((sizeof(Ch) == 1 || e < 256) && escape[(unsigned char)e])
+                                       RAPIDJSON_PUT(escape[(unsigned char)e]);
+                               else if (e == 'u') {    // Unicode
+                                       unsigned codepoint = ParseHex4(s);
+                                       if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair
+                                               if (s.Take() != '\\' || s.Take() != 'u') {
+                                                       RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2);
+                                                       return;
+                                               }
+                                               unsigned codepoint2 = ParseHex4(s);
+                                               if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
+                                                       RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2);
+                                                       return;
+                                               }
+                                               codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
+                                       }
+
+                                       Ch buffer[4];
+                                       SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);
+
+                                       if (parseFlags & kParseInsituFlag) 
+                                               for (SizeType i = 0; i < count; i++)
+                                                       s.Put(buffer[i]);
+                                       else {
+                                               memcpy(stack_.template Push<Ch>(count), buffer, count * sizeof(Ch));
+                                               len += count;
+                                       }
+                               }
+                               else {
+                                       RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1);
+                                       return;
+                               }
+                       }
+                       else if (c == '"') {    // Closing double quote
+                               if (parseFlags & kParseInsituFlag) {
+                                       size_t length = s.PutEnd(head);
+                                       RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
+                                       RAPIDJSON_PUT('\0');    // null-terminate the string
+                                       handler.String(head, SizeType(length), false);
+                               }
+                               else {
+                                       RAPIDJSON_PUT('\0');
+                                       handler.String(stack_.template Pop<Ch>(len), len - 1, true);
+                               }
+                               stream = s;     // restore stream
+                               return;
+                       }
+                       else if (c == '\0') {
+                               RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1);
+                               return;
+                       }
+                       else if ((unsigned)c < 0x20) {  // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
+                               RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1);
+                               return;
+                       }
+                       else
+                               RAPIDJSON_PUT(c);       // Normal character, just copy
+               }
+#undef RAPIDJSON_PUT
+       }
+
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseNumber(Stream& stream, Handler& handler) {
+               Stream s = stream; // Local copy for optimization
+               // Parse minus
+               bool minus = false;
+               if (s.Peek() == '-') {
+                       minus = true;
+                       s.Take();
+               }
+
+               // Parse int: zero / ( digit1-9 *DIGIT )
+               unsigned i;
+               bool try64bit = false;
+               if (s.Peek() == '0') {
+                       i = 0;
+                       s.Take();
+               }
+               else if (s.Peek() >= '1' && s.Peek() <= '9') {
+                       i = s.Take() - '0';
+
+                       if (minus)
+                               while (s.Peek() >= '0' && s.Peek() <= '9') {
+                                       if (i >= 214748364) { // 2^31 = 2147483648
+                                               if (i != 214748364 || s.Peek() > '8') {
+                                                       try64bit = true;
+                                                       break;
+                                               }
+                                       }
+                                       i = i * 10 + (s.Take() - '0');
+                               }
+                       else
+                               while (s.Peek() >= '0' && s.Peek() <= '9') {
+                                       if (i >= 429496729) { // 2^32 - 1 = 4294967295
+                                               if (i != 429496729 || s.Peek() > '5') {
+                                                       try64bit = true;
+                                                       break;
+                                               }
+                                       }
+                                       i = i * 10 + (s.Take() - '0');
+                               }
+               }
+               else {
+                       RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell());
+                       return;
+               }
+
+               // Parse 64bit int
+               uint64_t i64 = 0;
+               bool useDouble = false;
+               if (try64bit) {
+                       i64 = i;
+                       if (minus) 
+                               while (s.Peek() >= '0' && s.Peek() <= '9') {                                    
+                                       if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808
+                                               if (i64 != 922337203685477580uLL || s.Peek() > '8') {
+                                                       useDouble = true;
+                                                       break;
+                                               }
+                                       i64 = i64 * 10 + (s.Take() - '0');
+                               }
+                       else
+                               while (s.Peek() >= '0' && s.Peek() <= '9') {                                    
+                                       if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615
+                                               if (i64 != 1844674407370955161uLL || s.Peek() > '5') {
+                                                       useDouble = true;
+                                                       break;
+                                               }
+                                       i64 = i64 * 10 + (s.Take() - '0');
+                               }
+               }
+
+               // Force double for big integer
+               double d = 0.0;
+               if (useDouble) {
+                       d = (double)i64;
+                       while (s.Peek() >= '0' && s.Peek() <= '9') {
+                               if (d >= 1E307) {
+                                       RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
+                                       return;
+                               }
+                               d = d * 10 + (s.Take() - '0');
+                       }
+               }
+
+               // Parse frac = decimal-point 1*DIGIT
+               int expFrac = 0;
+               if (s.Peek() == '.') {
+                       if (!useDouble) {
+                               d = try64bit ? (double)i64 : (double)i;
+                               useDouble = true;
+                       }
+                       s.Take();
+
+                       if (s.Peek() >= '0' && s.Peek() <= '9') {
+                               d = d * 10 + (s.Take() - '0');
+                               --expFrac;
+                       }
+                       else {
+                               RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell());
+                               return;
+                       }
+
+                       while (s.Peek() >= '0' && s.Peek() <= '9') {
+                               if (expFrac > -16) {
+                                       d = d * 10 + (s.Peek() - '0');
+                                       --expFrac;
+                               }
+                               s.Take();
+                       }
+               }
+
+               // Parse exp = e [ minus / plus ] 1*DIGIT
+               int exp = 0;
+               if (s.Peek() == 'e' || s.Peek() == 'E') {
+                       if (!useDouble) {
+                               d = try64bit ? (double)i64 : (double)i;
+                               useDouble = true;
+                       }
+                       s.Take();
+
+                       bool expMinus = false;
+                       if (s.Peek() == '+')
+                               s.Take();
+                       else if (s.Peek() == '-') {
+                               s.Take();
+                               expMinus = true;
+                       }
+
+                       if (s.Peek() >= '0' && s.Peek() <= '9') {
+                               exp = s.Take() - '0';
+                               while (s.Peek() >= '0' && s.Peek() <= '9') {
+                                       exp = exp * 10 + (s.Take() - '0');
+                                       if (exp > 308) {
+                                               RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
+                                               return;
+                                       }
+                               }
+                       }
+                       else {
+                               RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell());
+                               return;
+                       }
+
+                       if (expMinus)
+                               exp = -exp;
+               }
+
+               // Finish parsing, call event according to the type of number.
+               if (useDouble) {
+                       d *= internal::Pow10(exp + expFrac);
+                       handler.Double(minus ? -d : d);
+               }
+               else {
+                       if (try64bit) {
+                               if (minus)
+                                       handler.Int64(-(int64_t)i64);
+                               else
+                                       handler.Uint64(i64);
+                       }
+                       else {
+                               if (minus)
+                                       handler.Int(-(int)i);
+                               else
+                                       handler.Uint(i);
+                       }
+               }
+
+               stream = s; // restore stream
+       }
+
+       // Parse any JSON value
+       template<unsigned parseFlags, typename Stream, typename Handler>
+       void ParseValue(Stream& stream, Handler& handler) {
+               switch (stream.Peek()) {
+                       case 'n': ParseNull  <parseFlags>(stream, handler); break;
+                       case 't': ParseTrue  <parseFlags>(stream, handler); break;
+                       case 'f': ParseFalse <parseFlags>(stream, handler); break;
+                       case '"': ParseString<parseFlags>(stream, handler); break;
+                       case '{': ParseObject<parseFlags>(stream, handler); break;
+                       case '[': ParseArray <parseFlags>(stream, handler); break;
+                       default : ParseNumber<parseFlags>(stream, handler);
+               }
+       }
+
+       static const size_t kDefaultStackCapacity = 256;        //!< Default stack capacity in bytes for storing a single decoded string. 
+       internal::Stack<Allocator> stack_;      //!< A stack for storing decoded string temporarily during non-destructive parsing.
+       jmp_buf jmpbuf_;                                        //!< setjmp buffer for fast exit from nested parsing function calls.
+       const char* parseError_;
+       size_t errorOffset_;
+}; // class GenericReader
+
+//! Reader with UTF8 encoding and default allocator.
+typedef GenericReader<UTF8<> > Reader;
+
+} // namespace rapidjson
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // RAPIDJSON_READER_H_
index 34cff58ef9abc38e7cc71a1ad3fdaeae96e0b0c1..269ae10761dc22bc894e7ceee2a4ab81bbf58db5 100644 (file)
@@ -1,49 +1,49 @@
-#ifndef RAPIDJSON_STRINGBUFFER_H_\r
-#define RAPIDJSON_STRINGBUFFER_H_\r
-\r
-#include "rapidjson.h"\r
-#include "internal/stack.h"\r
-\r
-namespace rapidjson {\r
-\r
-//! Represents an in-memory output stream.\r
-/*!\r
-       \tparam Encoding Encoding of the stream.\r
-       \tparam Allocator type for allocating memory buffer.\r
-       \implements Stream\r
-*/\r
-template <typename Encoding, typename Allocator = CrtAllocator>\r
-struct GenericStringBuffer {\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}\r
-\r
-       void Put(Ch c) { *stack_.template Push<Ch>() = c; }\r
-\r
-       void Clear() { stack_.Clear(); }\r
-\r
-       const char* GetString() const {\r
-               // Push and pop a null terminator. This is safe.\r
-               *stack_.template Push<Ch>() = '\0';\r
-               stack_.template Pop<Ch>(1);\r
-\r
-               return stack_.template Bottom<Ch>();\r
-       }\r
-\r
-       size_t Size() const { return stack_.GetSize(); }\r
-\r
-       static const size_t kDefaultCapacity = 256;\r
-       mutable internal::Stack<Allocator> stack_;\r
-};\r
-\r
-typedef GenericStringBuffer<UTF8<> > StringBuffer;\r
-\r
-//! Implement specialized version of PutN() with memset() for better performance.\r
-template<>\r
-inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {\r
-       memset(stream.stack_.Push<char>(n), c, n * sizeof(c));\r
-}\r
-\r
-} // namespace rapidjson\r
-\r
-#endif // RAPIDJSON_STRINGBUFFER_H_\r
+#ifndef RAPIDJSON_STRINGBUFFER_H_
+#define RAPIDJSON_STRINGBUFFER_H_
+
+#include "rapidjson.h"
+#include "internal/stack.h"
+
+namespace rapidjson {
+
+//! Represents an in-memory output stream.
+/*!
+       \tparam Encoding Encoding of the stream.
+       \tparam Allocator type for allocating memory buffer.
+       \implements Stream
+*/
+template <typename Encoding, typename Allocator = CrtAllocator>
+struct GenericStringBuffer {
+       typedef typename Encoding::Ch Ch;
+
+       GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
+
+       void Put(Ch c) { *stack_.template Push<Ch>() = c; }
+
+       void Clear() { stack_.Clear(); }
+
+       const char* GetString() const {
+               // Push and pop a null terminator. This is safe.
+               *stack_.template Push<Ch>() = '\0';
+               stack_.template Pop<Ch>(1);
+
+               return stack_.template Bottom<Ch>();
+       }
+
+       size_t Size() const { return stack_.GetSize(); }
+
+       static const size_t kDefaultCapacity = 256;
+       mutable internal::Stack<Allocator> stack_;
+};
+
+typedef GenericStringBuffer<UTF8<> > StringBuffer;
+
+//! Implement specialized version of PutN() with memset() for better performance.
+template<>
+inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
+       memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
+}
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_STRINGBUFFER_H_
index 9d674b7bf34557e70182cbbbc0630337342cb9ff..d96f2081a91d05f9defd175131c06255bfbafa71 100644 (file)
-#ifndef RAPIDJSON_WRITER_H_\r
-#define RAPIDJSON_WRITER_H_\r
-\r
-#include "rapidjson.h"\r
-#include "internal/stack.h"\r
-#include "internal/strfunc.h"\r
-#include <cstdio>      // snprintf() or _sprintf_s()\r
-#include <new>         // placement new\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(push)\r
-#pragma warning(disable : 4127) // conditional expression is constant\r
-#endif\r
-\r
-namespace rapidjson {\r
-\r
-//! JSON writer\r
-/*! Writer implements the concept Handler.\r
-       It generates JSON text by events to an output stream.\r
-\r
-       User may programmatically calls the functions of a writer to generate JSON text.\r
-\r
-       On the other side, a writer can also be passed to objects that generates events, \r
-\r
-       for example Reader::Parse() and Document::Accept().\r
-\r
-       \tparam Stream Type of ouptut stream.\r
-       \tparam Encoding Encoding of both source strings and output.\r
-       \implements Handler\r
-*/\r
-template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >\r
-class Writer {\r
-public:\r
-       typedef typename Encoding::Ch Ch;\r
-\r
-       Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : \r
-               stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {}\r
-\r
-       //@name Implementation of Handler\r
-       //@{\r
-       Writer& Null()                                  { Prefix(kNullType);   WriteNull();                     return *this; }\r
-       Writer& Bool(bool b)                    { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; }\r
-       Writer& Int(int i)                              { Prefix(kNumberType); WriteInt(i);                     return *this; }\r
-       Writer& Uint(unsigned u)                { Prefix(kNumberType); WriteUint(u);            return *this; }\r
-       Writer& Int64(int64_t i64)              { Prefix(kNumberType); WriteInt64(i64);         return *this; }\r
-       Writer& Uint64(uint64_t u64)    { Prefix(kNumberType); WriteUint64(u64);        return *this; }\r
-       Writer& Double(double d)                { Prefix(kNumberType); WriteDouble(d);          return *this; }\r
-\r
-       Writer& String(const Ch* str, SizeType length, bool copy = false) {\r
-               (void)copy;\r
-               Prefix(kStringType);\r
-               WriteString(str, length);\r
-               return *this;\r
-       }\r
-\r
-       Writer& StartObject() {\r
-               Prefix(kObjectType);\r
-               new (level_stack_.template Push<Level>()) Level(false);\r
-               WriteStartObject();\r
-               return *this;\r
-       }\r
-\r
-       Writer& EndObject(SizeType memberCount = 0) {\r
-               (void)memberCount;\r
-               RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));\r
-               RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);\r
-               level_stack_.template Pop<Level>(1);\r
-               WriteEndObject();\r
-               return *this;\r
-       }\r
-\r
-       Writer& StartArray() {\r
-               Prefix(kArrayType);\r
-               new (level_stack_.template Push<Level>()) Level(true);\r
-               WriteStartArray();\r
-               return *this;\r
-       }\r
-\r
-       Writer& EndArray(SizeType elementCount = 0) {\r
-               (void)elementCount;\r
-               RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));\r
-               RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);\r
-               level_stack_.template Pop<Level>(1);\r
-               WriteEndArray();\r
-               return *this;\r
-       }\r
-       //@}\r
-\r
-       //! Simpler but slower overload.\r
-       Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); }\r
-\r
-protected:\r
-       //! Information for each nested level\r
-       struct Level {\r
-               Level(bool inArray_) : inArray(inArray_), valueCount(0) {}\r
-               bool inArray;           //!< true if in array, otherwise in object\r
-               size_t valueCount;      //!< number of values in this level\r
-       };\r
-\r
-       static const size_t kDefaultLevelDepth = 32;\r
-\r
-       void WriteNull()  {\r
-               stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l');\r
-       }\r
-\r
-       void WriteBool(bool b)  {\r
-               if (b) {\r
-                       stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e');\r
-               }\r
-               else {\r
-                       stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e');\r
-               }\r
-       }\r
-\r
-       void WriteInt(int i) {\r
-               if (i < 0) {\r
-                       stream_.Put('-');\r
-                       i = -i;\r
-               }\r
-               WriteUint((unsigned)i);\r
-       }\r
-\r
-       void WriteUint(unsigned u) {\r
-               char buffer[10];\r
-               char *p = buffer;\r
-               do {\r
-                       *p++ = (u % 10) + '0';\r
-                       u /= 10;\r
-               } while (u > 0);\r
-\r
-               do {\r
-                       --p;\r
-                       stream_.Put(*p);\r
-               } while (p != buffer);\r
-       }\r
-\r
-       void WriteInt64(int64_t i64) {\r
-               if (i64 < 0) {\r
-                       stream_.Put('-');\r
-                       i64 = -i64;\r
-               }\r
-               WriteUint64((uint64_t)i64);\r
-       }\r
-\r
-       void WriteUint64(uint64_t u64) {\r
-               char buffer[20];\r
-               char *p = buffer;\r
-               do {\r
-                       *p++ = char(u64 % 10) + '0';\r
-                       u64 /= 10;\r
-               } while (u64 > 0);\r
-\r
-               do {\r
-                       --p;\r
-                       stream_.Put(*p);\r
-               } while (p != buffer);\r
-       }\r
-\r
-       //! \todo Optimization with custom double-to-string converter.\r
-       void WriteDouble(double d) {\r
-               char buffer[100];\r
-#if _MSC_VER\r
-               int ret = sprintf_s(buffer, sizeof(buffer), "%g", d);\r
-#else\r
-               int ret = snprintf(buffer, sizeof(buffer), "%g", d);\r
-#endif\r
-               RAPIDJSON_ASSERT(ret >= 1);\r
-               for (int i = 0; i < ret; i++)\r
-                       stream_.Put(buffer[i]);\r
-       }\r
-\r
-       void WriteString(const Ch* str, SizeType length)  {\r
-               static const char hexDigits[] = "0123456789ABCDEF";\r
-               static const char escape[256] = {\r
-#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\r
-                       //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F\r
-                       'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00\r
-                       'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10\r
-                         0,   0, '"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20\r
-                       Z16, Z16,                                                                                                                                               // 30~4F\r
-                         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\',   0,   0,   0, // 50\r
-                       Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16                                                                // 60~FF\r
-#undef Z16\r
-               };\r
-\r
-               stream_.Put('\"');\r
-               for (const Ch* p = str; p != str + length; ++p) {\r
-                       if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p])  {\r
-                               stream_.Put('\\');\r
-                               stream_.Put(escape[(unsigned char)*p]);\r
-                               if (escape[(unsigned char)*p] == 'u') {\r
-                                       stream_.Put('0');\r
-                                       stream_.Put('0');\r
-                                       stream_.Put(hexDigits[(*p) >> 4]);\r
-                                       stream_.Put(hexDigits[(*p) & 0xF]);\r
-                               }\r
-                       }\r
-                       else\r
-                               stream_.Put(*p);\r
-               }\r
-               stream_.Put('\"');\r
-       }\r
-\r
-       void WriteStartObject() { stream_.Put('{'); }\r
-       void WriteEndObject()   { stream_.Put('}'); }\r
-       void WriteStartArray()  { stream_.Put('['); }\r
-       void WriteEndArray()    { stream_.Put(']'); }\r
-\r
-       void Prefix(Type type) {\r
-               (void)type;\r
-               if (level_stack_.GetSize() != 0) { // this value is not at root\r
-                       Level* level = level_stack_.template Top<Level>();\r
-                       if (level->valueCount > 0) {\r
-                               if (level->inArray) \r
-                                       stream_.Put(','); // add comma if it is not the first element in array\r
-                               else  // in object\r
-                                       stream_.Put((level->valueCount % 2 == 0) ? ',' : ':');\r
-                       }\r
-                       if (!level->inArray && level->valueCount % 2 == 0)\r
-                               RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\r
-                       level->valueCount++;\r
-               }\r
-               else\r
-                       RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);\r
-       }\r
-\r
-       Stream& stream_;\r
-       internal::Stack<Allocator> level_stack_;\r
-\r
-private:\r
-       // Prohibit assignment for VC C4512 warning\r
-       Writer& operator=(const Writer& w);\r
-};\r
-\r
-} // namespace rapidjson\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(pop)\r
-#endif\r
-\r
-#endif // RAPIDJSON_RAPIDJSON_H_\r
+#ifndef RAPIDJSON_WRITER_H_
+#define RAPIDJSON_WRITER_H_
+
+#include "rapidjson.h"
+#include "internal/stack.h"
+#include "internal/strfunc.h"
+#include <cstdio>      // snprintf() or _sprintf_s()
+#include <new>         // placement new
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+
+namespace rapidjson {
+
+//! JSON writer
+/*! Writer implements the concept Handler.
+       It generates JSON text by events to an output stream.
+
+       User may programmatically calls the functions of a writer to generate JSON text.
+
+       On the other side, a writer can also be passed to objects that generates events, 
+
+       for example Reader::Parse() and Document::Accept().
+
+       \tparam Stream Type of ouptut stream.
+       \tparam Encoding Encoding of both source strings and output.
+       \implements Handler
+*/
+template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
+class Writer {
+public:
+       typedef typename Encoding::Ch Ch;
+
+       Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : 
+               stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {}
+
+       //@name Implementation of Handler
+       //@{
+       Writer& Null()                                  { Prefix(kNullType);   WriteNull();                     return *this; }
+       Writer& Bool(bool b)                    { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; }
+       Writer& Int(int i)                              { Prefix(kNumberType); WriteInt(i);                     return *this; }
+       Writer& Uint(unsigned u)                { Prefix(kNumberType); WriteUint(u);            return *this; }
+       Writer& Int64(int64_t i64)              { Prefix(kNumberType); WriteInt64(i64);         return *this; }
+       Writer& Uint64(uint64_t u64)    { Prefix(kNumberType); WriteUint64(u64);        return *this; }
+       Writer& Double(double d)                { Prefix(kNumberType); WriteDouble(d);          return *this; }
+
+       Writer& String(const Ch* str, SizeType length, bool copy = false) {
+               (void)copy;
+               Prefix(kStringType);
+               WriteString(str, length);
+               return *this;
+       }
+
+       Writer& StartObject() {
+               Prefix(kObjectType);
+               new (level_stack_.template Push<Level>()) Level(false);
+               WriteStartObject();
+               return *this;
+       }
+
+       Writer& EndObject(SizeType memberCount = 0) {
+               (void)memberCount;
+               RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
+               RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
+               level_stack_.template Pop<Level>(1);
+               WriteEndObject();
+               return *this;
+       }
+
+       Writer& StartArray() {
+               Prefix(kArrayType);
+               new (level_stack_.template Push<Level>()) Level(true);
+               WriteStartArray();
+               return *this;
+       }
+
+       Writer& EndArray(SizeType elementCount = 0) {
+               (void)elementCount;
+               RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
+               RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
+               level_stack_.template Pop<Level>(1);
+               WriteEndArray();
+               return *this;
+       }
+       //@}
+
+       //! Simpler but slower overload.
+       Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); }
+
+protected:
+       //! Information for each nested level
+       struct Level {
+               Level(bool inArray_) : inArray(inArray_), valueCount(0) {}
+               bool inArray;           //!< true if in array, otherwise in object
+               size_t valueCount;      //!< number of values in this level
+       };
+
+       static const size_t kDefaultLevelDepth = 32;
+
+       void WriteNull()  {
+               stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l');
+       }
+
+       void WriteBool(bool b)  {
+               if (b) {
+                       stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e');
+               }
+               else {
+                       stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e');
+               }
+       }
+
+       void WriteInt(int i) {
+               if (i < 0) {
+                       stream_.Put('-');
+                       i = -i;
+               }
+               WriteUint((unsigned)i);
+       }
+
+       void WriteUint(unsigned u) {
+               char buffer[10];
+               char *p = buffer;
+               do {
+                       *p++ = (u % 10) + '0';
+                       u /= 10;
+               } while (u > 0);
+
+               do {
+                       --p;
+                       stream_.Put(*p);
+               } while (p != buffer);
+       }
+
+       void WriteInt64(int64_t i64) {
+               if (i64 < 0) {
+                       stream_.Put('-');
+                       i64 = -i64;
+               }
+               WriteUint64((uint64_t)i64);
+       }
+
+       void WriteUint64(uint64_t u64) {
+               char buffer[20];
+               char *p = buffer;
+               do {
+                       *p++ = char(u64 % 10) + '0';
+                       u64 /= 10;
+               } while (u64 > 0);
+
+               do {
+                       --p;
+                       stream_.Put(*p);
+               } while (p != buffer);
+       }
+
+       //! \todo Optimization with custom double-to-string converter.
+       void WriteDouble(double d) {
+               char buffer[100];
+#if _MSC_VER
+               int ret = sprintf_s(buffer, sizeof(buffer), "%g", d);
+#else
+               int ret = snprintf(buffer, sizeof(buffer), "%g", d);
+#endif
+               RAPIDJSON_ASSERT(ret >= 1);
+               for (int i = 0; i < ret; i++)
+                       stream_.Put(buffer[i]);
+       }
+
+       void WriteString(const Ch* str, SizeType length)  {
+               static const char hexDigits[] = "0123456789ABCDEF";
+               static const char escape[256] = {
+#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                       //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
+                       'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
+                       'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
+                         0,   0, '"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20
+                       Z16, Z16,                                                                                                                                               // 30~4F
+                         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\',   0,   0,   0, // 50
+                       Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16                                                                // 60~FF
+#undef Z16
+               };
+
+               stream_.Put('\"');
+               for (const Ch* p = str; p != str + length; ++p) {
+                       if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p])  {
+                               stream_.Put('\\');
+                               stream_.Put(escape[(unsigned char)*p]);
+                               if (escape[(unsigned char)*p] == 'u') {
+                                       stream_.Put('0');
+                                       stream_.Put('0');
+                                       stream_.Put(hexDigits[(*p) >> 4]);
+                                       stream_.Put(hexDigits[(*p) & 0xF]);
+                               }
+                       }
+                       else
+                               stream_.Put(*p);
+               }
+               stream_.Put('\"');
+       }
+
+       void WriteStartObject() { stream_.Put('{'); }
+       void WriteEndObject()   { stream_.Put('}'); }
+       void WriteStartArray()  { stream_.Put('['); }
+       void WriteEndArray()    { stream_.Put(']'); }
+
+       void Prefix(Type type) {
+               (void)type;
+               if (level_stack_.GetSize() != 0) { // this value is not at root
+                       Level* level = level_stack_.template Top<Level>();
+                       if (level->valueCount > 0) {
+                               if (level->inArray) 
+                                       stream_.Put(','); // add comma if it is not the first element in array
+                               else  // in object
+                                       stream_.Put((level->valueCount % 2 == 0) ? ',' : ':');
+                       }
+                       if (!level->inArray && level->valueCount % 2 == 0)
+                               RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name
+                       level->valueCount++;
+               }
+               else
+                       RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
+       }
+
+       Stream& stream_;
+       internal::Stack<Allocator> level_stack_;
+
+private:
+       // Prohibit assignment for VC C4512 warning
+       Writer& operator=(const Writer& w);
+};
+
+} // namespace rapidjson
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // RAPIDJSON_RAPIDJSON_H_
index fba5ec225b62c1e164489491b9da77c0c22f5394..03d97d163edb9e0391709918f2ccc1ae2407d044 100644 (file)
@@ -1,19 +1,19 @@
-Copyright (C) 2011 Milo Yip\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy\r
-of this software and associated documentation files (the "Software"), to deal\r
-in the Software without restriction, including without limitation the rights\r
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-copies of the Software, and to permit persons to whom the Software is\r
-furnished to do so, subject to the following conditions:\r
-\r
-The above copyright notice and this permission notice shall be included in\r
-all copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+Copyright (C) 2011 Milo Yip
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
\ No newline at end of file