Browse Source

Add JSON support in Urho3D.

aster2013 11 years ago
parent
commit
460da659ee

+ 1 - 1
Source/Engine/Resource/CMakeLists.txt

@@ -24,4 +24,4 @@
 define_source_files (PARENT_SCOPE)
 define_source_files (PARENT_SCOPE)
 
 
 # Define dependency libs
 # Define dependency libs
-set (ENGINE_INCLUDE_DIRS_ONLY ${ENGINE_INCLUDE_DIRS_ONLY} ../ThirdParty/JO ../ThirdParty/PugiXml/src ../ThirdParty/STB PARENT_SCOPE)
+set (ENGINE_INCLUDE_DIRS_ONLY ${ENGINE_INCLUDE_DIRS_ONLY} ../ThirdParty/JO ../ThirdParty/rapidjson/include ../ThirdParty/PugiXml/src ../ThirdParty/STB PARENT_SCOPE)

+ 124 - 0
Source/Engine/Resource/JSONFile.cpp

@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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.
+//
+
+#include "Precompiled.h"
+#include "ArrayPtr.h"
+#include "Context.h"
+#include "Deserializer.h"
+#include "JSONFile.h"
+#include "Log.h"
+#include "Profiler.h"
+#include "ResourceCache.h"
+#include "Serializer.h"
+#include <rapidjson/document.h>
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/prettywriter.h>
+
+#include "DebugNew.h"
+
+using namespace rapidjson;
+
+namespace Urho3D
+{
+
+JSONFile::JSONFile(Context* context) :
+    Resource(context),
+    document_(new Document())
+{
+}
+
+JSONFile::~JSONFile()
+{
+    delete document_;
+    document_ = 0;
+}
+
+void JSONFile::RegisterObject(Context* context)
+{
+    context->RegisterFactory<JSONFile>();
+}
+
+bool JSONFile::Load(Deserializer& source)
+{
+    PROFILE(LoadJSONFile);
+
+    unsigned dataSize = source.GetSize();
+    if (!dataSize && !source.GetName().Empty())
+    {
+        LOGERROR("Zero sized JSON data in " + source.GetName());
+        return false;
+    }
+
+    SharedArrayPtr<char> buffer(new char[dataSize + 1]);
+    if (source.Read(buffer.Get(), dataSize) != dataSize)
+        return false;
+    buffer[dataSize] = '\0';
+
+    if (document_->Parse<0>(buffer).HasParseError())
+    {
+        LOGERROR("Could not parse JOSO data from " + source.GetName());
+        return false;
+    }
+
+    SetMemoryUse(dataSize);
+
+    return true;
+}
+
+bool JSONFile::Save(Serializer& dest) const
+{
+    StringBuffer buffer;
+    PrettyWriter<StringBuffer> writer(buffer, &(document_->GetAllocator()));
+    writer.SetIndent('\t', 1);
+
+    document_->Accept(writer);
+    dest.Write(buffer.GetString(), buffer.GetSize());
+
+    return true;
+}
+
+JSONValue JSONFile::CreateRoot(JSONValueType valueType)
+{
+    if (valueType == JVT_OBJECT)
+        document_->SetObject();
+    else
+        document_->SetArray();
+
+    return JSONValue(this, document_);
+}
+
+JSONValue JSONFile::GetRoot(JSONValueType valueType)
+{
+    if (!document_)
+        return JSONValue::EMPTY;
+
+    if ((valueType == JVT_OBJECT && document_->GetType() != kObjectType) ||
+        (valueType == JVT_ARRAY && document_->GetType() != kArrayType))
+    {
+        LOGERROR("Invalid root value type");
+        return JSONValue::EMPTY;
+    }
+
+    return JSONValue(this, document_);
+}
+
+}

+ 68 - 0
Source/Engine/Resource/JSONFile.h

@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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.
+//
+
+#pragma once
+
+#include "Resource.h"
+#include "JSONValue.h"
+
+namespace rapidjson
+{
+    template <typename Encoding, typename Allocator> class GenericDocument;
+    typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Document;
+}
+
+namespace Urho3D
+{
+
+/// JSON document resource.
+class URHO3D_API JSONFile : public Resource
+{
+    OBJECT(JSONFile);
+
+public:
+    /// Construct.
+    JSONFile(Context* context);
+    /// Destruct.
+    virtual ~JSONFile();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Load resource. Return true if successful.
+    virtual bool Load(Deserializer& source);
+    /// Save resource. Return true if successful. Only supports saving to a File.
+    virtual bool Save(Serializer& dest) const;
+
+    /// Clear the document and create a root value, default is object type.
+    JSONValue CreateRoot(JSONValueType valueType = JVT_OBJECT);
+    /// Return the root value with specific value type, Return null value if not found.
+    JSONValue GetRoot(JSONValueType valueType = JVT_UNKNOWN);
+
+    /// Return rapidjson document.
+    rapidjson::Document* GetDocument() const { return document_; }
+
+private:
+    /// Rapid JSON document.
+    rapidjson::Document* document_;
+};
+
+}

+ 815 - 0
Source/Engine/Resource/JSONValue.cpp

@@ -0,0 +1,815 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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:addmember
+//
+// 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.
+//
+
+#include "Precompiled.h"
+#include "Context.h"
+#include "Log.h"
+#include "JSONFile.h"
+
+#include <rapidjson/document.h>
+
+#include "DebugNew.h"
+
+using namespace rapidjson;
+
+namespace Urho3D
+{
+
+const JSONValue JSONValue::EMPTY;
+
+static rapidjson::Type ToRapidJsonType(JSONValueType valueType)
+{
+    if (valueType == JVT_OBJECT)
+        return kObjectType;
+    else if (valueType == JVT_ARRAY)
+        return kArrayType;
+    return kNullType;
+}
+
+JSONValue::JSONValue() :
+    file_(0),
+    value_(0)
+{
+}
+
+JSONValue::JSONValue(JSONFile* file, rapidjson::Value* value) :
+    file_(file),
+    value_(value)
+{
+}
+
+JSONValue::JSONValue(const JSONValue& rhs) :
+    file_(rhs.file_),
+    value_(rhs.value_)
+{
+}
+
+JSONValue::~JSONValue()
+{
+}
+
+JSONValue& JSONValue::operator = (const JSONValue& rhs)
+{
+    file_ = rhs.file_;
+    value_ = rhs.value_;
+    return *this;
+}
+
+bool JSONValue::IsNull() const
+{
+    return value_ == 0;
+}
+
+bool JSONValue::NotNull() const
+{
+    return value_ != 0;
+}
+
+JSONValue::operator bool() const
+{
+    return NotNull();
+}
+
+JSONValue JSONValue::CreateChild(const String& name, JSONValueType valueType)
+{
+    assert(IsObject());
+    if (!IsObject())
+        return JSONValue::EMPTY;
+
+    Value jsonValue;
+    if (valueType == JVT_OBJECT)
+        jsonValue.SetObject();
+    else if (valueType == JVT_ARRAY)
+        jsonValue.SetArray();
+
+    AddMember(name, jsonValue);
+
+    return GetChild(name, valueType);
+}
+
+JSONValue JSONValue::GetChild(const String& name, JSONValueType valueType) const
+{
+    assert(IsObject());
+
+    if (!value_->HasMember(name.CString()))
+        return JSONValue::EMPTY;
+
+    Value& value = GetMember(name);
+    if (valueType != JVT_UNKNOWN && value.GetType() != ToRapidJsonType(valueType))
+        return JSONValue::EMPTY;
+
+    return JSONValue(file_, &value);
+}
+
+void JSONValue::SetInt(const String& name, int value)
+{
+    Value jsonValue;
+    jsonValue.SetInt(value);
+    AddMember(name, jsonValue);
+}
+
+void JSONValue::SetBool(const String& name, bool value)
+{
+    Value jsonValue;
+    jsonValue.SetBool(value);
+    AddMember(name, jsonValue);
+}
+
+void JSONValue::SetFloat(const String& name, float value)
+{
+    Value jsonValue;
+    jsonValue.SetDouble((double)value);
+    AddMember(name, jsonValue);
+}
+
+void JSONValue::SetVector2(const String& name, const Vector2& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetVector3(const String& name, const Vector3& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetVector4(const String& name, const Vector4& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetVectorVariant(const String& name, const Variant& value)
+{
+    VariantType type = value.GetType();
+    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4 || type == VAR_MATRIX3 ||
+        type == VAR_MATRIX3X4 || type == VAR_MATRIX4)
+        SetString(name, value.ToString());
+}
+
+void JSONValue::SetQuaternion(const String& name, const Quaternion& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetColor(const String& name, const Color& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetString(const String& name, const String& value)
+{
+    Value jsonValue;
+    jsonValue.SetString(value.CString(), value.Length(), file_->GetDocument()->GetAllocator());
+    AddMember(name, jsonValue);
+}
+
+void JSONValue::SetBuffer(const String& name, const void* data, unsigned size)
+{
+    String dataStr;
+    BufferToString(dataStr, data, size);
+    SetString(name, dataStr);
+}
+
+void JSONValue::SetBuffer(const String& name, const PODVector<unsigned char>& value)
+{
+    if (!value.Size())
+        SetString(name, String::EMPTY);
+    else
+        SetBuffer(name, &value[0], value.Size());
+}
+
+void JSONValue::SetResourceRef(const String& name, const ResourceRef& value)
+{
+    Context* context = file_->GetContext();
+    SetString(name, String(context->GetTypeName(value.type_)) + ";" + value.name_);
+}
+
+void JSONValue::SetResourceRefList(const String& name, const ResourceRefList& value)
+{
+    Context* context = file_->GetContext();
+    String str(context->GetTypeName(value.type_));
+    for (unsigned i = 0; i < value.names_.Size(); ++i)
+    {
+        str += ";";
+        str += value.names_[i];
+    }
+    SetString(name, str);
+}
+
+void JSONValue::SetIntRect(const String& name, const IntRect& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetIntVector2(const String& name, const IntVector2& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetMatrix3(const String& name, const Matrix3& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetMatrix3x4(const String& name, const Matrix3x4& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetMatrix4(const String& name, const Matrix4& value)
+{
+    SetString(name, value.ToString());
+}
+
+void JSONValue::SetVariant(const String& name, const Variant& value)
+{
+    // Create child object for variant
+    JSONValue child = CreateChild(name, JVT_OBJECT);
+    // Set type
+    child.SetString("type", value.GetTypeName());
+    // Set value
+    child.SetVariantValue("value", value);
+}
+
+void JSONValue::SetVariantValue(const String& name, const Variant& value)
+{
+    switch (value.GetType())
+    {
+    case VAR_RESOURCEREF:
+        SetResourceRef(name, value.GetResourceRef());
+        break;
+
+    case VAR_RESOURCEREFLIST:
+        SetResourceRefList(name, value.GetResourceRefList());
+        break;
+
+    case VAR_VARIANTVECTOR:
+    case VAR_VARIANTMAP:
+        LOGERROR("Unsupported value type");
+        break;
+
+    default:
+        SetString(name, value.ToString());
+    }
+}
+
+bool JSONValue::IsObject() const
+{
+    return value_ && value_->IsObject();
+}
+
+int JSONValue::GetInt(const String& name) const
+{
+    return GetMember(name).GetInt();
+}
+
+bool JSONValue::GetBool(const String& name) const
+{
+    return GetMember(name).GetBool();
+}
+
+float JSONValue::GetFloat(const String& name) const
+{
+    return (float)GetMember(name).GetDouble();
+}
+
+Vector2 JSONValue::GetVector2(const String& name) const
+{
+    return ToVector2(GetCString(name));
+}
+
+Vector3 JSONValue::GetVector3(const String& name) const
+{
+    return ToVector3(GetCString(name));
+}
+
+Vector4 JSONValue::GetVector4(const String& name) const
+{
+    return ToVector4(GetCString(name));
+}
+
+Variant JSONValue::GetVectorVariant(const String& name) const
+{
+    return ToVectorVariant(GetCString(name));
+}
+
+Quaternion JSONValue::GetQuaternion(const String& name) const
+{
+    return ToQuaternion(GetCString(name));
+}
+
+Color JSONValue::GetColor(const String& name) const
+{
+    return ToColor(GetCString(name));
+}
+
+String JSONValue::GetString(const String& name) const
+{
+    return GetMember(name).GetString();
+}
+
+const char* JSONValue::GetCString(const String& name) const
+{
+    return GetMember(name).GetString();
+}
+
+PODVector<unsigned char> JSONValue::GetBuffer(const String& name) const
+{
+    PODVector<unsigned char> buffer;
+    StringToBuffer(buffer, GetCString(name));
+    return buffer;
+}
+
+bool JSONValue::GetBuffer(const String& name, void* dest, unsigned size) const
+{
+    Vector<String> bytes = GetString(name).Split(' ');
+    unsigned char* destBytes = (unsigned char*)dest;
+    if (size < bytes.Size())
+        return false;
+
+    for (unsigned i = 0; i < bytes.Size(); ++i)
+        destBytes[i] = ToInt(bytes[i]);
+    return true;
+}
+
+
+ResourceRef JSONValue::GetResourceRef(const String& name) const
+{
+    ResourceRef ret;
+
+    Vector<String> values = GetString(name).Split(';');
+    if (values.Size() == 2)
+    {
+        ret.type_ = values[0];
+        ret.name_ = values[1];
+    }
+
+    return ret;
+}
+
+ResourceRefList JSONValue::GetResourceRefList(const String& name) const
+{
+    ResourceRefList ret;
+
+    Vector<String> values = GetString(name).Split(';');
+    if (values.Size() >= 1)
+    {
+        ret.type_ = values[0];
+        ret.names_.Resize(values.Size() - 1);
+        for (unsigned i = 1; i < values.Size(); ++i)
+            ret.names_[i - 1] = values[i];
+    }
+
+    return ret;
+}
+
+IntRect JSONValue::GetIntRect(const String& name) const
+{
+    return ToIntRect(GetCString(name));
+}
+
+IntVector2 JSONValue::GetIntVector2(const String& name) const
+{
+    return ToIntVector2(GetCString(name));
+}
+
+Matrix3 JSONValue::GetMatrix3(const String& name) const
+{
+    return ToMatrix3(GetCString(name));
+}
+
+Matrix3x4 JSONValue::GetMatrix3x4(const String& name) const
+{
+    return ToMatrix3x4(GetCString(name));
+}
+
+Matrix4 JSONValue::GetMatrix4(const String& name) const
+{
+    return ToMatrix4(GetCString(name));
+}
+
+Variant JSONValue::GetVariant(const String& name) const
+{
+    // Get child for variant
+    JSONValue child = GetChild(name, JVT_OBJECT);
+    if (child.IsNull())
+        return Variant::EMPTY;
+
+    // Get type
+    VariantType type = Variant::GetTypeFromName(child.GetString("type"));
+    // Get value
+    return child.GetVariantValue("value", type);
+}
+
+Variant JSONValue::GetVariantValue(const String& name, VariantType type) const
+{
+    Variant ret;
+
+    if (type == VAR_RESOURCEREF)
+        ret = GetResourceRef(name);
+    else if (type == VAR_RESOURCEREFLIST)
+        ret = GetResourceRefList(name);
+    else if (type == VAR_VARIANTVECTOR || type == VAR_VARIANTMAP)
+        LOGERROR("Unsupported value type");
+    else
+        ret.FromString(type, GetCString(name));
+
+    return ret;
+}
+
+JSONValue JSONValue::CreateChild(JSONValueType valueType)
+{
+    assert(IsArray());
+    if (!IsArray())
+        return JSONValue::EMPTY;
+
+    Value value(ToRapidJsonType(valueType));
+    value_->PushBack(value, file_->GetDocument()->GetAllocator());
+
+    return GetChild(GetSize() - 1, valueType);
+}
+
+JSONValue JSONValue::GetChild(unsigned index, JSONValueType valueType) const
+{
+    if (index >= GetSize())
+        return JSONValue::EMPTY;
+
+    const Value& value = (*value_)[(SizeType)index];
+    if (valueType != JVT_UNKNOWN && value.GetType() != ToRapidJsonType(valueType))
+        return JSONValue::EMPTY;
+
+    return JSONValue(file_, (Value*)&value);
+}
+
+void JSONValue::PushInt(int value)
+{
+    Value jsonValue;
+    jsonValue.SetInt(value);
+    PushMember(jsonValue);
+}
+
+void JSONValue::PushBool(bool value)
+{
+    Value jsonValue;
+    jsonValue.SetBool(value);
+    PushMember(jsonValue);
+}
+
+void JSONValue::PushFloat(float value)
+{
+    Value jsonValue;
+    jsonValue.SetDouble((double)value);
+    PushMember(jsonValue);
+}
+
+void JSONValue::PushVector2(const Vector2& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushVector3(const Vector3& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushVector4(const Vector4& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushVectorVariant(const Variant& value)
+{
+    VariantType type = value.GetType();
+    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4 || type == VAR_MATRIX3 ||
+        type == VAR_MATRIX3X4 || type == VAR_MATRIX4)
+        PushString(value.ToString());
+}
+
+void JSONValue::PushQuaternion(const Quaternion& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushColor(const Color& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushString(const String& value)
+{
+    Value jsonValue;
+    jsonValue.SetString(value.CString(), value.Length(), file_->GetDocument()->GetAllocator());
+    PushMember(jsonValue);
+}
+
+void JSONValue::PushBuffer(const PODVector<unsigned char>& value)
+{
+    if (!value.Size())
+        PushString(String::EMPTY);
+    else
+        PushBuffer(&value[0], value.Size());
+}
+
+void JSONValue::PushBuffer(const void* data, unsigned size)
+{
+    String dataStr;
+    BufferToString(dataStr, data, size);
+    PushString(dataStr);
+}
+
+void JSONValue::PushResourceRef(const ResourceRef& value)
+{
+    Context* context = file_->GetContext();
+    PushString(String(context->GetTypeName(value.type_)) + ";" + value.name_);
+}
+
+void JSONValue::PushResourceRefList(const ResourceRefList& value)
+{
+    Context* context = file_->GetContext();
+    String str(context->GetTypeName(value.type_));
+    for (unsigned i = 0; i < value.names_.Size(); ++i)
+    {
+        str += ";";
+        str += value.names_[i];
+    }
+    PushString(str);
+}
+
+void JSONValue::PushIntRect(const IntRect& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushIntVector2(const IntVector2& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushMatrix3(const Matrix3& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushMatrix3x4(const Matrix3x4& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushMatrix4(const Matrix4& value)
+{
+    PushString(value.ToString());
+}
+
+void JSONValue::PushVariant(const Variant& value)
+{
+    // Create child object for variant
+    JSONValue child = CreateChild(JVT_OBJECT);
+    // Set type
+    child.SetString("type", value.GetTypeName());
+    // Set value
+    child.SetVariantValue("value", value);
+}
+
+void JSONValue::PushVariantValue(const Variant& value)
+{
+    switch (value.GetType())
+    {
+    case VAR_RESOURCEREF:
+        PushResourceRef(value.GetResourceRef());
+        break;
+
+    case VAR_RESOURCEREFLIST:
+        PushResourceRefList(value.GetResourceRefList());
+        break;
+
+    case VAR_VARIANTVECTOR:
+    case VAR_VARIANTMAP:
+        LOGERROR("Unsupported value type");
+        break;
+
+    default:
+        PushString(value.ToString());
+    }
+}
+
+unsigned JSONValue::GetSize() const
+{
+    if (IsArray())
+        return (unsigned)value_->Size();
+    else
+        return 0;
+}
+
+bool JSONValue::IsArray() const
+{
+    return value_ && value_->IsArray();
+}
+
+int JSONValue::GetInt(unsigned index) const
+{
+    return GetMember(index).GetInt();
+}
+
+bool JSONValue::GetBool(unsigned index) const
+{
+    return GetMember(index).GetBool();
+}
+
+float JSONValue::GetFloat(unsigned index) const
+{
+    return (float)GetMember(index).GetDouble();
+}
+
+Vector2 JSONValue::GetVector2(unsigned index) const
+{
+    return ToVector2(GetCString(index));
+}
+
+Vector3 JSONValue::GetVector3(unsigned index) const
+{
+    return ToVector3(GetCString(index));
+}
+
+Vector4 JSONValue::GetVector4(unsigned index) const
+{
+    return ToVector4(GetCString(index));
+}
+
+Variant JSONValue::GetVectorVariant(unsigned index) const
+{
+    return ToVectorVariant(GetCString(index));
+}
+
+Quaternion JSONValue::GetQuaternion(unsigned index) const
+{
+    return ToQuaternion(GetCString(index));
+}
+
+Color JSONValue::GetColor(unsigned index) const
+{
+    return ToColor(GetCString(index));
+}
+
+String JSONValue::GetString(unsigned index) const
+{
+    return GetMember(index).GetString();
+}
+
+const char* JSONValue::GetCString(unsigned index) const
+{
+    return GetMember(index).GetString();
+}
+
+PODVector<unsigned char> JSONValue::GetBuffer(unsigned index) const
+{
+    PODVector<unsigned char> buffer;
+    StringToBuffer(buffer, GetCString(index));
+    return buffer;
+}
+
+bool JSONValue::GetBuffer(unsigned index, void* dest, unsigned size) const
+{
+    Vector<String> bytes = GetString(index).Split(' ');
+    unsigned char* destBytes = (unsigned char*)dest;
+    if (size < bytes.Size())
+        return false;
+
+    for (unsigned i = 0; i < bytes.Size(); ++i)
+        destBytes[i] = ToInt(bytes[i]);
+    return true;
+}
+
+ResourceRef JSONValue::GetResourceRef(unsigned index) const
+{
+    ResourceRef ret;
+
+    Vector<String> values = GetString(index).Split(';');
+    if (values.Size() == 2)
+    {
+        ret.type_ = values[0];
+        ret.name_ = values[1];
+    }
+
+    return ret;
+}
+
+ResourceRefList JSONValue::GetResourceRefList(unsigned index) const
+{
+    ResourceRefList ret;
+
+    Vector<String> values = GetString(index).Split(';');
+    if (values.Size() >= 1)
+    {
+        ret.type_ = values[0];
+        ret.names_.Resize(values.Size() - 1);
+        for (unsigned i = 1; i < values.Size(); ++i)
+            ret.names_[i - 1] = values[i];
+    }
+
+    return ret;
+}
+
+IntRect JSONValue::GetIntRect(unsigned index) const
+{
+    return ToIntRect(GetCString(index));
+}
+
+IntVector2 JSONValue::GetIntVector2(unsigned index) const
+{
+    return ToIntVector2(GetCString(index));
+}
+
+Matrix3 JSONValue::GetMatrix3(unsigned index) const
+{
+    return ToMatrix3(GetCString(index));
+}
+
+Matrix3x4 JSONValue::GetMatrix3x4(unsigned index) const
+{
+    return ToMatrix3x4(GetCString(index));
+}
+
+Matrix4 JSONValue::GetMatrix4(unsigned index) const
+{
+    return ToMatrix4(GetCString(index));
+}
+
+Variant JSONValue::GetVariant(unsigned index) const
+{
+    // Get child for variant
+    JSONValue child = GetChild(index, JVT_OBJECT);
+    if (child.IsNull())
+        return Variant::EMPTY;
+
+    // Get type
+    VariantType type = Variant::GetTypeFromName(child.GetString("type"));
+    // Get value
+    return child.GetVariantValue("value", type);
+}
+
+Variant JSONValue::GetVariantValue(unsigned index, VariantType type) const
+{
+    Variant ret;
+
+    if (type == VAR_RESOURCEREF)
+        ret = GetResourceRef(index);
+    else if (type == VAR_RESOURCEREFLIST)
+        ret = GetResourceRefList(index);
+    else if (type == VAR_VARIANTVECTOR || type == VAR_VARIANTMAP)
+        LOGERROR("Unsupported value type");
+    else
+        ret.FromString(type, GetCString(index));
+
+    return ret;
+}
+
+void JSONValue::AddMember(const String& name, rapidjson::Value& jsonValue)
+{
+    if (!IsObject())
+        return;
+
+    Value jsonName;
+    jsonName.SetString(name.CString(), name.Length(), file_->GetDocument()->GetAllocator());
+    value_->AddMember(jsonName, jsonValue, file_->GetDocument()->GetAllocator());
+}
+
+rapidjson::Value& JSONValue::GetMember(const String& name) const
+{
+    assert(IsObject());
+
+    return (*value_)[name.CString()];
+}
+
+void JSONValue::PushMember(rapidjson::Value& jsonValue)
+{
+    assert(IsArray());
+
+    value_->PushBack(jsonValue, file_->GetDocument()->GetAllocator());
+}
+
+rapidjson::Value& JSONValue::GetMember(unsigned index) const
+{
+    assert(IsArray());
+
+    return (*value_)[(SizeType)index];
+}
+
+}

+ 288 - 0
Source/Engine/Resource/JSONValue.h

@@ -0,0 +1,288 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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.
+//
+
+#pragma once
+
+#include "BoundingBox.h"
+#include "Rect.h"
+#include "Ptr.h"
+#include "Variant.h"
+
+namespace rapidjson
+{
+    template<typename CharType> struct UTF8;
+    class CrtAllocator;
+    template <typename BaseAllocator> class MemoryPoolAllocator;
+    template <typename Encoding, typename Allocator> class GenericValue;
+    typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
+}
+
+namespace Urho3D
+{
+
+class JSONFile;
+
+/// JSON value type.
+enum JSONValueType
+{
+    /// Object type (Hash Map).
+    JVT_OBJECT = 0,
+    /// Array type.
+    JVT_ARRAY,
+    /// Unknown type.
+    JVT_UNKNOWN,
+};
+
+/// JSON value class.
+class URHO3D_API JSONValue
+{
+public:
+    /// Construct null value.
+    JSONValue();
+    /// Construct with document and JSON value pointers.
+    JSONValue(JSONFile* file, rapidjson::Value* value);
+    /// Copy-construct from another value.
+    JSONValue(const JSONValue& rhs);
+    /// Destruct.
+    ~JSONValue();
+
+    /// Assignment operator.
+    JSONValue& operator = (const JSONValue& rhs);
+
+    /// Return whether does not refer to JSON value.
+    bool IsNull() const;
+    /// Return whether refers to JSON value.
+    bool NotNull() const;
+    /// Return true if refers to JSON value.
+    operator bool () const;
+
+    // JSON object value functions
+    /// Create a child value.
+    JSONValue CreateChild(const String& name, JSONValueType valueType = JVT_OBJECT);
+    /// Return a child value by name. Return null if not exist.
+    JSONValue GetChild(const String& name, JSONValueType valueType = JVT_UNKNOWN) const;
+    /// Set int.
+    void SetInt(const String& name, int value);
+    /// Set bool.
+    void SetBool(const String& name, bool value);
+    /// Set float.
+    void SetFloat(const String& name, float value);
+    /// Set vector2.
+    void SetVector2(const String& name, const Vector2& value);
+    /// Set vector3.
+    void SetVector3(const String& name, const Vector3& value);
+    /// Set vector4.
+    void SetVector4(const String& name, const Vector4& value);
+    /// Set vector variant.
+    void SetVectorVariant(const String& name, const Variant& value);
+    /// Set quaternion.
+    void SetQuaternion(const String& name, const Quaternion& value);
+    /// Set color.
+    void SetColor(const String& name, const Color& value);
+    /// Set string.
+    void SetString(const String& name, const String& value);
+    /// Set buffer.
+    void SetBuffer(const String& name, const void* data, unsigned size);
+    /// Set buffer.
+    void SetBuffer(const String& name, const PODVector<unsigned char>& value);
+    /// Set resource ref.
+    void SetResourceRef(const String& name, const ResourceRef& value);
+    /// Set resource ref list.
+    void SetResourceRefList(const String& name, const ResourceRefList& value);
+    /// Set int rect.
+    void SetIntRect(const String& name, const IntRect& value);
+    /// Set int vector2.
+    void SetIntVector2(const String& name, const IntVector2& value);
+    /// Set matrix3.
+    void SetMatrix3(const String& name, const Matrix3& value);
+    /// Set matrix3x4.
+    void SetMatrix3x4(const String& name, const Matrix3x4& value);
+    /// Set matrix4.
+    void SetMatrix4(const String& name, const Matrix4& value);
+    /// Set variant (include type).
+    void SetVariant(const String& name, const Variant& value);
+    /// Set variant value.
+    void SetVariantValue(const String& name, const Variant& value);
+
+    /// Is object type.
+    bool IsObject() const;
+    /// Return int.
+    int GetInt(const String& name) const;
+    /// Return bool.
+    bool GetBool(const String& name) const;
+    /// Return float.
+    float GetFloat(const String& name) const;
+    /// Return vector2.
+    Vector2 GetVector2(const String& name) const;
+    /// Return vector3.
+    Vector3 GetVector3(const String& name) const;
+    /// Return vector4.
+    Vector4 GetVector4(const String& name) const;
+    /// Return vector variant.
+    Variant GetVectorVariant(const String& name) const;
+    /// Return quaternion.
+    Quaternion GetQuaternion(const String& name) const;
+    /// Return color.
+    Color GetColor(const String& name) const;
+    /// Return string.
+    String GetString(const String& name) const;
+    /// Return C string.
+    const char* GetCString(const String& name) const;
+    /// Return buffer.
+    PODVector<unsigned char> GetBuffer(const String& name) const;
+    /// Return buffer.
+    bool GetBuffer(const String& name, void* dest, unsigned size) const;
+    /// Return resource ref.
+    ResourceRef GetResourceRef(const String& name) const;
+    /// Return resource ref list.
+    ResourceRefList GetResourceRefList(const String& name) const;
+    /// Return int rect.
+    IntRect GetIntRect(const String& name) const;
+    /// Return int vector2.
+    IntVector2 GetIntVector2(const String& name) const;
+    /// Return matrix3.
+    Matrix3 GetMatrix3(const String& name) const;
+    /// Return matrix3x4.
+    Matrix3x4 GetMatrix3x4(const String& name) const;
+    /// Return matrix4.
+    Matrix4 GetMatrix4(const String& name) const;
+    /// Return variant.
+    Variant GetVariant(const String& name) const;
+    /// Return variant value.
+    Variant GetVariantValue(const String& name, VariantType type) const;
+
+    // JSON array value functions
+    /// Create a child value in array.
+    JSONValue CreateChild(JSONValueType valueType = JVT_OBJECT);
+    /// Remove a child value in array. Return null if not exist.
+    JSONValue GetChild(unsigned index, JSONValueType valueType = JVT_UNKNOWN) const;
+    /// Push int.
+    void PushInt(int value);
+    /// Push bool.
+    void PushBool(bool value);
+    /// Push float.
+    void PushFloat(float value);
+    /// Push vector2.
+    void PushVector2(const Vector2& value);
+    /// Push vector3.
+    void PushVector3(const Vector3& value);
+    /// Push vector4.
+    void PushVector4(const Vector4& value);
+    /// Push vector variant.
+    void PushVectorVariant(const Variant& value);
+    /// Push quaternion.
+    void PushQuaternion(const Quaternion& value);
+    /// Push color.
+    void PushColor(const Color& value);
+    /// Push string.
+    void PushString(const String& value);
+    /// Push buffer.
+    void PushBuffer(const PODVector<unsigned char>& value);
+    /// Push buffer.
+    void PushBuffer(const void* data, unsigned size);
+    /// Push resource ref.
+    void PushResourceRef(const ResourceRef& value);
+    /// Push resource ref list.
+    void PushResourceRefList(const ResourceRefList& value);
+    /// Push int rect.
+    void PushIntRect(const IntRect& value);
+    /// Push int vector2.
+    void PushIntVector2(const IntVector2& value);
+    /// Push matrix3.
+    void PushMatrix3(const Matrix3& value);
+    /// Push matrix3x4.
+    void PushMatrix3x4(const Matrix3x4& value);
+    /// Push matrix4.
+    void PushMatrix4(const Matrix4& value);
+    /// Push variant.
+    void PushVariant(const Variant& value);
+    /// Push variant value.
+    void PushVariantValue(const Variant& value);
+    /// Is array type.
+    bool IsArray() const;
+    /// Return array size.
+    unsigned GetSize() const;
+    /// Return int.
+    int GetInt(unsigned index) const;
+    /// Return bool.
+    bool GetBool(unsigned index) const;
+    /// Return float.
+    float GetFloat(unsigned index) const;
+    /// Return vector2.
+    Vector2 GetVector2(unsigned index) const;
+    /// Return vector3.
+    Vector3 GetVector3(unsigned index) const;
+    /// Return vector4.
+    Vector4 GetVector4(unsigned index) const;
+    /// Return vector variant.
+    Variant GetVectorVariant(unsigned index) const;
+    /// Return quaternion.
+    Quaternion GetQuaternion(unsigned index) const;
+    /// Return color.
+    Color GetColor(unsigned index) const;
+    /// Return string.
+    String GetString(unsigned index) const;
+    /// Return C string.
+    const char* GetCString(unsigned index) const;
+    /// Return buffer.
+    PODVector<unsigned char> GetBuffer(unsigned index) const;
+    /// Return buffer.
+    bool GetBuffer(unsigned index, void* dest, unsigned size) const;
+    /// Return resource ref.
+    ResourceRef GetResourceRef(unsigned index) const;
+    /// Return resource ref list.
+    ResourceRefList GetResourceRefList(unsigned index) const;
+    /// Return int rect.
+    IntRect GetIntRect(unsigned index) const;
+    /// Return int vector2.
+    IntVector2 GetIntVector2(unsigned index) const;
+    /// Return matrix3.
+    Matrix3 GetMatrix3(unsigned index) const;
+    /// Return matrix3x4.
+    Matrix3x4 GetMatrix3x4(unsigned index) const;
+    /// Return matrix4.
+    Matrix4 GetMatrix4(unsigned index) const;
+    /// Return variant.
+    Variant GetVariant(unsigned index) const;
+    /// Return variant.
+    Variant GetVariantValue(unsigned index, VariantType type) const;
+    
+    /// Empty JSONValue.
+    static const JSONValue EMPTY;
+
+private:
+    /// Set JSON value for object type.
+    void AddMember(const String& name, rapidjson::Value& jsonValue);
+    /// Return JSON value by name for object type.
+    rapidjson::Value& GetMember(const String& name) const;
+    /// Push JSON value to array type.
+    void PushMember(rapidjson::Value& jsonValue);
+    /// Return JSON value by index for array type.
+    rapidjson::Value&  GetMember(unsigned index) const;
+
+    /// JSON file.
+    WeakPtr<JSONFile> file_;
+    /// Rapid JSON value.
+    rapidjson::Value* value_;
+};
+
+}

+ 2 - 0
Source/Engine/Resource/ResourceCache.cpp

@@ -26,6 +26,7 @@
 #include "FileSystem.h"
 #include "FileSystem.h"
 #include "FileWatcher.h"
 #include "FileWatcher.h"
 #include "Image.h"
 #include "Image.h"
+#include "JSONFile.h"
 #include "Log.h"
 #include "Log.h"
 #include "PackageFile.h"
 #include "PackageFile.h"
 #include "ResourceCache.h"
 #include "ResourceCache.h"
@@ -854,6 +855,7 @@ File* ResourceCache::SearchPackages(const String& nameIn)
 void RegisterResourceLibrary(Context* context)
 void RegisterResourceLibrary(Context* context)
 {
 {
     Image::RegisterObject(context);
     Image::RegisterObject(context);
+    JSONFile::RegisterObject(context);
     XMLFile::RegisterObject(context);
     XMLFile::RegisterObject(context);
 }
 }
 
 

+ 221 - 0
Source/ThirdParty/rapidjson/include/rapidjson/allocators.h

@@ -0,0 +1,221 @@
+#ifndef RAPIDJSON_ALLOCATORS_H_
+#define RAPIDJSON_ALLOCATORS_H_
+
+#include "rapidjson.h"
+
+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 = RAPIDJSON_ALIGN(size);
+		if (chunkHead_->size + size > chunkHead_->capacity)
+			AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
+
+		char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;
+		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 = RAPIDJSON_ALIGN(increment);
+			if (chunkHead_->size + increment <= chunkHead_->capacity) {
+				chunkHead_->size += increment;
+				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 *ptr) { (void)ptr; } // 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.
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_ENCODINGS_H_

+ 843 - 0
Source/ThirdParty/rapidjson/include/rapidjson/document.h

@@ -0,0 +1,843 @@
+#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 name.
+	/*!
+		\note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
+		Since 0.2, if the name is not correct, it will assert.
+		If user is unsure whether a member exists, user should use HasMember() first.
+		A better approach is to use the now public FindMember().
+	*/
+	GenericValue& operator[](const Ch* name) {
+		if (Member* member = FindMember(name))
+			return member->value;
+		else {
+			RAPIDJSON_ASSERT(false);	// see above note
+			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.
+	/*!
+		\note It is better to use FindMember() directly if you need the obtain the value as well.
+	*/
+	bool HasMember(const Ch* name) const { return FindMember(name) != 0; }
+
+	//! Find member by name.
+	/*!
+		\return Return the member if exists. Otherwise returns null pointer.
+	*/
+	Member* FindMember(const Ch* name) {
+		RAPIDJSON_ASSERT(name);
+		RAPIDJSON_ASSERT(IsObject());
+
+		Object& o = data_.o;
+		for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member)
+			if (name[member->name.data_.s.length] == '\0' && memcmp(member->name.data_.s.str, name, member->name.data_.s.length * sizeof(Ch)) == 0)
+				return member;
+
+		return 0;
+	}
+	const Member* FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
+
+	//! 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
+
+	// 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 SourceEncoding, typename InputStream>
+	GenericDocument& ParseStream(InputStream& is) {
+		ValueType::SetNull(); // Remove existing root if exist
+		GenericReader<SourceEncoding, Encoding, Allocator> reader;
+		if (reader.template Parse<parseFlags>(is, *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, typename SourceEncoding>
+	GenericDocument& ParseInsitu(Ch* str) {
+		GenericInsituStringStream<Encoding> s(str);
+		return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s);
+	}
+
+	template <unsigned parseFlags>
+	GenericDocument& ParseInsitu(Ch* str) {
+		return ParseInsitu<parseFlags, Encoding>(str);
+	}
+
+	//! 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, typename SourceEncoding>
+	GenericDocument& Parse(const Ch* str) {
+		RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
+		GenericStringStream<SourceEncoding> s(str);
+		return ParseStream<parseFlags, SourceEncoding>(s);
+	}
+
+	template <unsigned parseFlags>
+	GenericDocument& Parse(const Ch* str) {
+		return Parse<parseFlags, Encoding>(str);
+	}
+
+	//! 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:
+	//friend class GenericReader<Encoding>;	// 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());
+	}
+
+private:
+	// Prohibit assignment
+	GenericDocument& operator=(const GenericDocument&);
+
+	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_

+ 250 - 0
Source/ThirdParty/rapidjson/include/rapidjson/encodedstream.h

@@ -0,0 +1,250 @@
+#ifndef RAPIDJSON_ENCODEDSTREAM_H_
+#define RAPIDJSON_ENCODEDSTREAM_H_
+
+#include "rapidjson.h"
+
+namespace rapidjson {
+
+//! Input byte stream wrapper with a statically bound encoding.
+/*!
+	\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
+	\tparam InputByteStream Type of input byte stream. For example, FileReadStream.
+*/
+template <typename Encoding, typename InputByteStream>
+class EncodedInputStream {
+	RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+public:
+	typedef typename Encoding::Ch Ch;
+
+	EncodedInputStream(InputByteStream& is) : is_(is) { 
+		current_ = Encoding::TakeBOM(is_);
+	}
+
+	Ch Peek() const { return current_; }
+	Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
+	size_t Tell() const { return is_.Tell(); }
+
+	// Not implemented
+	void Put(Ch c) { RAPIDJSON_ASSERT(false); }
+	void Flush() { RAPIDJSON_ASSERT(false); } 
+	Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+private:
+	// Prohibit assignment for VC C4512 warning
+	EncodedInputStream& operator=(const EncodedInputStream&);
+
+	InputByteStream& is_;
+	Ch current_;
+};
+
+//! Output byte stream wrapper with statically bound encoding.
+/*!
+	\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
+	\tparam InputByteStream Type of input byte stream. For example, FileWriteStream.
+*/
+template <typename Encoding, typename OutputByteStream>
+class EncodedOutputStream {
+	RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+public:
+	typedef typename Encoding::Ch Ch;
+
+	EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { 
+		if (putBOM)
+			Encoding::PutBOM(os_);
+	}
+
+	void Put(Ch c) { Encoding::Put(os_, c);  }
+	void Flush() { os_.Flush(); }
+
+	// Not implemented
+	Ch Peek() const { RAPIDJSON_ASSERT(false); }
+	Ch Take() { RAPIDJSON_ASSERT(false);  }
+	size_t Tell() const { RAPIDJSON_ASSERT(false);  return 0; }
+	Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+private:
+	// Prohibit assignment for VC C4512 warning
+	EncodedOutputStream& operator=(const EncodedOutputStream&);
+
+	OutputByteStream& os_;
+};
+
+#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
+
+//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
+/*!
+	\tparam CharType Type of character for reading.
+	\tparam InputByteStream type of input byte stream to be wrapped.
+*/
+template <typename CharType, typename InputByteStream>
+class AutoUTFInputStream {
+	RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+public:
+	typedef CharType Ch;
+
+	//! Constructor.
+	/*!
+		\param is input stream to be wrapped.
+		\param type UTF encoding type if it is not detected from the stream.
+	*/
+	AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
+		DetectType();
+		static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
+		takeFunc_ = f[type_];
+		current_ = takeFunc_(*is_);
+	}
+
+	UTFType GetType() const { return type_; }
+	bool HasBOM() const { return hasBOM_; }
+
+	Ch Peek() const { return current_; }
+	Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
+	size_t Tell() const { return is_->Tell(); }
+
+	// Not implemented
+	void Put(Ch) { RAPIDJSON_ASSERT(false); }
+	void Flush() { RAPIDJSON_ASSERT(false); } 
+	Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+private:
+	// Detect encoding type with BOM or RFC 4627
+	void DetectType() {
+		// BOM (Byte Order Mark):
+		// 00 00 FE FF  UTF-32BE
+		// FF FE 00 00  UTF-32LE
+		// FE FF		UTF-16BE
+		// FF FE		UTF-16LE
+		// EF BB BF		UTF-8
+
+		const unsigned char* c = (const unsigned char *)is_->Peek4();
+		if (!c)
+			return;
+
+		unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
+		hasBOM_ = false;
+		if (bom == 0xFFFE0000)					{ type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
+		else if (bom == 0x0000FEFF)				{ type_ = kUTF32LE;	hasBOM_ = true;	is_->Take(); is_->Take(); is_->Take(); is_->Take();	}
+		else if ((bom & 0xFFFF) == 0xFFFE)		{ type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take();							}
+		else if ((bom & 0xFFFF) == 0xFEFF)		{ type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take();							}
+		else if ((bom & 0xFFFFFF) == 0xBFBBEF)	{ type_ = kUTF8;	hasBOM_ = true; is_->Take(); is_->Take(); is_->Take();				}
+
+		// RFC 4627: Section 3
+		// "Since the first two characters of a JSON text will always be ASCII
+		// characters [RFC0020], it is possible to determine whether an octet
+		// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
+		// at the pattern of nulls in the first four octets."
+		// 00 00 00 xx  UTF-32BE
+		// 00 xx 00 xx  UTF-16BE
+		// xx 00 00 00  UTF-32LE
+		// xx 00 xx 00  UTF-16LE
+		// xx xx xx xx  UTF-8
+
+		if (!hasBOM_) {
+			unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
+			switch (pattern) {
+			case 0x08: type_ = kUTF32BE; break;
+			case 0x0A: type_ = kUTF16BE; break;
+			case 0x01: type_ = kUTF32LE; break;
+			case 0x05: type_ = kUTF16LE; break;
+			case 0x0F: type_ = kUTF8;    break;
+			}
+		}
+
+		// RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
+		switch (type_) {
+		case kUTF8:
+			// Do nothing
+			break;
+		case kUTF16LE:
+		case kUTF16BE:
+			RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
+			break;
+		case kUTF32LE:
+		case kUTF32BE:
+			RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
+			break;
+		}
+	}
+
+	typedef Ch (*TakeFunc)(InputByteStream& is);
+	InputByteStream* is_;
+	UTFType type_;
+	Ch current_;
+	TakeFunc takeFunc_;
+	bool hasBOM_;
+};
+
+//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
+/*!
+	\tparam CharType Type of character for writing.
+	\tparam InputByteStream type of output byte stream to be wrapped.
+*/
+template <typename CharType, typename OutputByteStream>
+class AutoUTFOutputStream {
+	RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+public:
+	typedef CharType Ch;
+
+	//! Constructor.
+	/*!
+		\param os output stream to be wrapped.
+		\param type UTF encoding type.
+		\param putBOM Whether to write BOM at the beginning of the stream.
+	*/
+	AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
+		// RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
+		switch (type_) {
+		case kUTF16LE:
+		case kUTF16BE:
+			RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
+			break;
+		case kUTF32LE:
+		case kUTF32BE:
+			RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
+			break;
+		case kUTF8:
+			// Do nothing
+			break;
+		}
+
+		static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
+		putFunc_ = f[type_];
+
+		if (putBOM)
+			PutBOM();
+	}
+
+	UTFType GetType() const { return type_; }
+
+	void Put(Ch c) { putFunc_(*os_, c); }
+	void Flush() { os_->Flush(); } 
+
+	// Not implemented
+	Ch Peek() const { RAPIDJSON_ASSERT(false); }
+	Ch Take() { RAPIDJSON_ASSERT(false); }
+	size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
+	Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+private:
+	void PutBOM() { 
+		typedef void (*PutBOMFunc)(OutputByteStream&);
+		static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
+		f[type_](*os_);
+	}
+
+	typedef void (*PutFunc)(OutputByteStream&, Ch);
+
+	OutputByteStream* os_;
+	UTFType type_;
+	PutFunc putFunc_;
+};
+
+#undef RAPIDJSON_ENCODINGS_FUNC
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_FILESTREAM_H_

+ 527 - 0
Source/ThirdParty/rapidjson/include/rapidjson/encodings.h

@@ -0,0 +1,527 @@
+#ifndef RAPIDJSON_ENCODINGS_H_
+#define RAPIDJSON_ENCODINGS_H_
+
+#include "rapidjson.h"
+
+namespace rapidjson {
+
+///////////////////////////////////////////////////////////////////////////////
+// Encoding
+
+/*! \class rapidjson::Encoding
+	\brief Concept for encoding of Unicode characters.
+
+\code
+concept Encoding {
+	typename Ch;	//! Type of character. A "character" is actually a code unit in unicode's definition.
+
+	//! \brief Encode a Unicode codepoint to an output stream.
+	//! \param os Output stream.
+	//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
+	template<typename OutputStream>
+	static void Encode(OutputStream& os, unsigned codepoint);
+
+	//! \brief Decode a Unicode codepoint from an input stream.
+	//! \param is Input stream.
+	//! \param codepoint Output of the unicode codepoint.
+	//! \return true if a valid codepoint can be decoded from the stream.
+	template <typename InputStream>
+	static bool Decode(InputStream& is, unsigned* codepoint);
+
+	//! \brief Validate one Unicode codepoint from an encoded stream.
+	//! \param is Input stream to obtain codepoint.
+	//! \param os Output for copying one codepoint.
+	//! \return true if it is valid.
+	//! \note This function just validating and copying the codepoint without actually decode it.
+	template <typename InputStream, typename OutputStream>
+	static bool Validate(InputStream& is, OutputStream& os);
+
+	// The following functions are deal with byte streams.
+
+	//! Take a character from input byte stream, skip BOM if exist.
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is);
+
+	//! Take a character from input byte stream.
+	template <typename InputByteStream>
+	static Ch Take(InputByteStream& is);
+
+	//! Put BOM to output byte stream.
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os);
+
+	//! Put a character to output byte stream.
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, Ch c);
+};
+\endcode
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// UTF8
+
+//! UTF-8 encoding.
+/*! http://en.wikipedia.org/wiki/UTF-8
+	http://tools.ietf.org/html/rfc3629
+	\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.
+	\implements Encoding
+*/
+template<typename CharType = char>
+struct UTF8 {
+	typedef CharType Ch;
+
+	template<typename OutputStream>
+	static void Encode(OutputStream& os, unsigned codepoint) {
+		if (codepoint <= 0x7F) 
+			os.Put(codepoint & 0xFF);
+		else if (codepoint <= 0x7FF) {
+			os.Put(0xC0 | ((codepoint >> 6) & 0xFF));
+			os.Put(0x80 | ((codepoint & 0x3F)));
+		}
+		else if (codepoint <= 0xFFFF) {
+			os.Put(0xE0 | ((codepoint >> 12) & 0xFF));
+			os.Put(0x80 | ((codepoint >> 6) & 0x3F));
+			os.Put(0x80 | (codepoint & 0x3F));
+		}
+		else {
+			RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+			os.Put(0xF0 | ((codepoint >> 18) & 0xFF));
+			os.Put(0x80 | ((codepoint >> 12) & 0x3F));
+			os.Put(0x80 | ((codepoint >> 6) & 0x3F));
+			os.Put(0x80 | (codepoint & 0x3F));
+		}
+	}
+
+	template <typename InputStream>
+	static bool Decode(InputStream& is, unsigned* codepoint) {
+#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
+#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
+#define TAIL() COPY(); TRANS(0x70)
+		Ch c = is.Take();
+		if (!(c & 0x80)) {
+			*codepoint = (unsigned char)c;
+			return true;
+		}
+
+		unsigned char type = GetRange((unsigned char)c);
+		*codepoint = (0xFF >> type) & (unsigned char)c;
+		bool result = true;
+		switch (type) {
+		case 2:	TAIL(); return result;
+		case 3:	TAIL(); TAIL(); return result;
+		case 4:	COPY(); TRANS(0x50); TAIL(); return result;
+		case 5:	COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
+		case 6: TAIL(); TAIL(); TAIL(); return result;
+		case 10: COPY(); TRANS(0x20); TAIL(); return result;
+		case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
+		default: return false;
+		}
+#undef COPY
+#undef TRANS
+#undef TAIL
+	}
+
+	template <typename InputStream, typename OutputStream>
+	static bool Validate(InputStream& is, OutputStream& os) {
+#define COPY() os.Put(c = is.Take())
+#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
+#define TAIL() COPY(); TRANS(0x70)
+		Ch c;
+		COPY();
+		if (!(c & 0x80))
+			return true;
+
+		bool result = true;
+		switch (GetRange((unsigned char)c)) {
+		case 2:	TAIL(); return result;
+		case 3:	TAIL(); TAIL(); return result;
+		case 4:	COPY(); TRANS(0x50); TAIL(); return result;
+		case 5:	COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
+		case 6: TAIL(); TAIL(); TAIL(); return result;
+		case 10: COPY(); TRANS(0x20); TAIL(); return result;
+		case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
+		default: return false;
+		}
+#undef COPY
+#undef TRANS
+#undef TAIL
+	}
+
+	static unsigned char GetRange(unsigned char c) {
+		// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+		// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
+		static const unsigned char type[] = {
+			0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+			0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+			0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+			0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+			0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+			0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+			0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+			0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+			8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+			10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+		};
+		return type[c];
+	}
+
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		Ch c = Take(is);
+		if ((unsigned char)c != 0xEFu) return c;
+		c = is.Take();
+		if ((unsigned char)c != 0xBBu) return c;
+		c = is.Take();
+		if ((unsigned char)c != 0xBFu) return c;
+		c = is.Take();
+		return c;
+	}
+
+	template <typename InputByteStream>
+	static Ch Take(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		return is.Take();
+	}
+
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu);
+	}
+
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, Ch c) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(static_cast<typename OutputByteStream::Ch>(c));
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// UTF16
+
+//! UTF-16 encoding.
+/*! http://en.wikipedia.org/wiki/UTF-16
+	http://tools.ietf.org/html/rfc2781
+	\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
+	\implements Encoding
+
+	\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
+	For streaming, use UTF16LE and UTF16BE, which handle endianness.
+*/
+template<typename CharType = wchar_t>
+struct UTF16 {
+	typedef CharType Ch;
+	RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
+
+	template<typename OutputStream>
+	static void Encode(OutputStream& os, unsigned codepoint) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
+		if (codepoint <= 0xFFFF) {
+			RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair 
+			os.Put(static_cast<typename OutputStream::Ch>(codepoint));
+		}
+		else {
+			RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+			unsigned v = codepoint - 0x10000;
+			os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
+			os.Put((v & 0x3FF) | 0xDC00);
+		}
+	}
+
+	template <typename InputStream>
+	static bool Decode(InputStream& is, unsigned* codepoint) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
+		Ch c = is.Take();
+		if (c < 0xD800 || c > 0xDFFF) {
+			*codepoint = c;
+			return true;
+		}
+		else if (c <= 0xDBFF) {
+			*codepoint = (c & 0x3FF) << 10;
+			c = is.Take();
+			*codepoint |= (c & 0x3FF);
+			*codepoint += 0x10000;
+			return c >= 0xDC00 && c <= 0xDFFF;
+		}
+		return false;
+	}
+
+	template <typename InputStream, typename OutputStream>
+	static bool Validate(InputStream& is, OutputStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
+		Ch c;
+		os.Put(c = is.Take());
+		if (c < 0xD800 || c > 0xDFFF)
+			return true;
+		else if (c <= 0xDBFF) {
+			os.Put(c = is.Take());
+			return c >= 0xDC00 && c <= 0xDFFF;
+		}
+		return false;
+	}
+};
+
+//! UTF-16 little endian encoding.
+template<typename CharType = wchar_t>
+struct UTF16LE : UTF16<CharType> {
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = Take(is);
+		return (unsigned short)c == 0xFEFFu ? Take(is) : c;
+	}
+
+	template <typename InputByteStream>
+	static CharType Take(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = (unsigned char)is.Take();
+		c |= (unsigned char)is.Take() << 8;
+		return c;
+	}
+
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(0xFFu); os.Put(0xFEu);
+	}
+
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, CharType c) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(c & 0xFFu);
+		os.Put((c >> 8) & 0xFFu);
+	}
+};
+
+//! UTF-16 big endian encoding.
+template<typename CharType = wchar_t>
+struct UTF16BE : UTF16<CharType> {
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = Take(is);
+		return (unsigned short)c == 0xFEFFu ? Take(is) : c;
+	}
+
+	template <typename InputByteStream>
+	static CharType Take(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = (unsigned char)is.Take() << 8;
+		c |= (unsigned char)is.Take();
+		return c;
+	}
+
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(0xFEu); os.Put(0xFFu);
+	}
+
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, CharType c) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put((c >> 8) & 0xFFu);
+		os.Put(c & 0xFFu);
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// 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
+
+	\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
+	For streaming, use UTF32LE and UTF32BE, which handle endianness.
+*/
+template<typename CharType = unsigned>
+struct UTF32 {
+	typedef CharType Ch;
+	RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
+
+	template<typename OutputStream>
+	static void Encode(OutputStream& os, unsigned codepoint) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
+		RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
+		os.Put(codepoint);
+	}
+
+	template <typename InputStream>
+	static bool Decode(InputStream& is, unsigned* codepoint) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
+		Ch c = is.Take();
+		*codepoint = c;
+		return c <= 0x10FFFF;
+	}
+
+	template <typename InputStream, typename OutputStream>
+	static bool Validate(InputStream& is, OutputStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
+		Ch c;
+		os.Put(c = is.Take());
+		return c <= 0x10FFFF;
+	}
+};
+
+//! UTF-32 little endian enocoding.
+template<typename CharType = unsigned>
+struct UTF32LE : UTF32<CharType> {
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = Take(is);
+		return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
+	}
+
+	template <typename InputByteStream>
+	static CharType Take(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = (unsigned char)is.Take();
+		c |= (unsigned char)is.Take() << 8;
+		c |= (unsigned char)is.Take() << 16;
+		c |= (unsigned char)is.Take() << 24;
+		return c;
+	}
+
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
+	}
+
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, CharType c) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(c & 0xFFu);
+		os.Put((c >> 8) & 0xFFu);
+		os.Put((c >> 16) & 0xFFu);
+		os.Put((c >> 24) & 0xFFu);
+	}
+};
+
+//! UTF-32 big endian encoding.
+template<typename CharType = unsigned>
+struct UTF32BE : UTF32<CharType> {
+	template <typename InputByteStream>
+	static CharType TakeBOM(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = Take(is);
+		return (unsigned)c == 0x0000FEFFu ? Take(is) : c; 
+	}
+
+	template <typename InputByteStream>
+	static CharType Take(InputByteStream& is) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
+		CharType c = (unsigned char)is.Take() << 24;
+		c |= (unsigned char)is.Take() << 16;
+		c |= (unsigned char)is.Take() << 8;
+		c |= (unsigned char)is.Take();
+		return c;
+	}
+
+	template <typename OutputByteStream>
+	static void PutBOM(OutputByteStream& os) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
+	}
+
+	template <typename OutputByteStream>
+	static void Put(OutputByteStream& os, CharType c) {
+		RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
+		os.Put((c >> 24) & 0xFFu);
+		os.Put((c >> 16) & 0xFFu);
+		os.Put((c >> 8) & 0xFFu);
+		os.Put(c & 0xFFu);
+	}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// AutoUTF
+
+//! Runtime-specified UTF encoding type of a stream.
+enum UTFType {
+	kUTF8 = 0,		//!< UTF-8.
+	kUTF16LE = 1,	//!< UTF-16 little endian.
+	kUTF16BE = 2,	//!< UTF-16 big endian.
+	kUTF32LE = 3,	//!< UTF-32 little endian.
+	kUTF32BE = 4,	//!< UTF-32 big endian.
+};
+
+//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.
+/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().
+*/
+template<typename CharType>
+struct AutoUTF {
+	typedef CharType Ch;
+
+#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
+
+	template<typename OutputStream>
+	RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {
+		typedef void (*EncodeFunc)(OutputStream&, unsigned);
+		static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
+		(*f[os.GetType()])(os, codepoint);
+	}
+
+	template <typename InputStream>
+	RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
+		typedef bool (*DecodeFunc)(InputStream&, unsigned*);
+		static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
+		return (*f[is.GetType()])(is, codepoint);
+	}
+
+	template <typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+		typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
+		static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
+		return (*f[is.GetType()])(is, os);
+	}
+
+#undef RAPIDJSON_ENCODINGS_FUNC
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Transcoder
+
+//! Encoding conversion.
+template<typename SourceEncoding, typename TargetEncoding>
+struct Transcoder {
+	//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
+	template<typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
+		unsigned codepoint;
+		if (!SourceEncoding::Decode(is, &codepoint))
+			return false;
+		TargetEncoding::Encode(os, codepoint);
+		return true;
+	}
+
+	//! Validate one Unicode codepoint from an encoded stream.
+	template<typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+		return Transcode(is, os);	// Since source/target encoding is different, must transcode.
+	}
+};
+
+//! Specialization of Transcoder with same source and target encoding.
+template<typename Encoding>
+struct Transcoder<Encoding, Encoding> {
+	template<typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
+		os.Put(is.Take());	// Just copy one code unit. This semantic is different from primary template class.
+		return true;
+	}
+	
+	template<typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+		return Encoding::Validate(is, os);	// source/target encoding are the same
+	}
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_ENCODINGS_H_

+ 74 - 0
Source/ThirdParty/rapidjson/include/rapidjson/filereadstream.h

@@ -0,0 +1,74 @@
+#ifndef RAPIDJSON_FILEREADSTREAM_H_
+#define RAPIDJSON_FILEREADSTREAM_H_
+
+#include "rapidjson.h"
+#include <cstdio>
+
+namespace rapidjson {
+
+//! File byte stream for input using fread().
+/*!
+	\implements Stream
+*/
+class FileReadStream {
+public:
+	typedef char Ch;	//!< Character type (byte).
+
+	//! Constructor.
+	/*!
+		\param fp File pointer opened for read.
+		\param buffer user-supplied buffer.
+		\param bufferSize size of buffer in bytes. Must >=4 bytes.
+	*/
+	FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 
+		RAPIDJSON_ASSERT(fp_ != 0);
+		RAPIDJSON_ASSERT(bufferSize >= 4);
+		Read();
+	}
+
+	Ch Peek() const { return *current_; }
+	Ch Take() { Ch c = *current_; Read(); return c; }
+	size_t Tell() const { return count_ + (current_ - buffer_); }
+
+	// Not implemented
+	void Put(Ch) { RAPIDJSON_ASSERT(false); }
+	void Flush() { RAPIDJSON_ASSERT(false); } 
+	Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
+
+	// For encoding detection only.
+	const Ch* Peek4() const {
+		return (current_ + 4 <= bufferLast_) ? current_ : 0;
+	}
+
+private:
+	void Read() {
+		if (current_ < bufferLast_)
+			++current_;
+		else if (!eof_) {
+			count_ += readCount_;
+			readCount_ = fread(buffer_, 1, bufferSize_, fp_);
+			bufferLast_ = buffer_ + readCount_ - 1;
+			current_ = buffer_;
+
+			if (readCount_ < bufferSize_) {
+				buffer_[readCount_] = '\0';
+				++bufferLast_;
+				eof_ = true;
+			}
+		}
+	}
+
+	FILE* fp_;
+	Ch *buffer_;
+	size_t bufferSize_;
+	Ch *bufferLast_;
+	Ch *current_;
+	size_t readCount_;
+	size_t count_;	//!< Number of characters read
+	bool eof_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_FILESTREAM_H_

+ 49 - 0
Source/ThirdParty/rapidjson/include/rapidjson/filestream.h

@@ -0,0 +1,49 @@
+#ifndef RAPIDJSON_FILESTREAM_H_
+#define RAPIDJSON_FILESTREAM_H_
+
+#include "rapidjson.h"
+#include <cstdio>
+
+namespace rapidjson {
+
+//! (Depreciated) Wrapper of C file stream for input or output.
+/*!
+	This simple wrapper does not check the validity of the stream.
+	\implements Stream
+	\deprecated { This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. }
+*/
+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_); }
+	void Flush() { fflush(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 if (current_ != '\0')
+			current_ = '\0';
+	}
+
+	FILE* fp_;
+	char current_;
+	size_t count_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_FILESTREAM_H_

+ 73 - 0
Source/ThirdParty/rapidjson/include/rapidjson/filewritestream.h

@@ -0,0 +1,73 @@
+#ifndef RAPIDJSON_FILEWRITESTREAM_H_
+#define RAPIDJSON_FILEWRITESTREAM_H_
+
+#include "rapidjson.h"
+#include <cstdio>
+
+namespace rapidjson {
+
+//! Wrapper of C file stream for input using fread().
+/*!
+	\implements Stream
+*/
+class FileWriteStream {
+public:
+	typedef char Ch;	//!< Character type. Only support char.
+
+	FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 
+		RAPIDJSON_ASSERT(fp_ != 0);
+	}
+
+	void Put(char c) { 
+		if (current_ >= bufferEnd_)
+			Flush();
+
+		*current_++ = c;
+	}
+
+	void PutN(char c, size_t n) {
+		size_t avail = bufferEnd_ - current_;
+		while (n > avail) {
+			memset(current_, c, avail);
+			current_ += avail;
+			Flush();
+			n -= avail;
+			avail = bufferEnd_ - current_;
+		}
+
+		if (n > 0) {
+			memset(current_, c, n);
+			current_ += n;
+		}
+	}
+
+	void Flush() {
+		if (current_ != buffer_) {
+			fwrite(buffer_, 1, current_ - buffer_, fp_);
+			current_ = buffer_;
+		}
+	}
+
+	// Not implemented
+	char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
+	char Take() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
+	char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+	size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
+
+private:
+	FILE* fp_;
+	char *buffer_;
+	char *bufferEnd_;
+	char *current_;
+};
+
+//! Implement specialized version of PutN() with memset() for better performance.
+template<>
+inline void PutN(FileWriteStream& stream, char c, size_t n) {
+	stream.PutN(c, n);
+}
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_FILESTREAM_H_

+ 54 - 0
Source/ThirdParty/rapidjson/include/rapidjson/internal/pow10.h

@@ -0,0 +1,54 @@
+#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_

+ 83 - 0
Source/ThirdParty/rapidjson/include/rapidjson/internal/stack.h

@@ -0,0 +1,83 @@
+#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_; }
+	bool Empty() const { return stack_top_ == stack_; }
+	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_

+ 24 - 0
Source/ThirdParty/rapidjson/include/rapidjson/internal/strfunc.h

@@ -0,0 +1,24 @@
+#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_

+ 160 - 0
Source/ThirdParty/rapidjson/include/rapidjson/prettywriter.h

@@ -0,0 +1,160 @@
+#ifndef RAPIDJSON_PRETTYWRITER_H_
+#define RAPIDJSON_PRETTYWRITER_H_
+
+#include "writer.h"
+
+namespace rapidjson {
+
+//! Writer with indentation and spacing.
+/*!
+	\tparam OutputStream Type of ouptut os.
+	\tparam Encoding Encoding of both source strings and output.
+	\tparam Allocator Type of allocator for allocating memory of stack.
+*/
+template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
+class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> {
+public:
+	typedef Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> Base;
+	typedef typename Base::Ch Ch;
+
+	//! Constructor
+	/*! \param os Output os.
+		\param allocator User supplied allocator. If it is null, it will create a private one.
+		\param levelDepth Initial capacity of 
+	*/
+	PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
+		Base(os, 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::os_.Put('\n');
+			WriteIndent();
+		}
+		Base::WriteEndObject();
+		if (Base::level_stack_.Empty())	// end of json text
+			Base::os_.Flush();
+		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::os_.Put('\n');
+			WriteIndent();
+		}
+		Base::WriteEndArray();
+		if (Base::level_stack_.Empty())	// end of json text
+			Base::os_.Flush();
+		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::os_.Put(','); // add comma if it is not the first element in array
+					Base::os_.Put('\n');
+				}
+				else
+					Base::os_.Put('\n');
+				WriteIndent();
+			}
+			else {	// in object
+				if (level->valueCount > 0) {
+					if (level->valueCount % 2 == 0) {
+						Base::os_.Put(',');
+						Base::os_.Put('\n');
+					}
+					else {
+						Base::os_.Put(':');
+						Base::os_.Put(' ');
+					}
+				}
+				else
+					Base::os_.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::os_, indentChar_, count);
+	}
+
+	Ch indentChar_;
+	unsigned indentCharCount_;
+};
+
+} // namespace rapidjson
+
+#endif // RAPIDJSON_RAPIDJSON_H_

+ 256 - 0
Source/ThirdParty/rapidjson/include/rapidjson/rapidjson.h

@@ -0,0 +1,256 @@
+#ifndef RAPIDJSON_RAPIDJSON_H_
+#define RAPIDJSON_RAPIDJSON_H_
+
+// Copyright (c) 2011 Milo Yip ([email protected])
+// Version 0.1
+
+#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;
+#define RAPIDJSON_FORCEINLINE __forceinline
+#else
+#include <inttypes.h>
+#define RAPIDJSON_FORCEINLINE
+#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_ALIGNSIZE
+
+//! Data alignment of the machine.
+/*!
+	Some machine requires strict data alignment.
+	Currently the default uses 4 bytes alignment. User can customize this.
+*/
+#ifndef RAPIDJSON_ALIGN
+#define RAPIDJSON_ALIGN(x) ((x + 3) & ~3)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// 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
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_STATIC_ASSERT
+
+// Adopt from boost
+#ifndef RAPIDJSON_STATIC_ASSERT
+namespace rapidjson {
+template <bool x> struct STATIC_ASSERTION_FAILURE;
+template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
+template<int x> struct StaticAssertTest {};
+} // namespace rapidjson
+
+#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
+#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
+#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
+
+#define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\
+	sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
+	RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+
+#define RAPIDJSON_MULTILINEMACRO_BEGIN do {  
+#define RAPIDJSON_MULTILINEMACRO_END \
+} while((void)0, 0)
+
+///////////////////////////////////////////////////////////////////////////////
+// Allocators and Encodings
+
+#include "allocators.h"
+#include "encodings.h"
+
+namespace rapidjson {
+
+///////////////////////////////////////////////////////////////////////////////
+//  Stream
+
+/*! \class rapidjson::Stream
+	\brief Concept for reading and writing characters.
+
+	For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
+
+	For write-only stream, only need to implement Put() and Flush().
+
+\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);
+
+	//! Flush the buffer.
+	void Flush();
+
+	//! 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); }
+	void Flush() { 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; }
+	void Flush() {}
+	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_

+ 669 - 0
Source/ThirdParty/rapidjson/include/rapidjson/reader.h

@@ -0,0 +1,669 @@
+#ifndef RAPIDJSON_READER_H_
+#define RAPIDJSON_READER_H_
+
+// Copyright (c) 2011 Milo Yip ([email protected])
+// Version 0.1
+
+#include "rapidjson.h"
+#include "encodings.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.
+	kParseValidateEncodingFlag = 2,	//!< Validate encoding of JSON strings.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// 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 InputStream>
+void SkipWhitespace(InputStream& is) {
+	InputStream s = is;	// Use a local copy for optimization
+	while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
+		s.Take();
+	is = 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& is) { 
+	is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
+}
+
+//! Template function specialization for StringStream
+template<> inline void SkipWhitespace(StringStream& is) {
+	is.src_ = SkipWhitespace_SIMD(is.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 SourceEncoding Encoding of the input stream.
+	\tparam TargetEncoding Encoding of the parse output.
+    \tparam Allocator Allocator type for stack.
+*/
+template <typename SourceEncoding, typename TargetEncoding, typename Allocator = MemoryPoolAllocator<> >
+class GenericReader {
+public:
+	typedef typename SourceEncoding::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 InputStream 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 InputStream, typename Handler>
+	bool Parse(InputStream& is, 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(is);
+
+		if (is.Peek() == '\0')
+			RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", is.Tell());
+		else {
+			switch (is.Peek()) {
+				case '{': ParseObject<parseFlags>(is, handler); break;
+				case '[': ParseArray<parseFlags>(is, handler); break;
+				default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", is.Tell());
+			}
+			SkipWhitespace(is);
+
+			if (is.Peek() != '\0')
+				RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", is.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 InputStream, typename Handler>
+	void ParseObject(InputStream& is, Handler& handler) {
+		RAPIDJSON_ASSERT(is.Peek() == '{');
+		is.Take();	// Skip '{'
+		handler.StartObject();
+		SkipWhitespace(is);
+
+		if (is.Peek() == '}') {
+			is.Take();
+			handler.EndObject(0);	// empty object
+			return;
+		}
+
+		for (SizeType memberCount = 0;;) {
+			if (is.Peek() != '"')
+				RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell());
+
+			ParseString<parseFlags>(is, handler);
+			SkipWhitespace(is);
+
+			if (is.Take() != ':')
+				RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", is.Tell());
+
+			SkipWhitespace(is);
+
+			ParseValue<parseFlags>(is, handler);
+			SkipWhitespace(is);
+
+			++memberCount;
+
+			switch(is.Take()) {
+				case ',': SkipWhitespace(is); break;
+				case '}': handler.EndObject(memberCount); return;
+				default:  RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", is.Tell());
+			}
+		}
+	}
+
+	// Parse array: [ value, ... ]
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseArray(InputStream& is, Handler& handler) {
+		RAPIDJSON_ASSERT(is.Peek() == '[');
+		is.Take();	// Skip '['
+		handler.StartArray();
+		SkipWhitespace(is);
+
+		if (is.Peek() == ']') {
+			is.Take();
+			handler.EndArray(0); // empty array
+			return;
+		}
+
+		for (SizeType elementCount = 0;;) {
+			ParseValue<parseFlags>(is, handler);
+			++elementCount;
+			SkipWhitespace(is);
+
+			switch (is.Take()) {
+				case ',': SkipWhitespace(is); break;
+				case ']': handler.EndArray(elementCount); return;
+				default:  RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", is.Tell());
+			}
+		}
+	}
+
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseNull(InputStream& is, Handler& handler) {
+		RAPIDJSON_ASSERT(is.Peek() == 'n');
+		is.Take();
+
+		if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l')
+			handler.Null();
+		else
+			RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1);
+	}
+
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseTrue(InputStream& is, Handler& handler) {
+		RAPIDJSON_ASSERT(is.Peek() == 't');
+		is.Take();
+
+		if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e')
+			handler.Bool(true);
+		else
+			RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell());
+	}
+
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseFalse(InputStream& is, Handler& handler) {
+		RAPIDJSON_ASSERT(is.Peek() == 'f');
+		is.Take();
+
+		if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e')
+			handler.Bool(false);
+		else
+			RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1);
+	}
+
+	// Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
+	template<typename InputStream>
+	unsigned ParseHex4(InputStream& is) {
+		InputStream s = is;	// 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);
+		}
+		is = s; // Restore is
+		return codepoint;
+	}
+
+	class StackStream {
+	public:
+		typedef typename TargetEncoding::Ch Ch;
+
+		StackStream(internal::Stack<Allocator>& stack) : stack_(stack), length_(0) {}
+		void Put(Ch c) {
+			*stack_.template Push<Ch>() = c;
+			++length_;
+		}
+		internal::Stack<Allocator>& stack_;
+		SizeType length_;
+
+	private:
+		// Prohibit assignment for VC C4512 warning
+		StackStream& operator=(const StackStream&);
+	};
+
+	// Parse string and generate String event. Different code paths for kParseInsituFlag.
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseString(InputStream& is, Handler& handler) {
+		InputStream s = is;	// Local copy for optimization
+		if (parseFlags & kParseInsituFlag) {
+			Ch *head = s.PutBegin();
+			ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
+			size_t length = s.PutEnd(head) - 1;
+			RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
+			handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false);
+		}
+		else {
+			StackStream stackStream(stack_);
+			ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
+			handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true);
+		}
+		is = s;		// Restore is
+	}
+
+	// Parse string to an output is
+	// This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
+	template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
+	RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
+#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+		static const char 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
+
+		RAPIDJSON_ASSERT(is.Peek() == '\"');
+		is.Take();	// Skip '\"'
+
+		for (;;) {
+			Ch c = is.Peek();
+			if (c == '\\') {	// Escape
+				is.Take();
+				Ch e = is.Take();
+				if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e])
+					os.Put(escape[(unsigned char)e]);
+				else if (e == 'u') {	// Unicode
+					unsigned codepoint = ParseHex4(is);
+					if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
+						// Handle UTF-16 surrogate pair
+						if (is.Take() != '\\' || is.Take() != 'u')
+							RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", is.Tell() - 2);
+						unsigned codepoint2 = ParseHex4(is);
+						if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
+							RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", is.Tell() - 2);
+						codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
+					}
+					TEncoding::Encode(os, codepoint);
+				}
+				else
+					RAPIDJSON_PARSE_ERROR("Unknown escape character", is.Tell() - 1);
+			}
+			else if (c == '"') {	// Closing double quote
+				is.Take();
+				os.Put('\0');	// null-terminate the string
+				return;
+			}
+			else if (c == '\0')
+				RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", is.Tell() - 1);
+			else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
+				RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", is.Tell() - 1);
+			else {
+				if (parseFlags & kParseValidateEncodingFlag ? 
+					!Transcoder<SEncoding, TEncoding>::Validate(is, os) : 
+					!Transcoder<SEncoding, TEncoding>::Transcode(is, os))
+					RAPIDJSON_PARSE_ERROR("Invalid encoding", is.Tell());
+			}
+		}
+	}
+
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseNumber(InputStream& is, Handler& handler) {
+		InputStream s = is; // 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.", is.Tell());
+
+		// 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", is.Tell());
+				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", is.Tell());
+
+			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", is.Tell());
+				}
+			}
+			else
+				RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell());
+
+			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);
+			}
+		}
+
+		is = s; // restore is
+	}
+
+	// Parse any JSON value
+	template<unsigned parseFlags, typename InputStream, typename Handler>
+	void ParseValue(InputStream& is, Handler& handler) {
+		switch (is.Peek()) {
+			case 'n': ParseNull  <parseFlags>(is, handler); break;
+			case 't': ParseTrue  <parseFlags>(is, handler); break;
+			case 'f': ParseFalse <parseFlags>(is, handler); break;
+			case '"': ParseString<parseFlags>(is, handler); break;
+			case '{': ParseObject<parseFlags>(is, handler); break;
+			case '[': ParseArray <parseFlags>(is, handler); break;
+			default : ParseNumber<parseFlags>(is, 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<>, UTF8<> > Reader;
+
+} // namespace rapidjson
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // RAPIDJSON_READER_H_

+ 50 - 0
Source/ThirdParty/rapidjson/include/rapidjson/stringbuffer.h

@@ -0,0 +1,50 @@
+#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 Flush() {}
+
+	void Clear() { stack_.Clear(); }
+
+	const Ch* 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 GetSize() 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_

+ 249 - 0
Source/ThirdParty/rapidjson/include/rapidjson/writer.h

@@ -0,0 +1,249 @@
+#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 os.
+
+	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 OutputStream Type of output stream.
+	\tparam SourceEncoding Encoding of both source strings.
+	\tparam TargetEncoding Encoding of and output stream.
+	\implements Handler
+*/
+template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
+class Writer {
+public:
+	typedef typename SourceEncoding::Ch Ch;
+
+	Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : 
+		os_(os), 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();
+		if (level_stack_.Empty())	// end of json text
+			os_.Flush();
+		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();
+		if (level_stack_.Empty())	// end of json text
+			os_.Flush();
+		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()  {
+		os_.Put('n'); os_.Put('u'); os_.Put('l'); os_.Put('l');
+	}
+
+	void WriteBool(bool b)  {
+		if (b) {
+			os_.Put('t'); os_.Put('r'); os_.Put('u'); os_.Put('e');
+		}
+		else {
+			os_.Put('f'); os_.Put('a'); os_.Put('l'); os_.Put('s'); os_.Put('e');
+		}
+	}
+
+	void WriteInt(int i) {
+		if (i < 0) {
+			os_.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;
+			os_.Put(*p);
+		} while (p != buffer);
+	}
+
+	void WriteInt64(int64_t i64) {
+		if (i64 < 0) {
+			os_.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;
+			os_.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++)
+			os_.Put(buffer[i]);
+	}
+
+	void WriteString(const Ch* str, SizeType length)  {
+		static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+		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
+		};
+
+		os_.Put('\"');
+		GenericStringStream<SourceEncoding> is(str);
+		while (is.Tell() < length) {
+			const Ch c = is.Peek();
+			if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c])  {
+				is.Take();
+				os_.Put('\\');
+				os_.Put(escape[(unsigned char)c]);
+				if (escape[(unsigned char)c] == 'u') {
+					os_.Put('0');
+					os_.Put('0');
+					os_.Put(hexDigits[(unsigned char)c >> 4]);
+					os_.Put(hexDigits[(unsigned char)c & 0xF]);
+				}
+			}
+			else
+				Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, os_);
+		}
+		os_.Put('\"');
+	}
+
+	void WriteStartObject()	{ os_.Put('{'); }
+	void WriteEndObject()	{ os_.Put('}'); }
+	void WriteStartArray()	{ os_.Put('['); }
+	void WriteEndArray()	{ os_.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) 
+					os_.Put(','); // add comma if it is not the first element in array
+				else  // in object
+					os_.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);
+	}
+
+	OutputStream& os_;
+	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_