瀏覽代碼

Update RapidJSON lib [cache clear]

1vanK 3 年之前
父節點
當前提交
7514e0d469
共有 39 個文件被更改,包括 3027 次插入783 次删除
  1. 1 1
      Docs/Urho3D.dox
  2. 1 1
      README.md
  3. 3 0
      Source/ThirdParty/rapidjson/Urho3DNotes.txt
  4. 477 56
      Source/ThirdParty/rapidjson/include/rapidjson/allocators.h
  5. 78 0
      Source/ThirdParty/rapidjson/include/rapidjson/cursorstreamwrapper.h
  6. 561 143
      Source/ThirdParty/rapidjson/include/rapidjson/document.h
  7. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/encodedstream.h
  8. 41 41
      Source/ThirdParty/rapidjson/include/rapidjson/encodings.h
  9. 49 1
      Source/ThirdParty/rapidjson/include/rapidjson/error/en.h
  10. 64 3
      Source/ThirdParty/rapidjson/include/rapidjson/error/error.h
  11. 3 3
      Source/ThirdParty/rapidjson/include/rapidjson/filereadstream.h
  12. 3 3
      Source/ThirdParty/rapidjson/include/rapidjson/filewritestream.h
  13. 2 2
      Source/ThirdParty/rapidjson/include/rapidjson/fwd.h
  14. 16 9
      Source/ThirdParty/rapidjson/include/rapidjson/internal/biginteger.h
  15. 71 0
      Source/ThirdParty/rapidjson/include/rapidjson/internal/clzll.h
  16. 31 28
      Source/ThirdParty/rapidjson/include/rapidjson/internal/diyfp.h
  17. 8 4
      Source/ThirdParty/rapidjson/include/rapidjson/internal/dtoa.h
  18. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/internal/ieee754.h
  19. 44 40
      Source/ThirdParty/rapidjson/include/rapidjson/internal/itoa.h
  20. 8 3
      Source/ThirdParty/rapidjson/include/rapidjson/internal/meta.h
  21. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/internal/pow10.h
  22. 25 20
      Source/ThirdParty/rapidjson/include/rapidjson/internal/regex.h
  23. 5 4
      Source/ThirdParty/rapidjson/include/rapidjson/internal/stack.h
  24. 15 1
      Source/ThirdParty/rapidjson/include/rapidjson/internal/strfunc.h
  25. 66 42
      Source/ThirdParty/rapidjson/include/rapidjson/internal/strtod.h
  26. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/internal/swap.h
  27. 51 38
      Source/ThirdParty/rapidjson/include/rapidjson/istreamwrapper.h
  28. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/memorybuffer.h
  29. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/memorystream.h
  30. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/ostreamwrapper.h
  31. 141 17
      Source/ThirdParty/rapidjson/include/rapidjson/pointer.h
  32. 16 19
      Source/ThirdParty/rapidjson/include/rapidjson/prettywriter.h
  33. 136 23
      Source/ThirdParty/rapidjson/include/rapidjson/rapidjson.h
  34. 121 96
      Source/ThirdParty/rapidjson/include/rapidjson/reader.h
  35. 426 152
      Source/ThirdParty/rapidjson/include/rapidjson/schema.h
  36. 49 5
      Source/ThirdParty/rapidjson/include/rapidjson/stream.h
  37. 1 1
      Source/ThirdParty/rapidjson/include/rapidjson/stringbuffer.h
  38. 481 0
      Source/ThirdParty/rapidjson/include/rapidjson/uri.h
  39. 26 20
      Source/ThirdParty/rapidjson/include/rapidjson/writer.h

+ 1 - 1
Docs/Urho3D.dox

@@ -93,7 +93,7 @@ Urho3D uses the following third-party libraries:
 - nanodbc 2.12.4+ (https://lexicalunit.github.io/nanodbc)
 - nanodbc 2.12.4+ (https://lexicalunit.github.io/nanodbc)
 - Open Asset Import Library 4.1.0 (http://assimp.sourceforge.net)
 - Open Asset Import Library 4.1.0 (http://assimp.sourceforge.net)
 - pugixml 1.10+ (http://pugixml.org)
 - pugixml 1.10+ (http://pugixml.org)
-- rapidjson 1.1.0 (https://github.com/miloyip/rapidjson)
+- RapidJSON 1.1.0+ (https://github.com/Tencent/rapidjson)
 - Recast/Detour (https://github.com/recastnavigation/recastnavigation)
 - Recast/Detour (https://github.com/recastnavigation/recastnavigation)
 - SDL 2.0.10+ (https://www.libsdl.org)
 - SDL 2.0.10+ (https://www.libsdl.org)
 - SQLite 3.20.1 (https://www.sqlite.org)
 - SQLite 3.20.1 (https://www.sqlite.org)

+ 1 - 1
README.md

@@ -57,7 +57,7 @@ Urho3D uses the following third-party libraries:
 - nanodbc 2.12.4+ (https://lexicalunit.github.io/nanodbc)
 - nanodbc 2.12.4+ (https://lexicalunit.github.io/nanodbc)
 - Open Asset Import Library 4.1.0 (http://assimp.sourceforge.net)
 - Open Asset Import Library 4.1.0 (http://assimp.sourceforge.net)
 - pugixml 1.10+ (http://pugixml.org)
 - pugixml 1.10+ (http://pugixml.org)
-- rapidjson 1.1.0 (https://github.com/miloyip/rapidjson)
+- RapidJSON 1.1.0+ (https://github.com/Tencent/rapidjson)
 - Recast/Detour (https://github.com/recastnavigation/recastnavigation)
 - Recast/Detour (https://github.com/recastnavigation/recastnavigation)
 - SDL 2.0.10+ (https://www.libsdl.org)
 - SDL 2.0.10+ (https://www.libsdl.org)
 - SQLite 3.36.0 (https://www.sqlite.org)
 - SQLite 3.36.0 (https://www.sqlite.org)

+ 3 - 0
Source/ThirdParty/rapidjson/Urho3DNotes.txt

@@ -0,0 +1,3 @@
+URL: https://github.com/Tencent/rapidjson
+Date: 27.05.2022
+Latest commit: https://github.com/Tencent/rapidjson/commit/232389d4f1012dddec4ef84861face2d2ba85709

+ 477 - 56
Source/ThirdParty/rapidjson/include/rapidjson/allocators.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -16,6 +16,13 @@
 #define RAPIDJSON_ALLOCATORS_H_
 #define RAPIDJSON_ALLOCATORS_H_
 
 
 #include "rapidjson.h"
 #include "rapidjson.h"
+#include "internal/meta.h"
+
+#include <memory>
+
+#if RAPIDJSON_HAS_CXX11
+#include <type_traits>
+#endif
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
 
 
@@ -52,6 +59,19 @@ concept Allocator {
 \endcode
 \endcode
 */
 */
 
 
+
+/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
+    \ingroup RAPIDJSON_CONFIG
+    \brief User-defined kDefaultChunkCapacity definition.
+
+    User can define this as any \c size that is a power of 2.
+*/
+
+#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
+#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
+#endif
+
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // CrtAllocator
 // CrtAllocator
 
 
@@ -64,19 +84,26 @@ public:
     static const bool kNeedFree = true;
     static const bool kNeedFree = true;
     void* Malloc(size_t size) { 
     void* Malloc(size_t size) { 
         if (size) //  behavior of malloc(0) is implementation defined.
         if (size) //  behavior of malloc(0) is implementation defined.
-            return std::malloc(size);
+            return RAPIDJSON_MALLOC(size);
         else
         else
             return NULL; // standardize to returning NULL.
             return NULL; // standardize to returning NULL.
     }
     }
     void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
     void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
         (void)originalSize;
         (void)originalSize;
         if (newSize == 0) {
         if (newSize == 0) {
-            std::free(originalPtr);
+            RAPIDJSON_FREE(originalPtr);
             return NULL;
             return NULL;
         }
         }
-        return std::realloc(originalPtr, newSize);
+        return RAPIDJSON_REALLOC(originalPtr, newSize);
+    }
+    static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
+
+    bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
+        return true;
+    }
+    bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
+        return false;
     }
     }
-    static void Free(void *ptr) { std::free(ptr); }
 };
 };
 
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
@@ -100,16 +127,64 @@ public:
 */
 */
 template <typename BaseAllocator = CrtAllocator>
 template <typename BaseAllocator = CrtAllocator>
 class MemoryPoolAllocator {
 class MemoryPoolAllocator {
+    //! 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.
+    };
+
+    struct SharedData {
+        ChunkHeader *chunkHead;  //!< Head of the chunk linked-list. Only the head chunk serves allocation.
+        BaseAllocator* ownBaseAllocator; //!< base allocator created by this object.
+        size_t refcount;
+        bool ownBuffer;
+    };
+
+    static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
+    static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
+
+    static inline ChunkHeader *GetChunkHead(SharedData *shared)
+    {
+        return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
+    }
+    static inline uint8_t *GetChunkBuffer(SharedData *shared)
+    {
+        return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
+    }
+
+    static const size_t kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
+
 public:
 public:
     static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
     static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
+    static const bool kRefCounted = true;   //!< Tell users that this allocator is reference counted on copy
 
 
     //! Constructor with chunkSize.
     //! Constructor with chunkSize.
     /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
     /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
         \param baseAllocator The allocator for allocating memory chunks.
         \param baseAllocator The allocator for allocating memory chunks.
     */
     */
+    explicit
     MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 
     MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 
-        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+        chunk_capacity_(chunkSize),
+        baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
+        shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
     {
     {
+        RAPIDJSON_ASSERT(baseAllocator_ != 0);
+        RAPIDJSON_ASSERT(shared_ != 0);
+        if (baseAllocator) {
+            shared_->ownBaseAllocator = 0;
+        }
+        else {
+            shared_->ownBaseAllocator = baseAllocator_;
+        }
+        shared_->chunkHead = GetChunkHead(shared_);
+        shared_->chunkHead->capacity = 0;
+        shared_->chunkHead->size = 0;
+        shared_->chunkHead->next = 0;
+        shared_->ownBuffer = true;
+        shared_->refcount = 1;
     }
     }
 
 
     //! Constructor with user-supplied buffer.
     //! Constructor with user-supplied buffer.
@@ -123,41 +198,101 @@ public:
         \param baseAllocator The allocator for allocating memory chunks.
         \param baseAllocator The allocator for allocating memory chunks.
     */
     */
     MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
     MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
-        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+        chunk_capacity_(chunkSize),
+        baseAllocator_(baseAllocator),
+        shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
     {
     {
-        RAPIDJSON_ASSERT(buffer != 0);
-        RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
-        chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
-        chunkHead_->capacity = size - sizeof(ChunkHeader);
-        chunkHead_->size = 0;
-        chunkHead_->next = 0;
+        RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
+        shared_->chunkHead = GetChunkHead(shared_);
+        shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
+        shared_->chunkHead->size = 0;
+        shared_->chunkHead->next = 0;
+        shared_->ownBaseAllocator = 0;
+        shared_->ownBuffer = false;
+        shared_->refcount = 1;
     }
     }
 
 
+    MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
+        chunk_capacity_(rhs.chunk_capacity_),
+        baseAllocator_(rhs.baseAllocator_),
+        shared_(rhs.shared_)
+    {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+        ++shared_->refcount;
+    }
+    MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
+    {
+        RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+        ++rhs.shared_->refcount;
+        this->~MemoryPoolAllocator();
+        baseAllocator_ = rhs.baseAllocator_;
+        chunk_capacity_ = rhs.chunk_capacity_;
+        shared_ = rhs.shared_;
+        return *this;
+    }
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+    MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
+        chunk_capacity_(rhs.chunk_capacity_),
+        baseAllocator_(rhs.baseAllocator_),
+        shared_(rhs.shared_)
+    {
+        RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+        rhs.shared_ = 0;
+    }
+    MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
+    {
+        RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+        this->~MemoryPoolAllocator();
+        baseAllocator_ = rhs.baseAllocator_;
+        chunk_capacity_ = rhs.chunk_capacity_;
+        shared_ = rhs.shared_;
+        rhs.shared_ = 0;
+        return *this;
+    }
+#endif
+
     //! Destructor.
     //! Destructor.
     /*! This deallocates all memory chunks, excluding the user-supplied buffer.
     /*! This deallocates all memory chunks, excluding the user-supplied buffer.
     */
     */
-    ~MemoryPoolAllocator() {
+    ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
+        if (!shared_) {
+            // do nothing if moved
+            return;
+        }
+        if (shared_->refcount > 1) {
+            --shared_->refcount;
+            return;
+        }
         Clear();
         Clear();
-        RAPIDJSON_DELETE(ownBaseAllocator_);
+        BaseAllocator *a = shared_->ownBaseAllocator;
+        if (shared_->ownBuffer) {
+            baseAllocator_->Free(shared_);
+        }
+        RAPIDJSON_DELETE(a);
     }
     }
 
 
-    //! Deallocates all memory chunks, excluding the user-supplied buffer.
-    void Clear() {
-        while (chunkHead_ && chunkHead_ != userBuffer_) {
-            ChunkHeader* next = chunkHead_->next;
-            baseAllocator_->Free(chunkHead_);
-            chunkHead_ = next;
+    //! Deallocates all memory chunks, excluding the first/user one.
+    void Clear() RAPIDJSON_NOEXCEPT {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+        for (;;) {
+            ChunkHeader* c = shared_->chunkHead;
+            if (!c->next) {
+                break;
+            }
+            shared_->chunkHead = c->next;
+            baseAllocator_->Free(c);
         }
         }
-        if (chunkHead_ && chunkHead_ == userBuffer_)
-            chunkHead_->size = 0; // Clear user buffer
+        shared_->chunkHead->size = 0;
     }
     }
 
 
     //! Computes the total capacity of allocated memory chunks.
     //! Computes the total capacity of allocated memory chunks.
     /*! \return total capacity in bytes.
     /*! \return total capacity in bytes.
     */
     */
-    size_t Capacity() const {
+    size_t Capacity() const RAPIDJSON_NOEXCEPT {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
         size_t capacity = 0;
         size_t capacity = 0;
-        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+        for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
             capacity += c->capacity;
             capacity += c->capacity;
         return capacity;
         return capacity;
     }
     }
@@ -165,25 +300,35 @@ public:
     //! Computes the memory blocks allocated.
     //! Computes the memory blocks allocated.
     /*! \return total used bytes.
     /*! \return total used bytes.
     */
     */
-    size_t Size() const {
+    size_t Size() const RAPIDJSON_NOEXCEPT {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
         size_t size = 0;
         size_t size = 0;
-        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+        for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
             size += c->size;
             size += c->size;
         return size;
         return size;
     }
     }
 
 
+    //! Whether the allocator is shared.
+    /*! \return true or false.
+    */
+    bool Shared() const RAPIDJSON_NOEXCEPT {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+        return shared_->refcount > 1;
+    }
+
     //! Allocates a memory block. (concept Allocator)
     //! Allocates a memory block. (concept Allocator)
     void* Malloc(size_t size) {
     void* Malloc(size_t size) {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
         if (!size)
         if (!size)
             return NULL;
             return NULL;
 
 
         size = RAPIDJSON_ALIGN(size);
         size = RAPIDJSON_ALIGN(size);
-        if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
+        if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
             if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
             if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
                 return NULL;
                 return NULL;
 
 
-        void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
-        chunkHead_->size += size;
+        void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
+        shared_->chunkHead->size += size;
         return buffer;
         return buffer;
     }
     }
 
 
@@ -192,6 +337,7 @@ public:
         if (originalPtr == 0)
         if (originalPtr == 0)
             return Malloc(newSize);
             return Malloc(newSize);
 
 
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
         if (newSize == 0)
         if (newSize == 0)
             return NULL;
             return NULL;
 
 
@@ -203,10 +349,10 @@ public:
             return originalPtr;
             return originalPtr;
 
 
         // Simply expand it if it is the last allocation and there is sufficient space
         // Simply expand it if it is the last allocation and there is sufficient space
-        if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
+        if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) {
             size_t increment = static_cast<size_t>(newSize - originalSize);
             size_t increment = static_cast<size_t>(newSize - originalSize);
-            if (chunkHead_->size + increment <= chunkHead_->capacity) {
-                chunkHead_->size += increment;
+            if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
+                shared_->chunkHead->size += increment;
                 return originalPtr;
                 return originalPtr;
             }
             }
         }
         }
@@ -222,50 +368,325 @@ public:
     }
     }
 
 
     //! Frees a memory block (concept Allocator)
     //! Frees a memory block (concept Allocator)
-    static void Free(void *ptr) { (void)ptr; } // Do nothing
+    static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing
 
 
-private:
-    //! Copy constructor is not permitted.
-    MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
-    //! Copy assignment operator is not permitted.
-    MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
+    //! Compare (equality) with another MemoryPoolAllocator
+    bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
+        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
+        RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
+        return shared_ == rhs.shared_;
+    }
+    //! Compare (inequality) with another MemoryPoolAllocator
+    bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
+        return !operator==(rhs);
+    }
 
 
+private:
     //! Creates a new chunk.
     //! Creates a new chunk.
     /*! \param capacity Capacity of the chunk in bytes.
     /*! \param capacity Capacity of the chunk in bytes.
         \return true if success.
         \return true if success.
     */
     */
     bool AddChunk(size_t capacity) {
     bool AddChunk(size_t capacity) {
         if (!baseAllocator_)
         if (!baseAllocator_)
-            ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
-        if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
+            shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
+        if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
             chunk->capacity = capacity;
             chunk->capacity = capacity;
             chunk->size = 0;
             chunk->size = 0;
-            chunk->next = chunkHead_;
-            chunkHead_ =  chunk;
+            chunk->next = shared_->chunkHead;
+            shared_->chunkHead = chunk;
             return true;
             return true;
         }
         }
         else
         else
             return false;
             return false;
     }
     }
 
 
-    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.
-    };
+    static inline void* AlignBuffer(void* buf, size_t &size)
+    {
+        RAPIDJSON_NOEXCEPT_ASSERT(buf != 0);
+        const uintptr_t mask = sizeof(void*) - 1;
+        const uintptr_t ubuf = reinterpret_cast<uintptr_t>(buf);
+        if (RAPIDJSON_UNLIKELY(ubuf & mask)) {
+            const uintptr_t abuf = (ubuf + mask) & ~mask;
+            RAPIDJSON_ASSERT(size >= abuf - ubuf);
+            buf = reinterpret_cast<void*>(abuf);
+            size -= abuf - ubuf;
+        }
+        return buf;
+    }
 
 
-    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.
     size_t chunk_capacity_;     //!< The minimum capacity of chunk when they are allocated.
-    void *userBuffer_;          //!< User supplied buffer.
     BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.
     BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.
-    BaseAllocator* ownBaseAllocator_;   //!< base allocator created by this object.
+    SharedData *shared_;        //!< The shared data of the allocator
+};
+
+namespace internal {
+    template<typename, typename = void>
+    struct IsRefCounted :
+        public FalseType
+    { };
+    template<typename T>
+    struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> :
+        public TrueType
+    { };
+}
+
+template<typename T, typename A>
+inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
+{
+    RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
+    return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
+}
+
+template<typename T, typename A>
+inline T *Malloc(A& a, size_t n = 1)
+{
+    return Realloc<T, A>(a, NULL, 0, n);
+}
+
+template<typename T, typename A>
+inline void Free(A& a, T *p, size_t n = 1)
+{
+    static_cast<void>(Realloc<T, A>(a, p, n, 0));
+}
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
+#endif
+
+template <typename T, typename BaseAllocator = CrtAllocator>
+class StdAllocator :
+    public std::allocator<T>
+{
+    typedef std::allocator<T> allocator_type;
+#if RAPIDJSON_HAS_CXX11
+    typedef std::allocator_traits<allocator_type> traits_type;
+#else
+    typedef allocator_type traits_type;
+#endif
+
+public:
+    typedef BaseAllocator BaseAllocatorType;
+
+    StdAllocator() RAPIDJSON_NOEXCEPT :
+        allocator_type(),
+        baseAllocator_()
+    { }
+
+    StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+        allocator_type(rhs),
+        baseAllocator_(rhs.baseAllocator_)
+    { }
+
+    template<typename U>
+    StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
+        allocator_type(rhs),
+        baseAllocator_(rhs.baseAllocator_)
+    { }
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+    StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
+        allocator_type(std::move(rhs)),
+        baseAllocator_(std::move(rhs.baseAllocator_))
+    { }
+#endif
+#if RAPIDJSON_HAS_CXX11
+    using propagate_on_container_move_assignment = std::true_type;
+    using propagate_on_container_swap = std::true_type;
+#endif
+
+    /* implicit */
+    StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
+        allocator_type(),
+        baseAllocator_(allocator)
+    { }
+
+    ~StdAllocator() RAPIDJSON_NOEXCEPT
+    { }
+
+    template<typename U>
+    struct rebind {
+        typedef StdAllocator<U, BaseAllocator> other;
+    };
+
+    typedef typename traits_type::size_type         size_type;
+    typedef typename traits_type::difference_type   difference_type;
+
+    typedef typename traits_type::value_type        value_type;
+    typedef typename traits_type::pointer           pointer;
+    typedef typename traits_type::const_pointer     const_pointer;
+
+#if RAPIDJSON_HAS_CXX11
+
+    typedef typename std::add_lvalue_reference<value_type>::type &reference;
+    typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
+
+    pointer address(reference r) const RAPIDJSON_NOEXCEPT
+    {
+        return std::addressof(r);
+    }
+    const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
+    {
+        return std::addressof(r);
+    }
+
+    size_type max_size() const RAPIDJSON_NOEXCEPT
+    {
+        return traits_type::max_size(*this);
+    }
+
+    template <typename ...Args>
+    void construct(pointer p, Args&&... args)
+    {
+        traits_type::construct(*this, p, std::forward<Args>(args)...);
+    }
+    void destroy(pointer p)
+    {
+        traits_type::destroy(*this, p);
+    }
+
+#else // !RAPIDJSON_HAS_CXX11
+
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+
+    pointer address(reference r) const RAPIDJSON_NOEXCEPT
+    {
+        return allocator_type::address(r);
+    }
+    const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
+    {
+        return allocator_type::address(r);
+    }
+
+    size_type max_size() const RAPIDJSON_NOEXCEPT
+    {
+        return allocator_type::max_size();
+    }
+
+    void construct(pointer p, const_reference r)
+    {
+        allocator_type::construct(p, r);
+    }
+    void destroy(pointer p)
+    {
+        allocator_type::destroy(p);
+    }
+
+#endif // !RAPIDJSON_HAS_CXX11
+
+    template <typename U>
+    U* allocate(size_type n = 1, const void* = 0)
+    {
+        return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
+    }
+    template <typename U>
+    void deallocate(U* p, size_type n = 1)
+    {
+        RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
+    }
+
+    pointer allocate(size_type n = 1, const void* = 0)
+    {
+        return allocate<value_type>(n);
+    }
+    void deallocate(pointer p, size_type n = 1)
+    {
+        deallocate<value_type>(p, n);
+    }
+
+#if RAPIDJSON_HAS_CXX11
+    using is_always_equal = std::is_empty<BaseAllocator>;
+#endif
+
+    template<typename U>
+    bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
+    {
+        return baseAllocator_ == rhs.baseAllocator_;
+    }
+    template<typename U>
+    bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
+    {
+        return !operator==(rhs);
+    }
+
+    //! rapidjson Allocator concept
+    static const bool kNeedFree = BaseAllocator::kNeedFree;
+    static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
+    void* Malloc(size_t size)
+    {
+        return baseAllocator_.Malloc(size);
+    }
+    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
+    {
+        return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
+    }
+    static void Free(void *ptr) RAPIDJSON_NOEXCEPT
+    {
+        BaseAllocator::Free(ptr);
+    }
+
+private:
+    template <typename, typename>
+    friend class StdAllocator; // access to StdAllocator<!T>.*
+
+    BaseAllocator baseAllocator_;
 };
 };
 
 
+#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
+template <typename BaseAllocator>
+class StdAllocator<void, BaseAllocator> :
+    public std::allocator<void>
+{
+    typedef std::allocator<void> allocator_type;
+
+public:
+    typedef BaseAllocator BaseAllocatorType;
+
+    StdAllocator() RAPIDJSON_NOEXCEPT :
+        allocator_type(),
+        baseAllocator_()
+    { }
+
+    StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
+        allocator_type(rhs),
+        baseAllocator_(rhs.baseAllocator_)
+    { }
+
+    template<typename U>
+    StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
+        allocator_type(rhs),
+        baseAllocator_(rhs.baseAllocator_)
+    { }
+
+    /* implicit */
+    StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
+        allocator_type(),
+        baseAllocator_(baseAllocator)
+    { }
+
+    ~StdAllocator() RAPIDJSON_NOEXCEPT
+    { }
+
+    template<typename U>
+    struct rebind {
+        typedef StdAllocator<U, BaseAllocator> other;
+    };
+
+    typedef typename allocator_type::value_type value_type;
+
+private:
+    template <typename, typename>
+    friend class StdAllocator; // access to StdAllocator<!T>.*
+
+    BaseAllocator baseAllocator_;
+};
+#endif
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_POP
+#endif
+
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
 #endif // RAPIDJSON_ENCODINGS_H_
 #endif // RAPIDJSON_ENCODINGS_H_

+ 78 - 0
Source/ThirdParty/rapidjson/include/rapidjson/cursorstreamwrapper.h

@@ -0,0 +1,78 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
+#define RAPIDJSON_CURSORSTREAMWRAPPER_H_
+
+#include "stream.h"
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++)
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4702)  // unreachable code
+RAPIDJSON_DIAG_OFF(4512)  // assignment operator could not be generated
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+
+//! Cursor stream wrapper for counting line and column number if error exists.
+/*!
+    \tparam InputStream     Any stream that implements Stream Concept
+*/
+template <typename InputStream, typename Encoding = UTF8<> >
+class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
+public:
+    typedef typename Encoding::Ch Ch;
+
+    CursorStreamWrapper(InputStream& is):
+        GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
+
+    // counting line and column number
+    Ch Take() {
+        Ch ch = this->is_.Take();
+        if(ch == '\n') {
+            line_ ++;
+            col_ = 0;
+        } else {
+            col_ ++;
+        }
+        return ch;
+    }
+
+    //! Get the error line number, if error exists.
+    size_t GetLine() const { return line_; }
+    //! Get the error column number, if error exists.
+    size_t GetColumn() const { return col_; }
+
+private:
+    size_t line_;   //!< Current Line
+    size_t col_;    //!< Current Column
+};
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_POP
+#endif
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_POP
+#endif
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_

File diff suppressed because it is too large
+ 561 - 143
Source/ThirdParty/rapidjson/include/rapidjson/document.h


+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/encodedstream.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 41 - 41
Source/ThirdParty/rapidjson/include/rapidjson/encodings.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -17,7 +17,7 @@
 
 
 #include "rapidjson.h"
 #include "rapidjson.h"
 
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
 RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
 RAPIDJSON_DIAG_OFF(4702)  // unreachable code
 RAPIDJSON_DIAG_OFF(4702)  // unreachable code
@@ -144,9 +144,9 @@ struct UTF8 {
 
 
     template <typename InputStream>
     template <typename InputStream>
     static bool Decode(InputStream& is, unsigned* codepoint) {
     static bool Decode(InputStream& is, unsigned* codepoint) {
-#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
-#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
-#define TAIL() COPY(); TRANS(0x70)
+#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
+#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
+#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
         typename InputStream::Ch c = is.Take();
         typename InputStream::Ch c = is.Take();
         if (!(c & 0x80)) {
         if (!(c & 0x80)) {
             *codepoint = static_cast<unsigned char>(c);
             *codepoint = static_cast<unsigned char>(c);
@@ -161,44 +161,44 @@ struct UTF8 {
         }
         }
         bool result = true;
         bool result = true;
         switch (type) {
         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;
+        case 2: RAPIDJSON_TAIL(); return result;
+        case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
+        case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
+        case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
         default: return false;
         default: return false;
         }
         }
-#undef COPY
-#undef TRANS
-#undef TAIL
+#undef RAPIDJSON_COPY
+#undef RAPIDJSON_TRANS
+#undef RAPIDJSON_TAIL
     }
     }
 
 
     template <typename InputStream, typename OutputStream>
     template <typename InputStream, typename OutputStream>
     static bool Validate(InputStream& is, OutputStream& os) {
     static bool Validate(InputStream& is, OutputStream& os) {
-#define COPY() os.Put(c = is.Take())
-#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
-#define TAIL() COPY(); TRANS(0x70)
+#define RAPIDJSON_COPY() os.Put(c = is.Take())
+#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
+#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
         Ch c;
         Ch c;
-        COPY();
+        RAPIDJSON_COPY();
         if (!(c & 0x80))
         if (!(c & 0x80))
             return true;
             return true;
 
 
         bool result = true;
         bool result = true;
         switch (GetRange(static_cast<unsigned char>(c))) {
         switch (GetRange(static_cast<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;
+        case 2: RAPIDJSON_TAIL(); return result;
+        case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
+        case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
+        case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
+        case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
         default: return false;
         default: return false;
         }
         }
-#undef COPY
-#undef TRANS
-#undef TAIL
+#undef RAPIDJSON_COPY
+#undef RAPIDJSON_TRANS
+#undef RAPIDJSON_TAIL
     }
     }
 
 
     static unsigned char GetRange(unsigned char c) {
     static unsigned char GetRange(unsigned char c) {
@@ -384,7 +384,7 @@ struct UTF16BE : UTF16<CharType> {
     static CharType Take(InputByteStream& is) {
     static CharType Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
         unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
-        c |= static_cast<uint8_t>(is.Take());
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
         return static_cast<CharType>(c);
         return static_cast<CharType>(c);
     }
     }
 
 
@@ -620,28 +620,28 @@ struct AutoUTF {
 #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
 #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
 
 
     template<typename OutputStream>
     template<typename OutputStream>
-    RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {
+    static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {
         typedef void (*EncodeFunc)(OutputStream&, unsigned);
         typedef void (*EncodeFunc)(OutputStream&, unsigned);
         static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
         static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
         (*f[os.GetType()])(os, codepoint);
         (*f[os.GetType()])(os, codepoint);
     }
     }
 
 
     template<typename OutputStream>
     template<typename OutputStream>
-    RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
+    static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
         typedef void (*EncodeFunc)(OutputStream&, unsigned);
         typedef void (*EncodeFunc)(OutputStream&, unsigned);
         static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
         static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
         (*f[os.GetType()])(os, codepoint);
         (*f[os.GetType()])(os, codepoint);
     }
     }
 
 
     template <typename InputStream>
     template <typename InputStream>
-    RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
+    static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {
         typedef bool (*DecodeFunc)(InputStream&, unsigned*);
         typedef bool (*DecodeFunc)(InputStream&, unsigned*);
         static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
         static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
         return (*f[is.GetType()])(is, codepoint);
         return (*f[is.GetType()])(is, codepoint);
     }
     }
 
 
     template <typename InputStream, typename OutputStream>
     template <typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
         typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
         typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
         static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
         static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
         return (*f[is.GetType()])(is, os);
         return (*f[is.GetType()])(is, os);
@@ -658,7 +658,7 @@ template<typename SourceEncoding, typename TargetEncoding>
 struct Transcoder {
 struct Transcoder {
     //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
     //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
         unsigned codepoint;
         unsigned codepoint;
         if (!SourceEncoding::Decode(is, &codepoint))
         if (!SourceEncoding::Decode(is, &codepoint))
             return false;
             return false;
@@ -667,7 +667,7 @@ struct Transcoder {
     }
     }
 
 
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
         unsigned codepoint;
         unsigned codepoint;
         if (!SourceEncoding::Decode(is, &codepoint))
         if (!SourceEncoding::Decode(is, &codepoint))
             return false;
             return false;
@@ -677,7 +677,7 @@ struct Transcoder {
 
 
     //! Validate one Unicode codepoint from an encoded stream.
     //! Validate one Unicode codepoint from an encoded stream.
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
         return Transcode(is, os);   // Since source/target encoding is different, must transcode.
         return Transcode(is, os);   // Since source/target encoding is different, must transcode.
     }
     }
 };
 };
@@ -690,26 +690,26 @@ inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
 template<typename Encoding>
 template<typename Encoding>
 struct Transcoder<Encoding, Encoding> {
 struct Transcoder<Encoding, Encoding> {
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
         os.Put(is.Take());  // Just copy one code unit. This semantic is different from primary template class.
         os.Put(is.Take());  // Just copy one code unit. This semantic is different from primary template class.
         return true;
         return true;
     }
     }
     
     
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
         PutUnsafe(os, is.Take());  // Just copy one code unit. This semantic is different from primary template class.
         PutUnsafe(os, is.Take());  // Just copy one code unit. This semantic is different from primary template class.
         return true;
         return true;
     }
     }
     
     
     template<typename InputStream, typename OutputStream>
     template<typename InputStream, typename OutputStream>
-    RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
+    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
         return Encoding::Validate(is, os);  // source/target encoding are the same
         return Encoding::Validate(is, os);  // source/target encoding are the same
     }
     }
 };
 };
 
 
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#if defined(__GNUC__) || defined(_MSC_VER)
+#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 

+ 49 - 1
Source/ThirdParty/rapidjson/include/rapidjson/error/en.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -65,6 +65,54 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
     }
     }
 }
 }
 
 
+//! Maps error code of validation into error message.
+/*!
+    \ingroup RAPIDJSON_ERRORS
+    \param validateErrorCode Error code obtained from validator.
+    \return the error message.
+    \note User can make a copy of this function for localization.
+        Using switch-case is safer for future modification of error codes.
+*/
+inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) {
+    switch (validateErrorCode) {
+        case kValidateErrors:                           return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred");
+        case kValidateErrorNone:                        return RAPIDJSON_ERROR_STRING("No error.");
+
+        case kValidateErrorMultipleOf:                  return RAPIDJSON_ERROR_STRING("Number '%actual' is not a multiple of the 'multipleOf' value '%expected'.");
+        case kValidateErrorMaximum:                     return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than the 'maximum' value '%expected'.");
+        case kValidateErrorExclusiveMaximum:            return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than or equal to the 'exclusiveMaximum' value '%expected'.");
+        case kValidateErrorMinimum:                     return RAPIDJSON_ERROR_STRING("Number '%actual' is less than the 'minimum' value '%expected'.");
+        case kValidateErrorExclusiveMinimum:            return RAPIDJSON_ERROR_STRING("Number '%actual' is less than or equal to the 'exclusiveMinimum' value '%expected'.");
+
+        case kValidateErrorMaxLength:                   return RAPIDJSON_ERROR_STRING("String '%actual' is longer than the 'maxLength' value '%expected'.");
+        case kValidateErrorMinLength:                   return RAPIDJSON_ERROR_STRING("String '%actual' is shorter than the 'minLength' value '%expected'.");
+        case kValidateErrorPattern:                     return RAPIDJSON_ERROR_STRING("String '%actual' does not match the 'pattern' regular expression.");
+
+        case kValidateErrorMaxItems:                    return RAPIDJSON_ERROR_STRING("Array of length '%actual' is longer than the 'maxItems' value '%expected'.");
+        case kValidateErrorMinItems:                    return RAPIDJSON_ERROR_STRING("Array of length '%actual' is shorter than the 'minItems' value '%expected'.");
+        case kValidateErrorUniqueItems:                 return RAPIDJSON_ERROR_STRING("Array has duplicate items at indices '%duplicates' but 'uniqueItems' is true.");
+        case kValidateErrorAdditionalItems:             return RAPIDJSON_ERROR_STRING("Array has an additional item at index '%disallowed' that is not allowed by the schema.");
+
+        case kValidateErrorMaxProperties:               return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is more than 'maxProperties' value '%expected'.");
+        case kValidateErrorMinProperties:               return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is less than 'minProperties' value '%expected'.");
+        case kValidateErrorRequired:                    return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'.");
+        case kValidateErrorAdditionalProperties:        return RAPIDJSON_ERROR_STRING("Object has an additional member '%disallowed' that is not allowed by the schema.");
+        case kValidateErrorPatternProperties:           return RAPIDJSON_ERROR_STRING("Object has 'patternProperties' that are not allowed by the schema.");
+        case kValidateErrorDependencies:                return RAPIDJSON_ERROR_STRING("Object has missing property or schema dependencies, refer to following errors.");
+
+        case kValidateErrorEnum:                        return RAPIDJSON_ERROR_STRING("Property has a value that is not one of its allowed enumerated values.");
+        case kValidateErrorType:                        return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
+
+        case kValidateErrorOneOf:                       return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
+        case kValidateErrorOneOfMatch:                  return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
+        case kValidateErrorAllOf:                       return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
+        case kValidateErrorAnyOf:                       return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
+        case kValidateErrorNot:                         return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
+
+        default:                                        return RAPIDJSON_ERROR_STRING("Unknown error.");
+    }
+}
+
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
 #ifdef __clang__
 #ifdef __clang__

+ 64 - 3
Source/ThirdParty/rapidjson/include/rapidjson/error/error.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -104,6 +104,8 @@ enum ParseErrorCode {
     \see GenericReader::Parse, GenericDocument::Parse
     \see GenericReader::Parse, GenericDocument::Parse
 */
 */
 struct ParseResult {
 struct ParseResult {
+    //!! Unspecified boolean type
+    typedef bool (ParseResult::*BooleanType)() const;
 public:
 public:
     //! Default constructor, no error.
     //! Default constructor, no error.
     ParseResult() : code_(kParseErrorNone), offset_(0) {}
     ParseResult() : code_(kParseErrorNone), offset_(0) {}
@@ -115,8 +117,8 @@ public:
     //! Get the error offset, if \ref IsError(), 0 otherwise.
     //! Get the error offset, if \ref IsError(), 0 otherwise.
     size_t Offset() const { return offset_; }
     size_t Offset() const { return offset_; }
 
 
-    //! Conversion to \c bool, returns \c true, iff !\ref IsError().
-    operator bool() const { return !IsError(); }
+    //! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
+    operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
     //! Whether the result is an error.
     //! Whether the result is an error.
     bool IsError() const { return code_ != kParseErrorNone; }
     bool IsError() const { return code_ != kParseErrorNone; }
 
 
@@ -124,6 +126,10 @@ public:
     bool operator==(ParseErrorCode code) const { return code_ == code; }
     bool operator==(ParseErrorCode code) const { return code_ == code; }
     friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
     friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
 
 
+    bool operator!=(const ParseResult& that) const { return !(*this == that); }
+    bool operator!=(ParseErrorCode code) const { return !(*this == code); }
+    friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }
+
     //! Reset error code.
     //! Reset error code.
     void Clear() { Set(kParseErrorNone); }
     void Clear() { Set(kParseErrorNone); }
     //! Update error code and offset.
     //! Update error code and offset.
@@ -146,6 +152,61 @@ private:
 */
 */
 typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
 typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
 
 
+///////////////////////////////////////////////////////////////////////////////
+// ValidateErrorCode
+
+//! Error codes when validating.
+/*! \ingroup RAPIDJSON_ERRORS
+    \see GenericSchemaValidator
+*/
+enum ValidateErrorCode {
+    kValidateErrors    = -1,                   //!< Top level error code when kValidateContinueOnErrorsFlag set.
+    kValidateErrorNone = 0,                    //!< No error.
+
+    kValidateErrorMultipleOf,                  //!< Number is not a multiple of the 'multipleOf' value.
+    kValidateErrorMaximum,                     //!< Number is greater than the 'maximum' value.
+    kValidateErrorExclusiveMaximum,            //!< Number is greater than or equal to the 'maximum' value.
+    kValidateErrorMinimum,                     //!< Number is less than the 'minimum' value.
+    kValidateErrorExclusiveMinimum,            //!< Number is less than or equal to the 'minimum' value.
+
+    kValidateErrorMaxLength,                   //!< String is longer than the 'maxLength' value.
+    kValidateErrorMinLength,                   //!< String is longer than the 'maxLength' value.
+    kValidateErrorPattern,                     //!< String does not match the 'pattern' regular expression.
+
+    kValidateErrorMaxItems,                    //!< Array is longer than the 'maxItems' value.
+    kValidateErrorMinItems,                    //!< Array is shorter than the 'minItems' value.
+    kValidateErrorUniqueItems,                 //!< Array has duplicate items but 'uniqueItems' is true.
+    kValidateErrorAdditionalItems,             //!< Array has additional items that are not allowed by the schema.
+
+    kValidateErrorMaxProperties,               //!< Object has more members than 'maxProperties' value.
+    kValidateErrorMinProperties,               //!< Object has less members than 'minProperties' value.
+    kValidateErrorRequired,                    //!< Object is missing one or more members required by the schema.
+    kValidateErrorAdditionalProperties,        //!< Object has additional members that are not allowed by the schema.
+    kValidateErrorPatternProperties,           //!< See other errors.
+    kValidateErrorDependencies,                //!< Object has missing property or schema dependencies.
+
+    kValidateErrorEnum,                        //!< Property has a value that is not one of its allowed enumerated values
+    kValidateErrorType,                        //!< Property has a type that is not allowed by the schema..
+
+    kValidateErrorOneOf,                       //!< Property did not match any of the sub-schemas specified by 'oneOf'.
+    kValidateErrorOneOfMatch,                  //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
+    kValidateErrorAllOf,                       //!< Property did not match all of the sub-schemas specified by 'allOf'.
+    kValidateErrorAnyOf,                       //!< Property did not match any of the sub-schemas specified by 'anyOf'.
+    kValidateErrorNot                          //!< Property matched the sub-schema specified by 'not'.
+};
+
+//! Function pointer type of GetValidateError().
+/*! \ingroup RAPIDJSON_ERRORS
+
+    This is the prototype for \c GetValidateError_X(), where \c X is a locale.
+    User can dynamically change locale in runtime, e.g.:
+\code
+    GetValidateErrorFunc GetValidateError = GetValidateError_En; // or whatever
+    const RAPIDJSON_ERROR_CHARTYPE* s = GetValidateError(validator.GetInvalidSchemaCode());
+\endcode
+*/
+typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
+
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
 #ifdef __clang__
 #ifdef __clang__

+ 3 - 3
Source/ThirdParty/rapidjson/include/rapidjson/filereadstream.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -59,7 +59,7 @@ public:
 
 
     // For encoding detection only.
     // For encoding detection only.
     const Ch* Peek4() const {
     const Ch* Peek4() const {
-        return (current_ + 4 <= bufferLast_) ? current_ : 0;
+        return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
     }
     }
 
 
 private:
 private:
@@ -68,7 +68,7 @@ private:
             ++current_;
             ++current_;
         else if (!eof_) {
         else if (!eof_) {
             count_ += readCount_;
             count_ += readCount_;
-            readCount_ = fread(buffer_, 1, bufferSize_, fp_);
+            readCount_ = std::fread(buffer_, 1, bufferSize_, fp_);
             bufferLast_ = buffer_ + readCount_ - 1;
             bufferLast_ = buffer_ + readCount_ - 1;
             current_ = buffer_;
             current_ = buffer_;
 
 

+ 3 - 3
Source/ThirdParty/rapidjson/include/rapidjson/filewritestream.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -25,7 +25,7 @@ RAPIDJSON_DIAG_OFF(unreachable-code)
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
 
 
-//! Wrapper of C file stream for input using fread().
+//! Wrapper of C file stream for output using fwrite().
 /*!
 /*!
     \note implements Stream concept
     \note implements Stream concept
 */
 */
@@ -62,7 +62,7 @@ public:
 
 
     void Flush() {
     void Flush() {
         if (current_ != buffer_) {
         if (current_ != buffer_) {
-            size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
+            size_t result = std::fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
             if (result < static_cast<size_t>(current_ - buffer_)) {
             if (result < static_cast<size_t>(current_ - buffer_)) {
                 // failure deliberately ignored at this time
                 // failure deliberately ignored at this time
                 // added to avoid warn_unused_result build errors
                 // added to avoid warn_unused_result build errors

+ 2 - 2
Source/ThirdParty/rapidjson/include/rapidjson/fwd.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -102,7 +102,7 @@ class PrettyWriter;
 // document.h
 // document.h
 
 
 template <typename Encoding, typename Allocator> 
 template <typename Encoding, typename Allocator> 
-struct GenericMember;
+class GenericMember;
 
 
 template <bool Const, typename Encoding, typename Allocator>
 template <bool Const, typename Encoding, typename Allocator>
 class GenericMemberIterator;
 class GenericMemberIterator;

+ 16 - 9
Source/ThirdParty/rapidjson/include/rapidjson/internal/biginteger.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -17,9 +17,13 @@
 
 
 #include "../rapidjson.h"
 #include "../rapidjson.h"
 
 
-#if defined(_MSC_VER) && defined(_M_AMD64)
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
 #include <intrin.h> // for _umul128
 #include <intrin.h> // for _umul128
+#if !defined(_ARM64EC_)
 #pragma intrinsic(_umul128)
 #pragma intrinsic(_umul128)
+#else
+#pragma comment(lib,"softintrin")
+#endif
 #endif
 #endif
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
@@ -37,7 +41,8 @@ public:
         digits_[0] = u;
         digits_[0] = u;
     }
     }
 
 
-    BigInteger(const char* decimals, size_t length) : count_(1) {
+    template<typename Ch>
+    BigInteger(const Ch* decimals, size_t length) : count_(1) {
         RAPIDJSON_ASSERT(length > 0);
         RAPIDJSON_ASSERT(length > 0);
         digits_[0] = 0;
         digits_[0] = 0;
         size_t i = 0;
         size_t i = 0;
@@ -133,7 +138,7 @@ public:
         RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
         RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
 
 
         if (interShift == 0) {
         if (interShift == 0) {
-            std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
+            std::memmove(digits_ + offset, digits_, count_ * sizeof(Type));
             count_ += offset;
             count_ += offset;
         }
         }
         else {
         else {
@@ -221,7 +226,8 @@ public:
     bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
     bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
 
 
 private:
 private:
-    void AppendDecimal64(const char* begin, const char* end) {
+    template<typename Ch>
+    void AppendDecimal64(const Ch* begin, const Ch* end) {
         uint64_t u = ParseUint64(begin, end);
         uint64_t u = ParseUint64(begin, end);
         if (IsZero())
         if (IsZero())
             *this = u;
             *this = u;
@@ -236,11 +242,12 @@ private:
         digits_[count_++] = digit;
         digits_[count_++] = digit;
     }
     }
 
 
-    static uint64_t ParseUint64(const char* begin, const char* end) {
+    template<typename Ch>
+    static uint64_t ParseUint64(const Ch* begin, const Ch* end) {
         uint64_t r = 0;
         uint64_t r = 0;
-        for (const char* p = begin; p != end; ++p) {
-            RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
-            r = r * 10u + static_cast<unsigned>(*p - '0');
+        for (const Ch* p = begin; p != end; ++p) {
+            RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9'));
+            r = r * 10u + static_cast<unsigned>(*p - Ch('0'));
         }
         }
         return r;
         return r;
     }
     }

+ 71 - 0
Source/ThirdParty/rapidjson/include/rapidjson/internal/clzll.h

@@ -0,0 +1,71 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_CLZLL_H_
+#define RAPIDJSON_CLZLL_H_
+
+#include "../rapidjson.h"
+
+#if defined(_MSC_VER) && !defined(UNDER_CE)
+#include <intrin.h>
+#if defined(_WIN64)
+#pragma intrinsic(_BitScanReverse64)
+#else
+#pragma intrinsic(_BitScanReverse)
+#endif
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+namespace internal {
+
+inline uint32_t clzll(uint64_t x) {
+    // Passing 0 to __builtin_clzll is UB in GCC and results in an
+    // infinite loop in the software implementation.
+    RAPIDJSON_ASSERT(x != 0);
+
+#if defined(_MSC_VER) && !defined(UNDER_CE)
+    unsigned long r = 0;
+#if defined(_WIN64)
+    _BitScanReverse64(&r, x);
+#else
+    // Scan the high 32 bits.
+    if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
+        return 63 - (r + 32);
+
+    // Scan the low 32 bits.
+    _BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF));
+#endif // _WIN64
+
+    return 63 - r;
+#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
+    // __builtin_clzll wrapper
+    return static_cast<uint32_t>(__builtin_clzll(x));
+#else
+    // naive version
+    uint32_t r = 0;
+    while (!(x & (static_cast<uint64_t>(1) << 63))) {
+        x <<= 1;
+        ++r;
+    }
+
+    return r;
+#endif // _MSC_VER
+}
+
+#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
+
+} // namespace internal
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_CLZLL_H_

+ 31 - 28
Source/ThirdParty/rapidjson/include/rapidjson/internal/diyfp.h

@@ -1,15 +1,15 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
-// 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
 //
 //
 // http://opensource.org/licenses/MIT
 // http://opensource.org/licenses/MIT
 //
 //
-// Unless required by applicable law or agreed to in writing, software distributed 
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
 // specific language governing permissions and limitations under the License.
 // specific language governing permissions and limitations under the License.
 
 
 // This is a C++ header-only implementation of Grisu2 algorithm from the publication:
 // This is a C++ header-only implementation of Grisu2 algorithm from the publication:
@@ -20,11 +20,16 @@
 #define RAPIDJSON_DIYFP_H_
 #define RAPIDJSON_DIYFP_H_
 
 
 #include "../rapidjson.h"
 #include "../rapidjson.h"
+#include "clzll.h"
+#include <limits>
 
 
-#if defined(_MSC_VER) && defined(_M_AMD64)
+#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
 #include <intrin.h>
 #include <intrin.h>
-#pragma intrinsic(_BitScanReverse64)
+#if !defined(_ARM64EC_)
 #pragma intrinsic(_umul128)
 #pragma intrinsic(_umul128)
+#else
+#pragma comment(lib,"softintrin")
+#endif
 #endif
 #endif
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
@@ -56,7 +61,7 @@ struct DiyFp {
         if (biased_e != 0) {
         if (biased_e != 0) {
             f = significand + kDpHiddenBit;
             f = significand + kDpHiddenBit;
             e = biased_e - kDpExponentBias;
             e = biased_e - kDpExponentBias;
-        } 
+        }
         else {
         else {
             f = significand;
             f = significand;
             e = kDpMinExponent + 1;
             e = kDpMinExponent + 1;
@@ -99,21 +104,8 @@ struct DiyFp {
     }
     }
 
 
     DiyFp Normalize() const {
     DiyFp Normalize() const {
-#if defined(_MSC_VER) && defined(_M_AMD64)
-        unsigned long index;
-        _BitScanReverse64(&index, f);
-        return DiyFp(f << (63 - index), e - (63 - index));
-#elif defined(__GNUC__) && __GNUC__ >= 4
-        int s = __builtin_clzll(f);
+        int s = static_cast<int>(clzll(f));
         return DiyFp(f << s, e - s);
         return DiyFp(f << s, e - s);
-#else
-        DiyFp res = *this;
-        while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
-            res.f <<= 1;
-            res.e--;
-        }
-        return res;
-#endif
     }
     }
 
 
     DiyFp NormalizeBoundary() const {
     DiyFp NormalizeBoundary() const {
@@ -141,7 +133,16 @@ struct DiyFp {
             double d;
             double d;
             uint64_t u64;
             uint64_t u64;
         }u;
         }u;
-        const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : 
+        RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask);
+        if (e < kDpDenormalExponent) {
+            // Underflow.
+            return 0.0;
+        }
+        if (e >= kDpMaxExponent) {
+            // Overflow.
+            return std::numeric_limits<double>::infinity();
+        }
+        const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
             static_cast<uint64_t>(e + kDpExponentBias);
             static_cast<uint64_t>(e + kDpExponentBias);
         u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
         u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
         return u.d;
         return u.d;
@@ -220,9 +221,10 @@ inline DiyFp GetCachedPowerByIndex(size_t index) {
         641,   667,   694,   720,   747,   774,   800,   827,   853,   880,
         641,   667,   694,   720,   747,   774,   800,   827,   853,   880,
         907,   933,   960,   986,  1013,  1039,  1066
         907,   933,   960,   986,  1013,  1039,  1066
     };
     };
+    RAPIDJSON_ASSERT(index < 87);
     return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
     return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
 }
 }
-    
+
 inline DiyFp GetCachedPower(int e, int* K) {
 inline DiyFp GetCachedPower(int e, int* K) {
 
 
     //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
     //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
@@ -238,10 +240,11 @@ inline DiyFp GetCachedPower(int e, int* K) {
 }
 }
 
 
 inline DiyFp GetCachedPower10(int exp, int *outExp) {
 inline DiyFp GetCachedPower10(int exp, int *outExp) {
-     unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
-     *outExp = -348 + static_cast<int>(index) * 8;
-     return GetCachedPowerByIndex(index);
- }
+    RAPIDJSON_ASSERT(exp >= -348);
+    unsigned index = static_cast<unsigned>(exp + 348) / 8u;
+    *outExp = -348 + static_cast<int>(index) * 8;
+    return GetCachedPowerByIndex(index);
+}
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP

+ 8 - 4
Source/ThirdParty/rapidjson/include/rapidjson/internal/dtoa.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -58,7 +58,11 @@ inline int CountDecimalDigit32(uint32_t n) {
 }
 }
 
 
 inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
 inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
-    static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
+    static const uint64_t kPow10[] = { 1U, 10U, 100U, 1000U, 10000U, 100000U, 1000000U, 10000000U, 100000000U,
+                                       1000000000U, 10000000000U, 100000000000U, 1000000000000U,
+                                       10000000000000U, 100000000000000U, 1000000000000000U,
+                                       10000000000000000U, 100000000000000000U, 1000000000000000000U,
+                                       10000000000000000000U };
     const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
     const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
     const DiyFp wp_w = Mp - W;
     const DiyFp wp_w = Mp - W;
     uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
     uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
@@ -86,7 +90,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
         uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
         uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
         if (tmp <= delta) {
         if (tmp <= delta) {
             *K += kappa;
             *K += kappa;
-            GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
+            GrisuRound(buffer, *len, delta, tmp, kPow10[kappa] << -one.e, wp_w.f);
             return;
             return;
         }
         }
     }
     }
@@ -103,7 +107,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
         if (p2 < delta) {
         if (p2 < delta) {
             *K += kappa;
             *K += kappa;
             int index = -kappa;
             int index = -kappa;
-            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
+            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 20 ? kPow10[index] : 0));
             return;
             return;
         }
         }
     }
     }

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/internal/ieee754.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 44 - 40
Source/ThirdParty/rapidjson/include/rapidjson/internal/itoa.h

@@ -1,15 +1,15 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
-// 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
 //
 //
 // http://opensource.org/licenses/MIT
 // http://opensource.org/licenses/MIT
 //
 //
-// Unless required by applicable law or agreed to in writing, software distributed 
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
 // specific language governing permissions and limitations under the License.
 // specific language governing permissions and limitations under the License.
 
 
 #ifndef RAPIDJSON_ITOA_
 #ifndef RAPIDJSON_ITOA_
@@ -37,12 +37,14 @@ inline const char* GetDigitsLut() {
 }
 }
 
 
 inline char* u32toa(uint32_t value, char* buffer) {
 inline char* u32toa(uint32_t value, char* buffer) {
+    RAPIDJSON_ASSERT(buffer != 0);
+
     const char* cDigitsLut = GetDigitsLut();
     const char* cDigitsLut = GetDigitsLut();
 
 
     if (value < 10000) {
     if (value < 10000) {
         const uint32_t d1 = (value / 100) << 1;
         const uint32_t d1 = (value / 100) << 1;
         const uint32_t d2 = (value % 100) << 1;
         const uint32_t d2 = (value % 100) << 1;
-        
+
         if (value >= 1000)
         if (value >= 1000)
             *buffer++ = cDigitsLut[d1];
             *buffer++ = cDigitsLut[d1];
         if (value >= 100)
         if (value >= 100)
@@ -55,13 +57,13 @@ inline char* u32toa(uint32_t value, char* buffer) {
         // value = bbbbcccc
         // value = bbbbcccc
         const uint32_t b = value / 10000;
         const uint32_t b = value / 10000;
         const uint32_t c = value % 10000;
         const uint32_t c = value % 10000;
-        
+
         const uint32_t d1 = (b / 100) << 1;
         const uint32_t d1 = (b / 100) << 1;
         const uint32_t d2 = (b % 100) << 1;
         const uint32_t d2 = (b % 100) << 1;
-        
+
         const uint32_t d3 = (c / 100) << 1;
         const uint32_t d3 = (c / 100) << 1;
         const uint32_t d4 = (c % 100) << 1;
         const uint32_t d4 = (c % 100) << 1;
-        
+
         if (value >= 10000000)
         if (value >= 10000000)
             *buffer++ = cDigitsLut[d1];
             *buffer++ = cDigitsLut[d1];
         if (value >= 1000000)
         if (value >= 1000000)
@@ -69,7 +71,7 @@ inline char* u32toa(uint32_t value, char* buffer) {
         if (value >= 100000)
         if (value >= 100000)
             *buffer++ = cDigitsLut[d2];
             *buffer++ = cDigitsLut[d2];
         *buffer++ = cDigitsLut[d2 + 1];
         *buffer++ = cDigitsLut[d2 + 1];
-        
+
         *buffer++ = cDigitsLut[d3];
         *buffer++ = cDigitsLut[d3];
         *buffer++ = cDigitsLut[d3 + 1];
         *buffer++ = cDigitsLut[d3 + 1];
         *buffer++ = cDigitsLut[d4];
         *buffer++ = cDigitsLut[d4];
@@ -77,10 +79,10 @@ inline char* u32toa(uint32_t value, char* buffer) {
     }
     }
     else {
     else {
         // value = aabbbbcccc in decimal
         // value = aabbbbcccc in decimal
-        
+
         const uint32_t a = value / 100000000; // 1 to 42
         const uint32_t a = value / 100000000; // 1 to 42
         value %= 100000000;
         value %= 100000000;
-        
+
         if (a >= 10) {
         if (a >= 10) {
             const unsigned i = a << 1;
             const unsigned i = a << 1;
             *buffer++ = cDigitsLut[i];
             *buffer++ = cDigitsLut[i];
@@ -91,13 +93,13 @@ inline char* u32toa(uint32_t value, char* buffer) {
 
 
         const uint32_t b = value / 10000; // 0 to 9999
         const uint32_t b = value / 10000; // 0 to 9999
         const uint32_t c = value % 10000; // 0 to 9999
         const uint32_t c = value % 10000; // 0 to 9999
-        
+
         const uint32_t d1 = (b / 100) << 1;
         const uint32_t d1 = (b / 100) << 1;
         const uint32_t d2 = (b % 100) << 1;
         const uint32_t d2 = (b % 100) << 1;
-        
+
         const uint32_t d3 = (c / 100) << 1;
         const uint32_t d3 = (c / 100) << 1;
         const uint32_t d4 = (c % 100) << 1;
         const uint32_t d4 = (c % 100) << 1;
-        
+
         *buffer++ = cDigitsLut[d1];
         *buffer++ = cDigitsLut[d1];
         *buffer++ = cDigitsLut[d1 + 1];
         *buffer++ = cDigitsLut[d1 + 1];
         *buffer++ = cDigitsLut[d2];
         *buffer++ = cDigitsLut[d2];
@@ -111,6 +113,7 @@ inline char* u32toa(uint32_t value, char* buffer) {
 }
 }
 
 
 inline char* i32toa(int32_t value, char* buffer) {
 inline char* i32toa(int32_t value, char* buffer) {
+    RAPIDJSON_ASSERT(buffer != 0);
     uint32_t u = static_cast<uint32_t>(value);
     uint32_t u = static_cast<uint32_t>(value);
     if (value < 0) {
     if (value < 0) {
         *buffer++ = '-';
         *buffer++ = '-';
@@ -121,6 +124,7 @@ inline char* i32toa(int32_t value, char* buffer) {
 }
 }
 
 
 inline char* u64toa(uint64_t value, char* buffer) {
 inline char* u64toa(uint64_t value, char* buffer) {
+    RAPIDJSON_ASSERT(buffer != 0);
     const char* cDigitsLut = GetDigitsLut();
     const char* cDigitsLut = GetDigitsLut();
     const uint64_t  kTen8 = 100000000;
     const uint64_t  kTen8 = 100000000;
     const uint64_t  kTen9 = kTen8 * 10;
     const uint64_t  kTen9 = kTen8 * 10;
@@ -131,13 +135,13 @@ inline char* u64toa(uint64_t value, char* buffer) {
     const uint64_t kTen14 = kTen8 * 1000000;
     const uint64_t kTen14 = kTen8 * 1000000;
     const uint64_t kTen15 = kTen8 * 10000000;
     const uint64_t kTen15 = kTen8 * 10000000;
     const uint64_t kTen16 = kTen8 * kTen8;
     const uint64_t kTen16 = kTen8 * kTen8;
-    
+
     if (value < kTen8) {
     if (value < kTen8) {
         uint32_t v = static_cast<uint32_t>(value);
         uint32_t v = static_cast<uint32_t>(value);
         if (v < 10000) {
         if (v < 10000) {
             const uint32_t d1 = (v / 100) << 1;
             const uint32_t d1 = (v / 100) << 1;
             const uint32_t d2 = (v % 100) << 1;
             const uint32_t d2 = (v % 100) << 1;
-            
+
             if (v >= 1000)
             if (v >= 1000)
                 *buffer++ = cDigitsLut[d1];
                 *buffer++ = cDigitsLut[d1];
             if (v >= 100)
             if (v >= 100)
@@ -150,13 +154,13 @@ inline char* u64toa(uint64_t value, char* buffer) {
             // value = bbbbcccc
             // value = bbbbcccc
             const uint32_t b = v / 10000;
             const uint32_t b = v / 10000;
             const uint32_t c = v % 10000;
             const uint32_t c = v % 10000;
-            
+
             const uint32_t d1 = (b / 100) << 1;
             const uint32_t d1 = (b / 100) << 1;
             const uint32_t d2 = (b % 100) << 1;
             const uint32_t d2 = (b % 100) << 1;
-            
+
             const uint32_t d3 = (c / 100) << 1;
             const uint32_t d3 = (c / 100) << 1;
             const uint32_t d4 = (c % 100) << 1;
             const uint32_t d4 = (c % 100) << 1;
-            
+
             if (value >= 10000000)
             if (value >= 10000000)
                 *buffer++ = cDigitsLut[d1];
                 *buffer++ = cDigitsLut[d1];
             if (value >= 1000000)
             if (value >= 1000000)
@@ -164,7 +168,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
             if (value >= 100000)
             if (value >= 100000)
                 *buffer++ = cDigitsLut[d2];
                 *buffer++ = cDigitsLut[d2];
             *buffer++ = cDigitsLut[d2 + 1];
             *buffer++ = cDigitsLut[d2 + 1];
-            
+
             *buffer++ = cDigitsLut[d3];
             *buffer++ = cDigitsLut[d3];
             *buffer++ = cDigitsLut[d3 + 1];
             *buffer++ = cDigitsLut[d3 + 1];
             *buffer++ = cDigitsLut[d4];
             *buffer++ = cDigitsLut[d4];
@@ -174,22 +178,22 @@ inline char* u64toa(uint64_t value, char* buffer) {
     else if (value < kTen16) {
     else if (value < kTen16) {
         const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
         const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
         const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
         const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
-        
+
         const uint32_t b0 = v0 / 10000;
         const uint32_t b0 = v0 / 10000;
         const uint32_t c0 = v0 % 10000;
         const uint32_t c0 = v0 % 10000;
-        
+
         const uint32_t d1 = (b0 / 100) << 1;
         const uint32_t d1 = (b0 / 100) << 1;
         const uint32_t d2 = (b0 % 100) << 1;
         const uint32_t d2 = (b0 % 100) << 1;
-        
+
         const uint32_t d3 = (c0 / 100) << 1;
         const uint32_t d3 = (c0 / 100) << 1;
         const uint32_t d4 = (c0 % 100) << 1;
         const uint32_t d4 = (c0 % 100) << 1;
 
 
         const uint32_t b1 = v1 / 10000;
         const uint32_t b1 = v1 / 10000;
         const uint32_t c1 = v1 % 10000;
         const uint32_t c1 = v1 % 10000;
-        
+
         const uint32_t d5 = (b1 / 100) << 1;
         const uint32_t d5 = (b1 / 100) << 1;
         const uint32_t d6 = (b1 % 100) << 1;
         const uint32_t d6 = (b1 % 100) << 1;
-        
+
         const uint32_t d7 = (c1 / 100) << 1;
         const uint32_t d7 = (c1 / 100) << 1;
         const uint32_t d8 = (c1 % 100) << 1;
         const uint32_t d8 = (c1 % 100) << 1;
 
 
@@ -207,9 +211,8 @@ inline char* u64toa(uint64_t value, char* buffer) {
             *buffer++ = cDigitsLut[d3 + 1];
             *buffer++ = cDigitsLut[d3 + 1];
         if (value >= kTen9)
         if (value >= kTen9)
             *buffer++ = cDigitsLut[d4];
             *buffer++ = cDigitsLut[d4];
-        if (value >= kTen8)
-            *buffer++ = cDigitsLut[d4 + 1];
-        
+
+        *buffer++ = cDigitsLut[d4 + 1];
         *buffer++ = cDigitsLut[d5];
         *buffer++ = cDigitsLut[d5];
         *buffer++ = cDigitsLut[d5 + 1];
         *buffer++ = cDigitsLut[d5 + 1];
         *buffer++ = cDigitsLut[d6];
         *buffer++ = cDigitsLut[d6];
@@ -222,7 +225,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
     else {
     else {
         const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
         const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
         value %= kTen16;
         value %= kTen16;
-        
+
         if (a < 10)
         if (a < 10)
             *buffer++ = static_cast<char>('0' + static_cast<char>(a));
             *buffer++ = static_cast<char>('0' + static_cast<char>(a));
         else if (a < 100) {
         else if (a < 100) {
@@ -232,7 +235,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
         }
         }
         else if (a < 1000) {
         else if (a < 1000) {
             *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
             *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
-            
+
             const uint32_t i = (a % 100) << 1;
             const uint32_t i = (a % 100) << 1;
             *buffer++ = cDigitsLut[i];
             *buffer++ = cDigitsLut[i];
             *buffer++ = cDigitsLut[i + 1];
             *buffer++ = cDigitsLut[i + 1];
@@ -245,28 +248,28 @@ inline char* u64toa(uint64_t value, char* buffer) {
             *buffer++ = cDigitsLut[j];
             *buffer++ = cDigitsLut[j];
             *buffer++ = cDigitsLut[j + 1];
             *buffer++ = cDigitsLut[j + 1];
         }
         }
-        
+
         const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
         const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
         const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
         const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
-        
+
         const uint32_t b0 = v0 / 10000;
         const uint32_t b0 = v0 / 10000;
         const uint32_t c0 = v0 % 10000;
         const uint32_t c0 = v0 % 10000;
-        
+
         const uint32_t d1 = (b0 / 100) << 1;
         const uint32_t d1 = (b0 / 100) << 1;
         const uint32_t d2 = (b0 % 100) << 1;
         const uint32_t d2 = (b0 % 100) << 1;
-        
+
         const uint32_t d3 = (c0 / 100) << 1;
         const uint32_t d3 = (c0 / 100) << 1;
         const uint32_t d4 = (c0 % 100) << 1;
         const uint32_t d4 = (c0 % 100) << 1;
-        
+
         const uint32_t b1 = v1 / 10000;
         const uint32_t b1 = v1 / 10000;
         const uint32_t c1 = v1 % 10000;
         const uint32_t c1 = v1 % 10000;
-        
+
         const uint32_t d5 = (b1 / 100) << 1;
         const uint32_t d5 = (b1 / 100) << 1;
         const uint32_t d6 = (b1 % 100) << 1;
         const uint32_t d6 = (b1 % 100) << 1;
-        
+
         const uint32_t d7 = (c1 / 100) << 1;
         const uint32_t d7 = (c1 / 100) << 1;
         const uint32_t d8 = (c1 % 100) << 1;
         const uint32_t d8 = (c1 % 100) << 1;
-        
+
         *buffer++ = cDigitsLut[d1];
         *buffer++ = cDigitsLut[d1];
         *buffer++ = cDigitsLut[d1 + 1];
         *buffer++ = cDigitsLut[d1 + 1];
         *buffer++ = cDigitsLut[d2];
         *buffer++ = cDigitsLut[d2];
@@ -284,11 +287,12 @@ inline char* u64toa(uint64_t value, char* buffer) {
         *buffer++ = cDigitsLut[d8];
         *buffer++ = cDigitsLut[d8];
         *buffer++ = cDigitsLut[d8 + 1];
         *buffer++ = cDigitsLut[d8 + 1];
     }
     }
-    
+
     return buffer;
     return buffer;
 }
 }
 
 
 inline char* i64toa(int64_t value, char* buffer) {
 inline char* i64toa(int64_t value, char* buffer) {
+    RAPIDJSON_ASSERT(buffer != 0);
     uint64_t u = static_cast<uint64_t>(value);
     uint64_t u = static_cast<uint64_t>(value);
     if (value < 0) {
     if (value < 0) {
         *buffer++ = '-';
         *buffer++ = '-';

+ 8 - 3
Source/ThirdParty/rapidjson/include/rapidjson/internal/meta.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -21,7 +21,8 @@
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(effc++)
 RAPIDJSON_DIAG_OFF(effc++)
 #endif
 #endif
-#if defined(_MSC_VER)
+
+#if defined(_MSC_VER) && !defined(__clang__)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(6334)
 RAPIDJSON_DIAG_OFF(6334)
 #endif
 #endif
@@ -174,7 +175,11 @@ template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type;
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 //@endcond
 //@endcond
 
 
-#if defined(__GNUC__) || defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
+RAPIDJSON_DIAG_POP
+#endif
+
+#ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/internal/pow10.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 25 - 20
Source/ThirdParty/rapidjson/include/rapidjson/internal/regex.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -23,20 +23,14 @@
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(switch-enum)
 RAPIDJSON_DIAG_OFF(switch-enum)
-RAPIDJSON_DIAG_OFF(implicit-fallthrough)
+#elif defined(_MSC_VER)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
 #endif
 #endif
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(effc++)
 RAPIDJSON_DIAG_OFF(effc++)
-#if __GNUC__ >= 7
-RAPIDJSON_DIAG_OFF(implicit-fallthrough)
-#endif
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
 #endif
 #endif
 
 
 #ifndef RAPIDJSON_REGEX_VERBOSE
 #ifndef RAPIDJSON_REGEX_VERBOSE
@@ -120,7 +114,8 @@ public:
     template <typename, typename> friend class GenericRegexSearch;
     template <typename, typename> friend class GenericRegexSearch;
 
 
     GenericRegex(const Ch* source, Allocator* allocator = 0) : 
     GenericRegex(const Ch* source, Allocator* allocator = 0) : 
-        states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), 
+        ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_), 
+        states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), 
         anchorBegin_(), anchorEnd_()
         anchorBegin_(), anchorEnd_()
     {
     {
         GenericStringStream<Encoding> ss(source);
         GenericStringStream<Encoding> ss(source);
@@ -128,7 +123,10 @@ public:
         Parse(ds);
         Parse(ds);
     }
     }
 
 
-    ~GenericRegex() {}
+    ~GenericRegex()
+    {
+        RAPIDJSON_DELETE(ownAllocator_);
+    }
 
 
     bool IsValid() const {
     bool IsValid() const {
         return root_ != kRegexInvalidState;
         return root_ != kRegexInvalidState;
@@ -190,10 +188,9 @@ private:
 
 
     template <typename InputStream>
     template <typename InputStream>
     void Parse(DecodedStream<InputStream, Encoding>& ds) {
     void Parse(DecodedStream<InputStream, Encoding>& ds) {
-        Allocator allocator;
-        Stack<Allocator> operandStack(&allocator, 256);     // Frag
-        Stack<Allocator> operatorStack(&allocator, 256);    // Operator
-        Stack<Allocator> atomCountStack(&allocator, 256);   // unsigned (Atom per parenthesis)
+        Stack<Allocator> operandStack(allocator_, 256);    // Frag
+        Stack<Allocator> operatorStack(allocator_, 256);   // Operator
+        Stack<Allocator> atomCountStack(allocator_, 256);  // unsigned (Atom per parenthesis)
 
 
         *atomCountStack.template Push<unsigned>() = 0;
         *atomCountStack.template Push<unsigned>() = 0;
 
 
@@ -290,6 +287,7 @@ private:
                     if (!CharacterEscape(ds, &codepoint))
                     if (!CharacterEscape(ds, &codepoint))
                         return; // Unsupported escape character
                         return; // Unsupported escape character
                     // fall through to default
                     // fall through to default
+                    RAPIDJSON_DELIBERATE_FALLTHROUGH;
 
 
                 default: // Pattern character
                 default: // Pattern character
                     PushOperand(operandStack, codepoint);
                     PushOperand(operandStack, codepoint);
@@ -394,8 +392,7 @@ private:
                 }
                 }
                 return false;
                 return false;
 
 
-            default: 
-                RAPIDJSON_ASSERT(op == kOneOrMore);
+            case kOneOrMore:
                 if (operandStack.GetSize() >= sizeof(Frag)) {
                 if (operandStack.GetSize() >= sizeof(Frag)) {
                     Frag e = *operandStack.template Pop<Frag>(1);
                     Frag e = *operandStack.template Pop<Frag>(1);
                     SizeType s = NewState(kRegexInvalidState, e.start, 0);
                     SizeType s = NewState(kRegexInvalidState, e.start, 0);
@@ -404,6 +401,10 @@ private:
                     return true;
                     return true;
                 }
                 }
                 return false;
                 return false;
+
+            default: 
+                // syntax error (e.g. unclosed kLeftParenthesis)
+                return false;
         }
         }
     }
     }
 
 
@@ -516,6 +517,7 @@ private:
                 else if (!CharacterEscape(ds, &codepoint))
                 else if (!CharacterEscape(ds, &codepoint))
                     return false;
                     return false;
                 // fall through to default
                 // fall through to default
+                RAPIDJSON_DELIBERATE_FALLTHROUGH;
 
 
             default:
             default:
                 switch (step) {
                 switch (step) {
@@ -525,6 +527,7 @@ private:
                         break;
                         break;
                     }
                     }
                     // fall through to step 0 for other characters
                     // fall through to step 0 for other characters
+                    RAPIDJSON_DELIBERATE_FALLTHROUGH;
 
 
                 case 0:
                 case 0:
                     {
                     {
@@ -584,6 +587,8 @@ private:
         }
         }
     }
     }
 
 
+    Allocator* ownAllocator_;
+    Allocator* allocator_;
     Stack<Allocator> states_;
     Stack<Allocator> states_;
     Stack<Allocator> ranges_;
     Stack<Allocator> ranges_;
     SizeType root_;
     SizeType root_;
@@ -723,11 +728,11 @@ typedef GenericRegexSearch<Regex> RegexSearch;
 } // namespace internal
 } // namespace internal
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#ifdef __clang__
+#ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 
-#ifdef _MSC_VER
+#if defined(__clang__) || defined(_MSC_VER)
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 

+ 5 - 4
Source/ThirdParty/rapidjson/include/rapidjson/internal/stack.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -17,6 +17,7 @@
 
 
 #include "../allocators.h"
 #include "../allocators.h"
 #include "swap.h"
 #include "swap.h"
+#include <cstddef>
 
 
 #if defined(__clang__)
 #if defined(__clang__)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
@@ -100,7 +101,7 @@ public:
     void ShrinkToFit() { 
     void ShrinkToFit() { 
         if (Empty()) {
         if (Empty()) {
             // If the stack is empty, completely deallocate the memory.
             // If the stack is empty, completely deallocate the memory.
-            Allocator::Free(stack_);
+            Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
             stack_ = 0;
             stack_ = 0;
             stackTop_ = 0;
             stackTop_ = 0;
             stackEnd_ = 0;
             stackEnd_ = 0;
@@ -114,7 +115,7 @@ public:
     template<typename T>
     template<typename T>
     RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
     RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
          // Expand the stack if needed
          // Expand the stack if needed
-        if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
+        if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
             Expand<T>(count);
             Expand<T>(count);
     }
     }
 
 
@@ -127,7 +128,7 @@ public:
     template<typename T>
     template<typename T>
     RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
     RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
         RAPIDJSON_ASSERT(stackTop_);
         RAPIDJSON_ASSERT(stackTop_);
-        RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
+        RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
         T* ret = reinterpret_cast<T*>(stackTop_);
         T* ret = reinterpret_cast<T*>(stackTop_);
         stackTop_ += sizeof(T) * count;
         stackTop_ += sizeof(T) * count;
         return ret;
         return ret;

+ 15 - 1
Source/ThirdParty/rapidjson/include/rapidjson/internal/strfunc.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -45,6 +45,20 @@ inline SizeType StrLen(const wchar_t* s) {
     return SizeType(std::wcslen(s));
     return SizeType(std::wcslen(s));
 }
 }
 
 
+//! Custom strcmpn() which works on different character types.
+/*! \tparam Ch Character type (e.g. char, wchar_t, short)
+    \param s1 Null-terminated input string.
+    \param s2 Null-terminated input string.
+    \return 0 if equal
+*/
+template<typename Ch>
+inline int StrCmp(const Ch* s1, const Ch* s2) {
+    RAPIDJSON_ASSERT(s1 != 0);
+    RAPIDJSON_ASSERT(s2 != 0);
+    while(*s1 && (*s1 == *s2)) { s1++; s2++; }
+    return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
+}
+
 //! Returns number of code points in a encoded string.
 //! Returns number of code points in a encoded string.
 template<typename Encoding>
 template<typename Encoding>
 bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
 bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {

+ 66 - 42
Source/ThirdParty/rapidjson/include/rapidjson/internal/strtod.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -19,6 +19,8 @@
 #include "biginteger.h"
 #include "biginteger.h"
 #include "diyfp.h"
 #include "diyfp.h"
 #include "pow10.h"
 #include "pow10.h"
+#include <climits>
+#include <limits>
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
 namespace internal {
@@ -126,20 +128,21 @@ inline bool StrtodFast(double d, int p, double* result) {
 }
 }
 
 
 // Compute an approximation and see if it is within 1/2 ULP
 // Compute an approximation and see if it is within 1/2 ULP
-inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
+template<typename Ch>
+inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) {
     uint64_t significand = 0;
     uint64_t significand = 0;
-    size_t i = 0;   // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999    
-    for (; i < length; i++) {
+    int i = 0;   // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999    
+    for (; i < dLen; i++) {
         if (significand  >  RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
         if (significand  >  RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
-            (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
+            (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5')))
             break;
             break;
-        significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
+        significand = significand * 10u + static_cast<unsigned>(decimals[i] - Ch('0'));
     }
     }
     
     
-    if (i < length && decimals[i] >= '5') // Rounding
+    if (i < dLen && decimals[i] >= Ch('5')) // Rounding
         significand++;
         significand++;
 
 
-    size_t remaining = length - i;
+    int remaining = dLen - i;
     const int kUlpShift = 3;
     const int kUlpShift = 3;
     const int kUlp = 1 << kUlpShift;
     const int kUlp = 1 << kUlpShift;
     int64_t error = (remaining == 0) ? 0 : kUlp / 2;
     int64_t error = (remaining == 0) ? 0 : kUlp / 2;
@@ -148,24 +151,24 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
     v = v.Normalize();
     v = v.Normalize();
     error <<= -v.e;
     error <<= -v.e;
 
 
-    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
+    dExp += remaining;
 
 
     int actualExp;
     int actualExp;
     DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
     DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
     if (actualExp != dExp) {
     if (actualExp != dExp) {
         static const DiyFp kPow10[] = {
         static const DiyFp kPow10[] = {
-            DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60),  // 10^1
-            DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57),  // 10^2
-            DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54),  // 10^3
-            DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50),  // 10^4
-            DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47),  // 10^5
-            DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44),  // 10^6
-            DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40)   // 10^7
+            DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60),  // 10^1
+            DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57),  // 10^2
+            DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54),  // 10^3
+            DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50),  // 10^4
+            DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47),  // 10^5
+            DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44),  // 10^6
+            DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40)   // 10^7
         };
         };
-        int  adjustment = dExp - actualExp - 1;
-        RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
-        v = v * kPow10[adjustment];
-        if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
+        int adjustment = dExp - actualExp;
+        RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8);
+        v = v * kPow10[adjustment - 1];
+        if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit
             error += kUlp / 2;
             error += kUlp / 2;
     }
     }
 
 
@@ -203,9 +206,10 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
     return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
     return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
 }
 }
 
 
-inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
-    const BigInteger dInt(decimals, length);
-    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
+template<typename Ch>
+inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) {
+    RAPIDJSON_ASSERT(dLen >= 0);
+    const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
     Double a(approx);
     Double a(approx);
     int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
     int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
     if (cmp < 0)
     if (cmp < 0)
@@ -221,46 +225,66 @@ inline double StrtodBigInteger(double approx, const char* decimals, size_t lengt
         return a.NextPositiveDouble();
         return a.NextPositiveDouble();
 }
 }
 
 
-inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
+template<typename Ch>
+inline double StrtodFullPrecision(double d, int p, const Ch* decimals, size_t length, size_t decimalPosition, int exp) {
     RAPIDJSON_ASSERT(d >= 0.0);
     RAPIDJSON_ASSERT(d >= 0.0);
     RAPIDJSON_ASSERT(length >= 1);
     RAPIDJSON_ASSERT(length >= 1);
 
 
-    double result;
+    double result = 0.0;
     if (StrtodFast(d, p, &result))
     if (StrtodFast(d, p, &result))
         return result;
         return result;
 
 
+    RAPIDJSON_ASSERT(length <= INT_MAX);
+    int dLen = static_cast<int>(length);
+
+    RAPIDJSON_ASSERT(length >= decimalPosition);
+    RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX);
+    int dExpAdjust = static_cast<int>(length - decimalPosition);
+
+    RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust);
+    int dExp = exp - dExpAdjust;
+
+    // Make sure length+dExp does not overflow
+    RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen);
+
     // Trim leading zeros
     // Trim leading zeros
-    while (*decimals == '0' && length > 1) {
-        length--;
+    while (dLen > 0 && *decimals == '0') {
+        dLen--;
         decimals++;
         decimals++;
-        decimalPosition--;
     }
     }
 
 
     // Trim trailing zeros
     // Trim trailing zeros
-    while (decimals[length - 1] == '0' && length > 1) {
-        length--;
-        decimalPosition--;
-        exp++;
+    while (dLen > 0 && decimals[dLen - 1] == '0') {
+        dLen--;
+        dExp++;
+    }
+
+    if (dLen == 0) { // Buffer only contains zeros.
+        return 0.0;
     }
     }
 
 
     // Trim right-most digits
     // Trim right-most digits
-    const int kMaxDecimalDigit = 780;
-    if (static_cast<int>(length) > kMaxDecimalDigit) {
-        int delta = (static_cast<int>(length) - kMaxDecimalDigit);
-        exp += delta;
-        decimalPosition -= static_cast<unsigned>(delta);
-        length = kMaxDecimalDigit;
+    const int kMaxDecimalDigit = 767 + 1;
+    if (dLen > kMaxDecimalDigit) {
+        dExp += dLen - kMaxDecimalDigit;
+        dLen = kMaxDecimalDigit;
     }
     }
 
 
-    // If too small, underflow to zero
-    if (int(length) + exp < -324)
+    // If too small, underflow to zero.
+    // Any x <= 10^-324 is interpreted as zero.
+    if (dLen + dExp <= -324)
         return 0.0;
         return 0.0;
 
 
-    if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
+    // If too large, overflow to infinity.
+    // Any x >= 10^309 is interpreted as +infinity.
+    if (dLen + dExp > 309)
+        return std::numeric_limits<double>::infinity();
+
+    if (StrtodDiyFp(decimals, dLen, dExp, &result))
         return result;
         return result;
 
 
     // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
     // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
-    return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
+    return StrtodBigInteger(result, decimals, dLen, dExp);
 }
 }
 
 
 } // namespace internal
 } // namespace internal

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/internal/swap.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 //
 //
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 51 - 38
Source/ThirdParty/rapidjson/include/rapidjson/istreamwrapper.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -17,13 +17,12 @@
 
 
 #include "stream.h"
 #include "stream.h"
 #include <iosfwd>
 #include <iosfwd>
+#include <ios>
 
 
 #ifdef __clang__
 #ifdef __clang__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-#ifdef _MSC_VER
+#elif defined(_MSC_VER)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
 RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
 #endif
 #endif
@@ -50,57 +49,71 @@ template <typename StreamType>
 class BasicIStreamWrapper {
 class BasicIStreamWrapper {
 public:
 public:
     typedef typename StreamType::char_type Ch;
     typedef typename StreamType::char_type Ch;
-    BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}
 
 
-    Ch Peek() const { 
-        typename StreamType::int_type c = stream_.peek();
-        return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\0');
+    //! Constructor.
+    /*!
+        \param stream stream opened for read.
+    */
+    BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 
+        Read();
     }
     }
 
 
-    Ch Take() { 
-        typename StreamType::int_type c = stream_.get();
-        if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {
-            count_++;
-            return static_cast<Ch>(c);
-        }
-        else
-            return '\0';
+    //! Constructor.
+    /*!
+        \param stream stream opened for read.
+        \param buffer user-supplied buffer.
+        \param bufferSize size of buffer in bytes. Must >=4 bytes.
+    */
+    BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 
+        RAPIDJSON_ASSERT(bufferSize >= 4);
+        Read();
     }
     }
 
 
-    // tellg() may return -1 when failed. So we count by ourself.
-    size_t Tell() const { return count_; }
+    Ch Peek() const { return *current_; }
+    Ch Take() { Ch c = *current_; Read(); return c; }
+    size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
 
 
-    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
+    // Not implemented
     void Put(Ch) { RAPIDJSON_ASSERT(false); }
     void Put(Ch) { RAPIDJSON_ASSERT(false); }
-    void Flush() { RAPIDJSON_ASSERT(false); }
+    void Flush() { RAPIDJSON_ASSERT(false); } 
+    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
 
 
     // For encoding detection only.
     // For encoding detection only.
     const Ch* Peek4() const {
     const Ch* Peek4() const {
-        RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.
-        int i;
-        bool hasError = false;
-        for (i = 0; i < 4; ++i) {
-            typename StreamType::int_type c = stream_.get();
-            if (c == StreamType::traits_type::eof()) {
-                hasError = true;
-                stream_.clear();
-                break;
-            }
-            peekBuffer_[i] = static_cast<Ch>(c);
-        }
-        for (--i; i >= 0; --i)
-            stream_.putback(peekBuffer_[i]);
-        return !hasError ? peekBuffer_ : 0;
+        return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
     }
     }
 
 
 private:
 private:
+    BasicIStreamWrapper();
     BasicIStreamWrapper(const BasicIStreamWrapper&);
     BasicIStreamWrapper(const BasicIStreamWrapper&);
     BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
     BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
 
 
-    StreamType& stream_;
-    size_t count_;  //!< Number of characters read. Note:
-    mutable Ch peekBuffer_[4];
+    void Read() {
+        if (current_ < bufferLast_)
+            ++current_;
+        else if (!eof_) {
+            count_ += readCount_;
+            readCount_ = bufferSize_;
+            bufferLast_ = buffer_ + readCount_ - 1;
+            current_ = buffer_;
+
+            if (!stream_.read(buffer_, static_cast<std::streamsize>(bufferSize_))) {
+                readCount_ = static_cast<size_t>(stream_.gcount());
+                *(bufferLast_ = buffer_ + readCount_) = '\0';
+                eof_ = true;
+            }
+        }
+    }
+
+    StreamType &stream_;
+    Ch peekBuffer_[4], *buffer_;
+    size_t bufferSize_;
+    Ch *bufferLast_;
+    Ch *current_;
+    size_t readCount_;
+    size_t count_;  //!< Number of characters read
+    bool eof_;
 };
 };
 
 
 typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
 typedef BasicIStreamWrapper<std::istream> IStreamWrapper;

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/memorybuffer.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/memorystream.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/ostreamwrapper.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 141 - 17
Source/ThirdParty/rapidjson/include/rapidjson/pointer.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -16,14 +16,13 @@
 #define RAPIDJSON_POINTER_H_
 #define RAPIDJSON_POINTER_H_
 
 
 #include "document.h"
 #include "document.h"
+#include "uri.h"
 #include "internal/itoa.h"
 #include "internal/itoa.h"
 
 
 #ifdef __clang__
 #ifdef __clang__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(switch-enum)
 RAPIDJSON_DIAG_OFF(switch-enum)
-#endif
-
-#ifdef _MSC_VER
+#elif defined(_MSC_VER)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
 #endif
 #endif
@@ -82,6 +81,8 @@ class GenericPointer {
 public:
 public:
     typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
     typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
     typedef typename ValueType::Ch Ch;                      //!< Character type from Value
     typedef typename ValueType::Ch Ch;                      //!< Character type from Value
+    typedef GenericUri<ValueType, Allocator> UriType;
+
 
 
     //! A token is the basic units of internal representation.
     //! A token is the basic units of internal representation.
     /*!
     /*!
@@ -165,7 +166,12 @@ public:
     GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
     GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
 
 
     //! Copy constructor.
     //! Copy constructor.
-    GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+    GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+        *this = rhs;
+    }
+
+    //! Copy constructor.
+    GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
         *this = rhs;
         *this = rhs;
     }
     }
 
 
@@ -197,6 +203,36 @@ public:
         return *this;
         return *this;
     }
     }
 
 
+    //! Swap the content of this pointer with an other.
+    /*!
+        \param other The pointer to swap with.
+        \note Constant complexity.
+    */
+    GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
+        internal::Swap(allocator_, other.allocator_);
+        internal::Swap(ownAllocator_, other.ownAllocator_);
+        internal::Swap(nameBuffer_, other.nameBuffer_);
+        internal::Swap(tokens_, other.tokens_);
+        internal::Swap(tokenCount_, other.tokenCount_);
+        internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
+        internal::Swap(parseErrorCode_, other.parseErrorCode_);
+        return *this;
+    }
+
+    //! free-standing swap function helper
+    /*!
+        Helper function to enable support for common swap implementation pattern based on \c std::swap:
+        \code
+        void swap(MyClass& a, MyClass& b) {
+            using std::swap;
+            swap(a.pointer, b.pointer);
+            // ...
+        }
+        \endcode
+        \see Swap()
+     */
+    friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
+
     //@}
     //@}
 
 
     //!@name Append token
     //!@name Append token
@@ -353,6 +389,33 @@ public:
     */
     */
     bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
     bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
 
 
+    //! Less than operator.
+    /*!
+        \note Invalid pointers are always greater than valid ones.
+    */
+    bool operator<(const GenericPointer& rhs) const {
+        if (!IsValid())
+            return false;
+        if (!rhs.IsValid())
+            return true;
+
+        if (tokenCount_ != rhs.tokenCount_)
+            return tokenCount_ < rhs.tokenCount_;
+
+        for (size_t i = 0; i < tokenCount_; i++) {
+            if (tokens_[i].index != rhs.tokens_[i].index)
+                return tokens_[i].index < rhs.tokens_[i].index;
+
+            if (tokens_[i].length != rhs.tokens_[i].length)
+                return tokens_[i].length < rhs.tokens_[i].length;
+
+            if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
+                return cmp < 0;
+        }
+
+        return false;
+    }
+
     //@}
     //@}
 
 
     //!@name Stringify
     //!@name Stringify
@@ -428,10 +491,11 @@ public:
                     v = &((*v)[t->index]);
                     v = &((*v)[t->index]);
                 }
                 }
                 else {
                 else {
-                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
                     if (m == v->MemberEnd()) {
                     if (m == v->MemberEnd()) {
                         v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
                         v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
-                        v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
+                        m = v->MemberEnd();
+                        v = &(--m)->value; // Assumes AddMember() appends at the end
                         exist = false;
                         exist = false;
                     }
                     }
                     else
                     else
@@ -459,6 +523,70 @@ public:
 
 
     //@}
     //@}
 
 
+    //!@name Compute URI
+    //@{
+
+    //! Compute the in-scope URI for a subtree.
+    //  For use with JSON pointers into JSON schema documents.
+    /*!
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \param rootUri Root URI
+        \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
+        \param allocator Allocator for Uris
+        \return Uri if it can be resolved. Otherwise null.
+
+        \note
+        There are only 3 situations when a URI cannot be resolved:
+        1. A value in the path is not an array nor object.
+        2. An object value does not contain the token.
+        3. A token is out of range of an array value.
+
+        Use unresolvedTokenIndex to retrieve the token index.
+    */
+    UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
+        static const Ch kIdString[] = { 'i', 'd', '\0' };
+        static const ValueType kIdValue(kIdString, 2);
+        UriType base = UriType(rootUri, allocator);
+        RAPIDJSON_ASSERT(IsValid());
+        ValueType* v = &root;
+        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
+            switch (v->GetType()) {
+                case kObjectType:
+                {
+                    // See if we have an id, and if so resolve with the current base
+                    typename ValueType::MemberIterator m = v->FindMember(kIdValue);
+                    if (m != v->MemberEnd() && (m->value).IsString()) {
+                        UriType here = UriType(m->value, allocator).Resolve(base, allocator);
+                        base = here;
+                    }
+                    m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
+                    if (m == v->MemberEnd())
+                        break;
+                    v = &m->value;
+                }
+                  continue;
+                case kArrayType:
+                    if (t->index == kPointerInvalidIndex || t->index >= v->Size())
+                        break;
+                    v = &((*v)[t->index]);
+                    continue;
+                default:
+                    break;
+            }
+
+            // Error: unresolved token
+            if (unresolvedTokenIndex)
+                *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
+            return UriType(allocator);
+        }
+        return base;
+    }
+
+    UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
+      return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
+    }
+
+
     //!@name Query value
     //!@name Query value
     //@{
     //@{
 
 
@@ -483,7 +611,7 @@ public:
             switch (v->GetType()) {
             switch (v->GetType()) {
             case kObjectType:
             case kObjectType:
                 {
                 {
-                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
                     if (m == v->MemberEnd())
                     if (m == v->MemberEnd())
                         break;
                         break;
                     v = &m->value;
                     v = &m->value;
@@ -532,14 +660,14 @@ public:
     */
     */
     ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
     ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
         bool alreadyExist;
         bool alreadyExist;
-        Value& v = Create(root, allocator, &alreadyExist);
+        ValueType& v = Create(root, allocator, &alreadyExist);
         return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
         return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
     }
     }
 
 
     //! Query a value in a subtree with default null-terminated string.
     //! Query a value in a subtree with default null-terminated string.
     ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
     ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
         bool alreadyExist;
         bool alreadyExist;
-        Value& v = Create(root, allocator, &alreadyExist);
+        ValueType& v = Create(root, allocator, &alreadyExist);
         return alreadyExist ? v : v.SetString(defaultValue, allocator);
         return alreadyExist ? v : v.SetString(defaultValue, allocator);
     }
     }
 
 
@@ -547,7 +675,7 @@ public:
     //! Query a value in a subtree with default std::basic_string.
     //! Query a value in a subtree with default std::basic_string.
     ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
     ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
         bool alreadyExist;
         bool alreadyExist;
-        Value& v = Create(root, allocator, &alreadyExist);
+        ValueType& v = Create(root, allocator, &alreadyExist);
         return alreadyExist ? v : v.SetString(defaultValue, allocator);
         return alreadyExist ? v : v.SetString(defaultValue, allocator);
     }
     }
 #endif
 #endif
@@ -719,7 +847,7 @@ public:
             switch (v->GetType()) {
             switch (v->GetType()) {
             case kObjectType:
             case kObjectType:
                 {
                 {
-                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
                     if (m == v->MemberEnd())
                     if (m == v->MemberEnd())
                         return false;
                         return false;
                     v = &m->value;
                     v = &m->value;
@@ -1347,11 +1475,7 @@ bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
 
 
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef _MSC_VER
+#if defined(__clang__) || defined(_MSC_VER)
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 

+ 16 - 19
Source/ThirdParty/rapidjson/include/rapidjson/prettywriter.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -12,8 +12,6 @@
 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 // specific language governing permissions and limitations under the License.
 // specific language governing permissions and limitations under the License.
 
 
-// Modified by Ali Kamarainen for Urho3D
-
 #ifndef RAPIDJSON_PRETTYWRITER_H_
 #ifndef RAPIDJSON_PRETTYWRITER_H_
 #define RAPIDJSON_PRETTYWRITER_H_
 #define RAPIDJSON_PRETTYWRITER_H_
 
 
@@ -41,7 +39,7 @@ enum PrettyFormatOptions {
 
 
 //! Writer with indentation and spacing.
 //! Writer with indentation and spacing.
 /*!
 /*!
-    \tparam OutputStream Type of ouptut os.
+    \tparam OutputStream Type of output os.
     \tparam SourceEncoding Encoding of source string.
     \tparam SourceEncoding Encoding of source string.
     \tparam TargetEncoding Encoding of output stream.
     \tparam TargetEncoding Encoding of output stream.
     \tparam StackAllocator Type of allocator for allocating memory of stack.
     \tparam StackAllocator Type of allocator for allocating memory of stack.
@@ -62,7 +60,7 @@ public:
 
 
 
 
     explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
     explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 
-        Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
+        Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
 
 
 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
     PrettyWriter(PrettyWriter&& rhs) :
     PrettyWriter(PrettyWriter&& rhs) :
@@ -75,8 +73,7 @@ public:
         \note The default indentation is 4 spaces.
         \note The default indentation is 4 spaces.
     */
     */
     PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
     PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
-        // Urho3D: in order to be consistent with the XMLFile API, allow any character.
-        //RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
+        RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
         indentChar_ = indentChar;
         indentChar_ = indentChar;
         indentCharCount_ = indentCharCount;
         indentCharCount_ = indentCharCount;
         return *this;
         return *this;
@@ -95,26 +92,26 @@ public:
     */
     */
     //@{
     //@{
 
 
-    bool Null()                 { PrettyPrefix(kNullType);   return Base::WriteNull(); }
-    bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
-    bool Int(int i)             { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
-    bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
-    bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
-    bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::WriteUint64(u64);  }
-    bool Double(double d)       { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
+    bool Null()                 { PrettyPrefix(kNullType);   return Base::EndValue(Base::WriteNull()); }
+    bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
+    bool Int(int i)             { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
+    bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
+    bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
+    bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64));  }
+    bool Double(double d)       { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
 
 
     bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
     bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
         RAPIDJSON_ASSERT(str != 0);
         RAPIDJSON_ASSERT(str != 0);
         (void)copy;
         (void)copy;
         PrettyPrefix(kNumberType);
         PrettyPrefix(kNumberType);
-        return Base::WriteString(str, length);
+        return Base::EndValue(Base::WriteString(str, length));
     }
     }
 
 
     bool String(const Ch* str, SizeType length, bool copy = false) {
     bool String(const Ch* str, SizeType length, bool copy = false) {
         RAPIDJSON_ASSERT(str != 0);
         RAPIDJSON_ASSERT(str != 0);
         (void)copy;
         (void)copy;
         PrettyPrefix(kStringType);
         PrettyPrefix(kStringType);
-        return Base::WriteString(str, length);
+        return Base::EndValue(Base::WriteString(str, length));
     }
     }
 
 
 #if RAPIDJSON_HAS_STDSTRING
 #if RAPIDJSON_HAS_STDSTRING
@@ -149,7 +146,7 @@ public:
             Base::os_->Put('\n');
             Base::os_->Put('\n');
             WriteIndent();
             WriteIndent();
         }
         }
-        bool ret = Base::WriteEndObject();
+        bool ret = Base::EndValue(Base::WriteEndObject());
         (void)ret;
         (void)ret;
         RAPIDJSON_ASSERT(ret == true);
         RAPIDJSON_ASSERT(ret == true);
         if (Base::level_stack_.Empty()) // end of json text
         if (Base::level_stack_.Empty()) // end of json text
@@ -173,7 +170,7 @@ public:
             Base::os_->Put('\n');
             Base::os_->Put('\n');
             WriteIndent();
             WriteIndent();
         }
         }
-        bool ret = Base::WriteEndArray();
+        bool ret = Base::EndValue(Base::WriteEndArray());
         (void)ret;
         (void)ret;
         RAPIDJSON_ASSERT(ret == true);
         RAPIDJSON_ASSERT(ret == true);
         if (Base::level_stack_.Empty()) // end of json text
         if (Base::level_stack_.Empty()) // end of json text
@@ -204,7 +201,7 @@ public:
     bool RawValue(const Ch* json, size_t length, Type type) {
     bool RawValue(const Ch* json, size_t length, Type type) {
         RAPIDJSON_ASSERT(json != 0);
         RAPIDJSON_ASSERT(json != 0);
         PrettyPrefix(type);
         PrettyPrefix(type);
-        return Base::WriteRawValue(json, length);
+        return Base::EndValue(Base::WriteRawValue(json, length));
     }
     }
 
 
 protected:
 protected:

+ 136 - 23
Source/ThirdParty/rapidjson/include/rapidjson/rapidjson.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -26,7 +26,7 @@
 
 
     Some RapidJSON features are configurable to adapt the library to a wide
     Some RapidJSON features are configurable to adapt the library to a wide
     variety of platforms, environments and usage scenarios.  Most of the
     variety of platforms, environments and usage scenarios.  Most of the
-    features can be configured in terms of overriden or predefined
+    features can be configured in terms of overridden or predefined
     preprocessor macros at compile-time.
     preprocessor macros at compile-time.
 
 
     Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
     Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
@@ -124,6 +124,19 @@
 #define RAPIDJSON_NAMESPACE_END }
 #define RAPIDJSON_NAMESPACE_END }
 #endif
 #endif
 
 
+///////////////////////////////////////////////////////////////////////////////
+// __cplusplus macro
+
+//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
+
+#if defined(_MSC_VER)
+#define RAPIDJSON_CPLUSPLUS _MSVC_LANG
+#else
+#define RAPIDJSON_CPLUSPLUS __cplusplus
+#endif
+
+//!@endcond
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_HAS_STDSTRING
 // RAPIDJSON_HAS_STDSTRING
 
 
@@ -149,6 +162,24 @@
 #include <string>
 #include <string>
 #endif // RAPIDJSON_HAS_STDSTRING
 #endif // RAPIDJSON_HAS_STDSTRING
 
 
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_USE_MEMBERSMAP
+
+/*! \def RAPIDJSON_USE_MEMBERSMAP
+    \ingroup RAPIDJSON_CONFIG
+    \brief Enable RapidJSON support for object members handling in a \c std::multimap
+
+    By defining this preprocessor symbol to \c 1, \ref rapidjson::GenericValue object
+    members are stored in a \c std::multimap for faster lookup and deletion times, a
+    trade off with a slightly slower insertion time and a small object allocat(or)ed
+    memory overhead.
+
+    \hideinitializer
+*/
+#ifndef RAPIDJSON_USE_MEMBERSMAP
+#define RAPIDJSON_USE_MEMBERSMAP 0 // not by default
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_NO_INT64DEFINE
 // RAPIDJSON_NO_INT64DEFINE
 
 
@@ -219,7 +250,7 @@
 #    elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 #    elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #    else
 #    else
-#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
+#      error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
 #    endif // __BYTE_ORDER__
 #    endif // __BYTE_ORDER__
 // Detect with GLIBC's endian.h
 // Detect with GLIBC's endian.h
 #  elif defined(__GLIBC__)
 #  elif defined(__GLIBC__)
@@ -229,7 +260,7 @@
 #    elif (__BYTE_ORDER == __BIG_ENDIAN)
 #    elif (__BYTE_ORDER == __BIG_ENDIAN)
 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #    else
 #    else
-#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
+#      error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
 #   endif // __GLIBC__
 #   endif // __GLIBC__
 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
 #  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
 #  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
@@ -241,12 +272,12 @@
 #    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #  elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
 #  elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-#  elif defined(_MSC_VER) && defined(_M_ARM)
+#  elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
 #  elif defined(RAPIDJSON_DOXYGEN_RUNNING)
 #  elif defined(RAPIDJSON_DOXYGEN_RUNNING)
 #    define RAPIDJSON_ENDIAN
 #    define RAPIDJSON_ENDIAN
 #  else
 #  else
-#    error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.   
+#    error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.   
 #  endif
 #  endif
 #endif // RAPIDJSON_ENDIAN
 #endif // RAPIDJSON_ENDIAN
 
 
@@ -269,16 +300,11 @@
 /*! \ingroup RAPIDJSON_CONFIG
 /*! \ingroup RAPIDJSON_CONFIG
     \param x pointer to align
     \param x pointer to align
 
 
-    Some machines require strict data alignment. Currently the default uses 4 bytes
-    alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.
+    Some machines require strict data alignment. The default is 8 bytes.
     User can customize by defining the RAPIDJSON_ALIGN function macro.
     User can customize by defining the RAPIDJSON_ALIGN function macro.
 */
 */
 #ifndef RAPIDJSON_ALIGN
 #ifndef RAPIDJSON_ALIGN
-#if RAPIDJSON_64BIT == 1
-#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
-#else
-#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
-#endif
+#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
 #endif
 #endif
 
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
@@ -416,7 +442,7 @@ RAPIDJSON_NAMESPACE_END
 
 
 // Prefer C++11 static_assert, if available
 // Prefer C++11 static_assert, if available
 #ifndef RAPIDJSON_STATIC_ASSERT
 #ifndef RAPIDJSON_STATIC_ASSERT
-#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
+#if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
 #define RAPIDJSON_STATIC_ASSERT(x) \
 #define RAPIDJSON_STATIC_ASSERT(x) \
    static_assert(x, RAPIDJSON_STRINGIFY(x))
    static_assert(x, RAPIDJSON_STRINGIFY(x))
 #endif // C++11
 #endif // C++11
@@ -433,7 +459,7 @@ template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
 template <size_t x> struct StaticAssertTest {};
 template <size_t x> struct StaticAssertTest {};
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
 #else
 #else
 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 
 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 
@@ -495,6 +521,12 @@ RAPIDJSON_NAMESPACE_END
 #define RAPIDJSON_VERSION_CODE(x,y,z) \
 #define RAPIDJSON_VERSION_CODE(x,y,z) \
   (((x)*100000) + ((y)*100) + (z))
   (((x)*100000) + ((y)*100) + (z))
 
 
+#if defined(__has_builtin)
+#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#define RAPIDJSON_HAS_BUILTIN(x) 0
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
 
 
@@ -540,16 +572,23 @@ RAPIDJSON_NAMESPACE_END
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // C++11 features
 // C++11 features
 
 
+#ifndef RAPIDJSON_HAS_CXX11
+#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L)
+#endif
+
 #ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
 #ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
-#if defined(__clang__)
+#if RAPIDJSON_HAS_CXX11
+#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
+#elif defined(__clang__)
 #if __has_feature(cxx_rvalue_references) && \
 #if __has_feature(cxx_rvalue_references) && \
-    (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
+    (defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
 #else
 #else
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
 #endif
 #endif
 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
-      (defined(_MSC_VER) && _MSC_VER >= 1600)
+      (defined(_MSC_VER) && _MSC_VER >= 1600) || \
+      (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
 
 
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
 #else
 #else
@@ -557,40 +596,114 @@ RAPIDJSON_NAMESPACE_END
 #endif
 #endif
 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
 
 
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+#include <utility> // std::move
+#endif
+
 #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
 #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
-#if defined(__clang__)
+#if RAPIDJSON_HAS_CXX11
+#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
+#elif defined(__clang__)
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
-#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
-//    (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
+#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
+    (defined(_MSC_VER) && _MSC_VER >= 1900) || \
+    (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
 #else
 #else
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
 #endif
 #endif
 #endif
 #endif
+#ifndef RAPIDJSON_NOEXCEPT
 #if RAPIDJSON_HAS_CXX11_NOEXCEPT
 #if RAPIDJSON_HAS_CXX11_NOEXCEPT
 #define RAPIDJSON_NOEXCEPT noexcept
 #define RAPIDJSON_NOEXCEPT noexcept
 #else
 #else
-#define RAPIDJSON_NOEXCEPT /* noexcept */
+#define RAPIDJSON_NOEXCEPT throw()
 #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
 #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
+#endif
 
 
 // no automatic detection, yet
 // no automatic detection, yet
 #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
 #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
+#if (defined(_MSC_VER) && _MSC_VER >= 1700)
+#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1
+#else
 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
 #endif
 #endif
+#endif
 
 
 #ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
 #ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
 #if defined(__clang__)
 #if defined(__clang__)
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
-      (defined(_MSC_VER) && _MSC_VER >= 1700)
+      (defined(_MSC_VER) && _MSC_VER >= 1700) || \
+      (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
 #else
 #else
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
 #endif
 #endif
 #endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
 #endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
 
 
+///////////////////////////////////////////////////////////////////////////////
+// C++17 features
+
+#ifndef RAPIDJSON_HAS_CXX17
+#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L)
+#endif
+
+#if RAPIDJSON_HAS_CXX17
+# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
+#elif defined(__has_cpp_attribute)
+# if __has_cpp_attribute(clang::fallthrough)
+#  define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]]
+# elif __has_cpp_attribute(fallthrough)
+#  define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough))
+# else
+#  define RAPIDJSON_DELIBERATE_FALLTHROUGH
+# endif
+#else
+# define RAPIDJSON_DELIBERATE_FALLTHROUGH
+#endif
+
 //!@endcond
 //!@endcond
 
 
+//! Assertion (in non-throwing contexts).
+ /*! \ingroup RAPIDJSON_CONFIG
+    Some functions provide a \c noexcept guarantee, if the compiler supports it.
+    In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to
+    throw an exception.  This macro adds a separate customization point for
+    such cases.
+
+    Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is
+    supported, and to \ref RAPIDJSON_ASSERT otherwise.
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_NOEXCEPT_ASSERT
+
+#ifndef RAPIDJSON_NOEXCEPT_ASSERT
+#ifdef RAPIDJSON_ASSERT_THROWS
+#include <cassert>
+#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
+#else
+#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
+#endif // RAPIDJSON_ASSERT_THROWS
+#endif // RAPIDJSON_NOEXCEPT_ASSERT
+
+///////////////////////////////////////////////////////////////////////////////
+// malloc/realloc/free
+
+#ifndef RAPIDJSON_MALLOC
+///! customization point for global \c malloc
+#define RAPIDJSON_MALLOC(size) std::malloc(size)
+#endif
+#ifndef RAPIDJSON_REALLOC
+///! customization point for global \c realloc
+#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
+#endif
+#ifndef RAPIDJSON_FREE
+///! customization point for global \c free
+#define RAPIDJSON_FREE(ptr) std::free(ptr)
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // new/delete
 // new/delete
 
 

+ 121 - 96
Source/ThirdParty/rapidjson/include/rapidjson/reader.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 //
 //
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -20,6 +20,7 @@
 #include "allocators.h"
 #include "allocators.h"
 #include "stream.h"
 #include "stream.h"
 #include "encodedstream.h"
 #include "encodedstream.h"
+#include "internal/clzll.h"
 #include "internal/meta.h"
 #include "internal/meta.h"
 #include "internal/stack.h"
 #include "internal/stack.h"
 #include "internal/strtod.h"
 #include "internal/strtod.h"
@@ -37,17 +38,15 @@
 #include <arm_neon.h>
 #include <arm_neon.h>
 #endif
 #endif
 
 
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant
-RAPIDJSON_DIAG_OFF(4702)  // unreachable code
-#endif
-
 #ifdef __clang__
 #ifdef __clang__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(old-style-cast)
 RAPIDJSON_DIAG_OFF(old-style-cast)
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(switch-enum)
 RAPIDJSON_DIAG_OFF(switch-enum)
+#elif defined(_MSC_VER)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant
+RAPIDJSON_DIAG_OFF(4702)  // unreachable code
 #endif
 #endif
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
@@ -155,6 +154,7 @@ enum ParseFlag {
     kParseNumbersAsStringsFlag = 64,    //!< Parse all numbers (ints/doubles) as strings.
     kParseNumbersAsStringsFlag = 64,    //!< Parse all numbers (ints/doubles) as strings.
     kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
     kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
     kParseNanAndInfFlag = 256,      //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
     kParseNanAndInfFlag = 256,      //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
+    kParseEscapedApostropheFlag = 512,  //!< Allow escaped apostrophe in strings.
     kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
     kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
 };
 };
 
 
@@ -445,16 +445,16 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
 
 
         x = vmvnq_u8(x);                       // Negate
         x = vmvnq_u8(x);                       // Negate
         x = vrev64q_u8(x);                     // Rev in 64
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
         if (low == 0) {
         if (low == 0) {
             if (high != 0) {
             if (high != 0) {
-                int lz =__builtin_clzll(high);;
+                uint32_t lz = internal::clzll(high);
                 return p + 8 + (lz >> 3);
                 return p + 8 + (lz >> 3);
             }
             }
         } else {
         } else {
-            int lz = __builtin_clzll(low);;
+            uint32_t lz = internal::clzll(low);
             return p + (lz >> 3);
             return p + (lz >> 3);
         }
         }
     }
     }
@@ -481,16 +481,16 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
 
 
         x = vmvnq_u8(x);                       // Negate
         x = vmvnq_u8(x);                       // Negate
         x = vrev64q_u8(x);                     // Rev in 64
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
         if (low == 0) {
         if (low == 0) {
             if (high != 0) {
             if (high != 0) {
-                int lz = __builtin_clzll(high);
+                uint32_t lz = internal::clzll(high);
                 return p + 8 + (lz >> 3);
                 return p + 8 + (lz >> 3);
             }
             }
         } else {
         } else {
-            int lz = __builtin_clzll(low);
+            uint32_t lz = internal::clzll(low);
             return p + (lz >> 3);
             return p + (lz >> 3);
         }
         }
     }
     }
@@ -544,7 +544,8 @@ public:
     /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
     /*! \param stackAllocator 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)
         \param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)
     */
     */
-    GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
+    GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
+        stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
 
 
     //! Parse JSON text.
     //! Parse JSON text.
     /*! \tparam parseFlags Combination of \ref ParseFlag.
     /*! \tparam parseFlags Combination of \ref ParseFlag.
@@ -607,7 +608,7 @@ public:
         parseResult_.Clear();
         parseResult_.Clear();
         state_ = IterativeParsingStartState;
         state_ = IterativeParsingStartState;
     }
     }
-    
+
     //! Parse one token from JSON text
     //! Parse one token from JSON text
     /*! \tparam InputStream Type of input stream, implementing Stream concept
     /*! \tparam InputStream Type of input stream, implementing Stream concept
         \tparam Handler Type of handler, implementing Handler concept.
         \tparam Handler Type of handler, implementing Handler concept.
@@ -619,11 +620,11 @@ public:
     bool IterativeParseNext(InputStream& is, Handler& handler) {
     bool IterativeParseNext(InputStream& is, Handler& handler) {
         while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
         while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
             SkipWhitespaceAndComments<parseFlags>(is);
             SkipWhitespaceAndComments<parseFlags>(is);
-            
+
             Token t = Tokenize(is.Peek());
             Token t = Tokenize(is.Peek());
             IterativeParsingState n = Predict(state_, t);
             IterativeParsingState n = Predict(state_, t);
             IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
             IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
-            
+
             // If we've finished or hit an error...
             // If we've finished or hit an error...
             if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
             if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
                 // Report errors.
                 // Report errors.
@@ -631,11 +632,11 @@ public:
                     HandleError(state_, is);
                     HandleError(state_, is);
                     return false;
                     return false;
                 }
                 }
-            
+
                 // Transition to the finish state.
                 // Transition to the finish state.
                 RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
                 RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
                 state_ = d;
                 state_ = d;
-                
+
                 // If StopWhenDone is not set...
                 // If StopWhenDone is not set...
                 if (!(parseFlags & kParseStopWhenDoneFlag)) {
                 if (!(parseFlags & kParseStopWhenDoneFlag)) {
                     // ... and extra non-whitespace data is found...
                     // ... and extra non-whitespace data is found...
@@ -646,11 +647,11 @@ public:
                         return false;
                         return false;
                     }
                     }
                 }
                 }
-                
+
                 // Success! We are done!
                 // Success! We are done!
                 return true;
                 return true;
             }
             }
-            
+
             // Transition to the new state.
             // Transition to the new state.
             state_ = d;
             state_ = d;
 
 
@@ -658,7 +659,7 @@ public:
             if (!IsIterativeParsingDelimiterState(n))
             if (!IsIterativeParsingDelimiterState(n))
                 return true;
                 return true;
         }
         }
-        
+
         // We reached the end of file.
         // We reached the end of file.
         stack_.Clear();
         stack_.Clear();
 
 
@@ -666,18 +667,18 @@ public:
             HandleError(state_, is);
             HandleError(state_, is);
             return false;
             return false;
         }
         }
-        
+
         return true;
         return true;
     }
     }
-    
+
     //! Check if token-by-token parsing JSON text is complete
     //! Check if token-by-token parsing JSON text is complete
     /*! \return Whether the JSON has been fully decoded.
     /*! \return Whether the JSON has been fully decoded.
      */
      */
-    RAPIDJSON_FORCEINLINE bool IterativeParseComplete() {
+    RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const {
         return IsIterativeParsingCompleteState(state_);
         return IsIterativeParsingCompleteState(state_);
     }
     }
 
 
-    //! Whether a parse error has occured in the last parsing.
+    //! Whether a parse error has occurred in the last parsing.
     bool HasParseError() const { return parseResult_.IsError(); }
     bool HasParseError() const { return parseResult_.IsError(); }
 
 
     //! Get the \ref ParseErrorCode of last parsing.
     //! Get the \ref ParseErrorCode of last parsing.
@@ -900,7 +901,7 @@ private:
             return false;
             return false;
     }
     }
 
 
-    // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
+    // Helper function to parse four hexadecimal digits in \uXXXX in ParseString().
     template<typename InputStream>
     template<typename InputStream>
     unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
     unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
         unsigned codepoint = 0;
         unsigned codepoint = 0;
@@ -991,7 +992,7 @@ private:
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
         static const char escape[256] = {
         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, '/',
             Z16, Z16, 0, 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,'\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,
             0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1007,26 +1008,38 @@ private:
 
 
             Ch c = is.Peek();
             Ch c = is.Peek();
             if (RAPIDJSON_UNLIKELY(c == '\\')) {    // Escape
             if (RAPIDJSON_UNLIKELY(c == '\\')) {    // Escape
-                size_t escapeOffset = is.Tell();    // For invalid escaping, report the inital '\\' as error offset
+                size_t escapeOffset = is.Tell();    // For invalid escaping, report the initial '\\' as error offset
                 is.Take();
                 is.Take();
                 Ch e = is.Peek();
                 Ch e = is.Peek();
                 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
                 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
                     is.Take();
                     is.Take();
                     os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
                     os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
                 }
                 }
+                else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe
+                    is.Take();
+                    os.Put('\'');
+                }
                 else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode
                 else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode
                     is.Take();
                     is.Take();
                     unsigned codepoint = ParseHex4(is, escapeOffset);
                     unsigned codepoint = ParseHex4(is, escapeOffset);
                     RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
                     RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
-                        // Handle UTF-16 surrogate pair
-                        if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
-                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
-                        unsigned codepoint2 = ParseHex4(is, escapeOffset);
-                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-                        if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
+                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
+                        // high surrogate, check if followed by valid low surrogate
+                        if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) {
+                            // Handle UTF-16 surrogate pair
+                            if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
+                                RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
+                            unsigned codepoint2 = ParseHex4(is, escapeOffset);
+                            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
+                            if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
+                                RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
+                            codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
+                        }
+                        // single low surrogate
+                        else
+                        {
                             RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
                             RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
-                        codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
+                        }
                     }
                     }
                     TEncoding::Encode(os, codepoint);
                     TEncoding::Encode(os, codepoint);
                 }
                 }
@@ -1245,19 +1258,19 @@ private:
             x = vorrq_u8(x, vcltq_u8(s, s3));
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
 
             x = vrev64q_u8(x);                     // Rev in 64
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
             SizeType length = 0;
             SizeType length = 0;
             bool escaped = false;
             bool escaped = false;
             if (low == 0) {
             if (low == 0) {
                 if (high != 0) {
                 if (high != 0) {
-                    unsigned lz = (unsigned)__builtin_clzll(high);;
+                    uint32_t lz = internal::clzll(high);
                     length = 8 + (lz >> 3);
                     length = 8 + (lz >> 3);
                     escaped = true;
                     escaped = true;
                 }
                 }
             } else {
             } else {
-                unsigned lz = (unsigned)__builtin_clzll(low);;
+                uint32_t lz = internal::clzll(low);
                 length = lz >> 3;
                 length = lz >> 3;
                 escaped = true;
                 escaped = true;
             }
             }
@@ -1315,19 +1328,19 @@ private:
             x = vorrq_u8(x, vcltq_u8(s, s3));
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
 
             x = vrev64q_u8(x);                     // Rev in 64
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
             SizeType length = 0;
             SizeType length = 0;
             bool escaped = false;
             bool escaped = false;
             if (low == 0) {
             if (low == 0) {
                 if (high != 0) {
                 if (high != 0) {
-                    unsigned lz = (unsigned)__builtin_clzll(high);
+                    uint32_t lz = internal::clzll(high);
                     length = 8 + (lz >> 3);
                     length = 8 + (lz >> 3);
                     escaped = true;
                     escaped = true;
                 }
                 }
             } else {
             } else {
-                unsigned lz = (unsigned)__builtin_clzll(low);
+                uint32_t lz = internal::clzll(low);
                 length = lz >> 3;
                 length = lz >> 3;
                 escaped = true;
                 escaped = true;
             }
             }
@@ -1371,17 +1384,17 @@ private:
             x = vorrq_u8(x, vcltq_u8(s, s3));
             x = vorrq_u8(x, vcltq_u8(s, s3));
 
 
             x = vrev64q_u8(x);                     // Rev in 64
             x = vrev64q_u8(x);                     // Rev in 64
-            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+            uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+            uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
             if (low == 0) {
             if (low == 0) {
                 if (high != 0) {
                 if (high != 0) {
-                    int lz = __builtin_clzll(high);
+                    uint32_t lz = internal::clzll(high);
                     p += 8 + (lz >> 3);
                     p += 8 + (lz >> 3);
                     break;
                     break;
                 }
                 }
             } else {
             } else {
-                int lz = __builtin_clzll(low);
+                uint32_t lz = internal::clzll(low);
                 p += lz >> 3;
                 p += lz >> 3;
                 break;
                 break;
             }
             }
@@ -1391,11 +1404,11 @@ private:
     }
     }
 #endif // RAPIDJSON_NEON
 #endif // RAPIDJSON_NEON
 
 
-    template<typename InputStream, bool backup, bool pushOnTake>
+    template<typename InputStream, typename StackCharacter, bool backup, bool pushOnTake>
     class NumberStream;
     class NumberStream;
 
 
-    template<typename InputStream>
-    class NumberStream<InputStream, false, false> {
+    template<typename InputStream, typename StackCharacter>
+    class NumberStream<InputStream, StackCharacter, false, false> {
     public:
     public:
         typedef typename InputStream::Ch Ch;
         typedef typename InputStream::Ch Ch;
 
 
@@ -1404,11 +1417,11 @@ private:
         RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
         RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
         RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
         RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
         RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
         RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
-		  RAPIDJSON_FORCEINLINE void Push(char) {}
+        RAPIDJSON_FORCEINLINE void Push(char) {}
 
 
         size_t Tell() { return is.Tell(); }
         size_t Tell() { return is.Tell(); }
         size_t Length() { return 0; }
         size_t Length() { return 0; }
-        const char* Pop() { return 0; }
+        const StackCharacter* Pop() { return 0; }
 
 
     protected:
     protected:
         NumberStream& operator=(const NumberStream&);
         NumberStream& operator=(const NumberStream&);
@@ -1416,45 +1429,47 @@ private:
         InputStream& is;
         InputStream& is;
     };
     };
 
 
-    template<typename InputStream>
-    class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
-        typedef NumberStream<InputStream, false, false> Base;
+    template<typename InputStream, typename StackCharacter>
+    class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
+        typedef NumberStream<InputStream, StackCharacter, false, false> Base;
     public:
     public:
-        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
+        NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {}
 
 
         RAPIDJSON_FORCEINLINE Ch TakePush() {
         RAPIDJSON_FORCEINLINE Ch TakePush() {
-            stackStream.Put(static_cast<char>(Base::is.Peek()));
+            stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
             return Base::is.Take();
             return Base::is.Take();
         }
         }
 
 
-        RAPIDJSON_FORCEINLINE void Push(char c) {
+        RAPIDJSON_FORCEINLINE void Push(StackCharacter c) {
             stackStream.Put(c);
             stackStream.Put(c);
         }
         }
 
 
         size_t Length() { return stackStream.Length(); }
         size_t Length() { return stackStream.Length(); }
 
 
-        const char* Pop() {
+        const StackCharacter* Pop() {
             stackStream.Put('\0');
             stackStream.Put('\0');
             return stackStream.Pop();
             return stackStream.Pop();
         }
         }
 
 
     private:
     private:
-        StackStream<char> stackStream;
+        StackStream<StackCharacter> stackStream;
     };
     };
 
 
-    template<typename InputStream>
-    class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
-        typedef NumberStream<InputStream, true, false> Base;
+    template<typename InputStream, typename StackCharacter>
+    class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
+        typedef NumberStream<InputStream, StackCharacter, true, false> Base;
     public:
     public:
-        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
+        NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {}
 
 
         RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
         RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
     };
     };
 
 
     template<unsigned parseFlags, typename InputStream, typename Handler>
     template<unsigned parseFlags, typename InputStream, typename Handler>
     void ParseNumber(InputStream& is, Handler& handler) {
     void ParseNumber(InputStream& is, Handler& handler) {
+        typedef typename internal::SelectIf<internal::BoolType<(parseFlags & kParseNumbersAsStringsFlag) != 0>, typename TargetEncoding::Ch, char>::Type NumberCharacter;
+
         internal::StreamLocalCopy<InputStream> copy(is);
         internal::StreamLocalCopy<InputStream> copy(is);
-        NumberStream<InputStream,
+        NumberStream<InputStream, NumberCharacter,
             ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
             ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
                 ((parseFlags & kParseInsituFlag) == 0) :
                 ((parseFlags & kParseInsituFlag) == 0) :
                 ((parseFlags & kParseFullPrecisionFlag) != 0),
                 ((parseFlags & kParseFullPrecisionFlag) != 0),
@@ -1524,7 +1539,7 @@ private:
                     }
                     }
                 }
                 }
             }
             }
-            
+
             if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
             if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
                 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
                 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
             }
             }
@@ -1562,8 +1577,6 @@ private:
         // Force double for big integer
         // Force double for big integer
         if (useDouble) {
         if (useDouble) {
             while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
             while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
-                if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
-                    RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
                 d = d * 10 + (s.TakePush() - '0');
                 d = d * 10 + (s.TakePush() - '0');
             }
             }
         }
         }
@@ -1633,9 +1646,18 @@ private:
             if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
             if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
                 exp = static_cast<int>(s.Take() - '0');
                 exp = static_cast<int>(s.Take() - '0');
                 if (expMinus) {
                 if (expMinus) {
+                    // (exp + expFrac) must not underflow int => we're detecting when -exp gets
+                    // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
+                    // underflow territory):
+                    //
+                    //        -(exp * 10 + 9) + expFrac >= INT_MIN
+                    //   <=>  exp <= (expFrac - INT_MIN - 9) / 10
+                    RAPIDJSON_ASSERT(expFrac <= 0);
+                    int maxExp = (expFrac + 2147483639) / 10;
+
                     while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
                     while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
                         exp = exp * 10 + static_cast<int>(s.Take() - '0');
                         exp = exp * 10 + static_cast<int>(s.Take() - '0');
-                        if (exp >= 214748364) {                         // Issue #313: prevent overflow exponent
+                        if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
                             while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent
                             while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent
                                 s.Take();
                                 s.Take();
                         }
                         }
@@ -1672,10 +1694,10 @@ private:
             }
             }
             else {
             else {
                 SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
                 SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
-                StringStream srcStream(s.Pop());
+                GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
                 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
                 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
                 while (numCharsToCopy--) {
                 while (numCharsToCopy--) {
-                    Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
+                    Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
                 }
                 }
                 dstStream.Put('\0');
                 dstStream.Put('\0');
                 const typename TargetEncoding::Ch* str = dstStream.Pop();
                 const typename TargetEncoding::Ch* str = dstStream.Pop();
@@ -1685,7 +1707,7 @@ private:
         }
         }
         else {
         else {
            size_t length = s.Length();
            size_t length = s.Length();
-           const char* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
+           const NumberCharacter* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
 
 
            if (useDouble) {
            if (useDouble) {
                int p = exp + expFrac;
                int p = exp + expFrac;
@@ -1694,6 +1716,13 @@ private:
                else
                else
                    d = internal::StrtodNormalPrecision(d, p);
                    d = internal::StrtodNormalPrecision(d, p);
 
 
+               // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
+               if (d > (std::numeric_limits<double>::max)()) {
+                   // Overflow
+                   // TODO: internal::StrtodX should report overflow (or underflow)
+                   RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
+               }
+
                cont = handler.Double(minus ? -d : d);
                cont = handler.Double(minus ? -d : d);
            }
            }
            else if (useNanOrInf) {
            else if (useNanOrInf) {
@@ -1756,12 +1785,12 @@ private:
 
 
         // Single value state
         // Single value state
         IterativeParsingValueState,
         IterativeParsingValueState,
-        
+
         // Delimiter states (at bottom)
         // Delimiter states (at bottom)
         IterativeParsingElementDelimiterState,
         IterativeParsingElementDelimiterState,
         IterativeParsingMemberDelimiterState,
         IterativeParsingMemberDelimiterState,
         IterativeParsingKeyValueDelimiterState,
         IterativeParsingKeyValueDelimiterState,
-        
+
         cIterativeParsingStateCount
         cIterativeParsingStateCount
     };
     };
 
 
@@ -1785,7 +1814,7 @@ private:
         kTokenCount
         kTokenCount
     };
     };
 
 
-    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
+    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const {
 
 
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
 #define N NumberToken
 #define N NumberToken
@@ -1812,7 +1841,7 @@ private:
             return NumberToken;
             return NumberToken;
     }
     }
 
 
-    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
+    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const {
         // current state x one lookahead token -> new state
         // current state x one lookahead token -> new state
         static const char G[cIterativeParsingStateCount][kTokenCount] = {
         static const char G[cIterativeParsingStateCount][kTokenCount] = {
             // Finish(sink state)
             // Finish(sink state)
@@ -2151,46 +2180,46 @@ private:
         }
         }
     }
     }
 
 
-    RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) {
+    RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
         return s >= IterativeParsingElementDelimiterState;
         return s >= IterativeParsingElementDelimiterState;
     }
     }
-    
-    RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) {
+
+    RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
         return s <= IterativeParsingErrorState;
         return s <= IterativeParsingErrorState;
     }
     }
-    
+
     template <unsigned parseFlags, typename InputStream, typename Handler>
     template <unsigned parseFlags, typename InputStream, typename Handler>
     ParseResult IterativeParse(InputStream& is, Handler& handler) {
     ParseResult IterativeParse(InputStream& is, Handler& handler) {
         parseResult_.Clear();
         parseResult_.Clear();
         ClearStackOnExit scope(*this);
         ClearStackOnExit scope(*this);
         IterativeParsingState state = IterativeParsingStartState;
         IterativeParsingState state = IterativeParsingStartState;
-        
+
         SkipWhitespaceAndComments<parseFlags>(is);
         SkipWhitespaceAndComments<parseFlags>(is);
         RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
         RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
         while (is.Peek() != '\0') {
         while (is.Peek() != '\0') {
             Token t = Tokenize(is.Peek());
             Token t = Tokenize(is.Peek());
             IterativeParsingState n = Predict(state, t);
             IterativeParsingState n = Predict(state, t);
             IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
             IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
-            
+
             if (d == IterativeParsingErrorState) {
             if (d == IterativeParsingErrorState) {
                 HandleError(state, is);
                 HandleError(state, is);
                 break;
                 break;
             }
             }
-            
+
             state = d;
             state = d;
-            
+
             // Do not further consume streams if a root JSON has been parsed.
             // Do not further consume streams if a root JSON has been parsed.
             if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
             if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
                 break;
                 break;
-            
+
             SkipWhitespaceAndComments<parseFlags>(is);
             SkipWhitespaceAndComments<parseFlags>(is);
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
         }
         }
-        
+
         // Handle the end of file.
         // Handle the end of file.
         if (state != IterativeParsingFinishState)
         if (state != IterativeParsingFinishState)
             HandleError(state, is);
             HandleError(state, is);
-        
+
         return parseResult_;
         return parseResult_;
     }
     }
 
 
@@ -2205,7 +2234,7 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
 
 
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#ifdef __clang__
+#if defined(__clang__) || defined(_MSC_VER)
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 
@@ -2214,8 +2243,4 @@ RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
 #endif // RAPIDJSON_READER_H_
 #endif // RAPIDJSON_READER_H_

File diff suppressed because it is too large
+ 426 - 152
Source/ThirdParty/rapidjson/include/rapidjson/schema.h


+ 49 - 5
Source/ThirdParty/rapidjson/include/rapidjson/stream.h

@@ -1,15 +1,15 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
-// 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
 //
 //
 // http://opensource.org/licenses/MIT
 // http://opensource.org/licenses/MIT
 //
 //
-// Unless required by applicable law or agreed to in writing, software distributed 
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
 // specific language governing permissions and limitations under the License.
 // specific language governing permissions and limitations under the License.
 
 
 #include "rapidjson.h"
 #include "rapidjson.h"
@@ -100,6 +100,50 @@ inline void PutN(Stream& stream, Ch c, size_t n) {
         PutUnsafe(stream, c);
         PutUnsafe(stream, c);
 }
 }
 
 
+///////////////////////////////////////////////////////////////////////////////
+// GenericStreamWrapper
+
+//! A Stream Wrapper
+/*! \tThis string stream is a wrapper for any stream by just forwarding any
+    \treceived message to the origin stream.
+    \note implements Stream concept
+*/
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4702)  // unreachable code
+RAPIDJSON_DIAG_OFF(4512)  // assignment operator could not be generated
+#endif
+
+template <typename InputStream, typename Encoding = UTF8<> >
+class GenericStreamWrapper {
+public:
+    typedef typename Encoding::Ch Ch;
+    GenericStreamWrapper(InputStream& is): is_(is) {}
+
+    Ch Peek() const { return is_.Peek(); }
+    Ch Take() { return is_.Take(); }
+    size_t Tell() { return is_.Tell(); }
+    Ch* PutBegin() { return is_.PutBegin(); }
+    void Put(Ch ch) { is_.Put(ch); }
+    void Flush() { is_.Flush(); }
+    size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); }
+
+    // wrapper for MemoryStream
+    const Ch* Peek4() const { return is_.Peek4(); }
+
+    // wrapper for AutoUTFInputStream
+    UTFType GetType() const { return is_.GetType(); }
+    bool HasBOM() const { return is_.HasBOM(); }
+
+protected:
+    InputStream& is_;
+};
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_POP
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // StringStream
 // StringStream
 
 

+ 1 - 1
Source/ThirdParty/rapidjson/include/rapidjson/stringbuffer.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at

+ 481 - 0
Source/ThirdParty/rapidjson/include/rapidjson/uri.h

@@ -0,0 +1,481 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// (C) Copyright IBM Corporation 2021
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_URI_H_
+#define RAPIDJSON_URI_H_
+
+#include "internal/strfunc.h"
+
+#if defined(__clang__)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(c++98-compat)
+#elif defined(_MSC_VER)
+RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericUri
+
+template <typename ValueType, typename Allocator=CrtAllocator>
+class GenericUri {
+public:
+    typedef typename ValueType::Ch Ch;
+#if RAPIDJSON_HAS_STDSTRING
+    typedef std::basic_string<Ch> String;
+#endif
+
+    //! Constructors
+    GenericUri(Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+    }
+
+    GenericUri(const Ch* uri, SizeType len, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+        Parse(uri, len);
+    }
+
+    GenericUri(const Ch* uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+        Parse(uri, internal::StrLen<Ch>(uri));
+    }
+
+    // Use with specializations of GenericValue
+    template<typename T> GenericUri(const T& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+        const Ch* u = uri.template Get<const Ch*>(); // TypeHelper from document.h
+        Parse(u, internal::StrLen<Ch>(u));
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    GenericUri(const String& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+        Parse(uri.c_str(), internal::StrLen<Ch>(uri.c_str()));
+    }
+#endif
+
+    //! Copy constructor
+    GenericUri(const GenericUri& rhs) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(), ownAllocator_() {
+        *this = rhs;
+    }
+
+    //! Copy constructor
+    GenericUri(const GenericUri& rhs, Allocator* allocator) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
+        *this = rhs;
+    }
+
+    //! Destructor.
+    ~GenericUri() {
+        Free();
+        RAPIDJSON_DELETE(ownAllocator_);
+    }
+
+    //! Assignment operator
+    GenericUri& operator=(const GenericUri& rhs) {
+        if (this != &rhs) {
+            // Do not delete ownAllocator
+            Free();
+            Allocate(rhs.GetStringLength());
+            auth_ = CopyPart(scheme_, rhs.scheme_, rhs.GetSchemeStringLength());
+            path_ = CopyPart(auth_, rhs.auth_, rhs.GetAuthStringLength());
+            query_ = CopyPart(path_, rhs.path_, rhs.GetPathStringLength());
+            frag_ = CopyPart(query_, rhs.query_, rhs.GetQueryStringLength());
+            base_ = CopyPart(frag_, rhs.frag_, rhs.GetFragStringLength());
+            uri_ = CopyPart(base_, rhs.base_, rhs.GetBaseStringLength());
+            CopyPart(uri_, rhs.uri_, rhs.GetStringLength());
+        }
+        return *this;
+    }
+
+    //! Getters
+    // Use with specializations of GenericValue
+    template<typename T> void Get(T& uri, Allocator& allocator) {
+        uri.template Set<const Ch*>(this->GetString(), allocator); // TypeHelper from document.h
+    }
+
+    const Ch* GetString() const { return uri_; }
+    SizeType GetStringLength() const { return uri_ == 0 ? 0 : internal::StrLen<Ch>(uri_); }
+    const Ch* GetBaseString() const { return base_; }
+    SizeType GetBaseStringLength() const { return base_ == 0 ? 0 : internal::StrLen<Ch>(base_); }
+    const Ch* GetSchemeString() const { return scheme_; }
+    SizeType GetSchemeStringLength() const { return scheme_ == 0 ? 0 : internal::StrLen<Ch>(scheme_); }
+    const Ch* GetAuthString() const { return auth_; }
+    SizeType GetAuthStringLength() const { return auth_ == 0 ? 0 : internal::StrLen<Ch>(auth_); }
+    const Ch* GetPathString() const { return path_; }
+    SizeType GetPathStringLength() const { return path_ == 0 ? 0 : internal::StrLen<Ch>(path_); }
+    const Ch* GetQueryString() const { return query_; }
+    SizeType GetQueryStringLength() const { return query_ == 0 ? 0 : internal::StrLen<Ch>(query_); }
+    const Ch* GetFragString() const { return frag_; }
+    SizeType GetFragStringLength() const { return frag_ == 0 ? 0 : internal::StrLen<Ch>(frag_); }
+
+#if RAPIDJSON_HAS_STDSTRING
+    static String Get(const GenericUri& uri) { return String(uri.GetString(), uri.GetStringLength()); }
+    static String GetBase(const GenericUri& uri) { return String(uri.GetBaseString(), uri.GetBaseStringLength()); }
+    static String GetScheme(const GenericUri& uri) { return String(uri.GetSchemeString(), uri.GetSchemeStringLength()); }
+    static String GetAuth(const GenericUri& uri) { return String(uri.GetAuthString(), uri.GetAuthStringLength()); }
+    static String GetPath(const GenericUri& uri) { return String(uri.GetPathString(), uri.GetPathStringLength()); }
+    static String GetQuery(const GenericUri& uri) { return String(uri.GetQueryString(), uri.GetQueryStringLength()); }
+    static String GetFrag(const GenericUri& uri) { return String(uri.GetFragString(), uri.GetFragStringLength()); }
+#endif
+
+    //! Equality operators
+    bool operator==(const GenericUri& rhs) const {
+        return Match(rhs, true);
+    }
+
+    bool operator!=(const GenericUri& rhs) const {
+        return !Match(rhs, true);
+    }
+
+    bool Match(const GenericUri& uri, bool full = true) const {
+        Ch* s1;
+        Ch* s2;
+        if (full) {
+            s1 = uri_;
+            s2 = uri.uri_;
+        } else {
+            s1 = base_;
+            s2 = uri.base_;
+        }
+        if (s1 == s2) return true;
+        if (s1 == 0 || s2 == 0) return false;
+        return internal::StrCmp<Ch>(s1, s2) == 0;
+    }
+
+    //! Resolve this URI against another (base) URI in accordance with URI resolution rules.
+    // See https://tools.ietf.org/html/rfc3986
+    // Use for resolving an id or $ref with an in-scope id.
+    // Returns a new GenericUri for the resolved URI.
+    GenericUri Resolve(const GenericUri& baseuri, Allocator* allocator = 0) {
+        GenericUri resuri;
+        resuri.allocator_ = allocator;
+        // Ensure enough space for combining paths
+        resuri.Allocate(GetStringLength() + baseuri.GetStringLength() + 1); // + 1 for joining slash
+
+        if (!(GetSchemeStringLength() == 0)) {
+            // Use all of this URI
+            resuri.auth_ = CopyPart(resuri.scheme_, scheme_, GetSchemeStringLength());
+            resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
+            resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
+            resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
+            resuri.RemoveDotSegments();
+        } else {
+            // Use the base scheme
+            resuri.auth_ = CopyPart(resuri.scheme_, baseuri.scheme_, baseuri.GetSchemeStringLength());
+            if (!(GetAuthStringLength() == 0)) {
+                // Use this auth, path, query
+                resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
+                resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
+                resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
+                resuri.RemoveDotSegments();
+            } else {
+                // Use the base auth
+                resuri.path_ = CopyPart(resuri.auth_, baseuri.auth_, baseuri.GetAuthStringLength());
+                if (GetPathStringLength() == 0) {
+                    // Use the base path
+                    resuri.query_ = CopyPart(resuri.path_, baseuri.path_, baseuri.GetPathStringLength());
+                    if (GetQueryStringLength() == 0) {
+                        // Use the base query
+                        resuri.frag_ = CopyPart(resuri.query_, baseuri.query_, baseuri.GetQueryStringLength());
+                    } else {
+                        // Use this query
+                        resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
+                    }
+                } else {
+                    if (path_[0] == '/') {
+                        // Absolute path - use all of this path
+                        resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
+                        resuri.RemoveDotSegments();
+                    } else {
+                        // Relative path - append this path to base path after base path's last slash
+                        size_t pos = 0;
+                        if (!(baseuri.GetAuthStringLength() == 0) && baseuri.GetPathStringLength() == 0) {
+                            resuri.path_[pos] = '/';
+                            pos++;
+                        }
+                        size_t lastslashpos = baseuri.GetPathStringLength();
+                        while (lastslashpos > 0) {
+                            if (baseuri.path_[lastslashpos - 1] == '/') break;
+                            lastslashpos--;
+                        }
+                        std::memcpy(&resuri.path_[pos], baseuri.path_, lastslashpos * sizeof(Ch));
+                        pos += lastslashpos;
+                        resuri.query_ = CopyPart(&resuri.path_[pos], path_, GetPathStringLength());
+                        resuri.RemoveDotSegments();
+                    }
+                    // Use this query
+                    resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
+                }
+            }
+        }
+        // Always use this frag
+        resuri.base_ = CopyPart(resuri.frag_, frag_, GetFragStringLength());
+
+        // Re-constitute base_ and uri_
+        resuri.SetBase();
+        resuri.uri_ = resuri.base_ + resuri.GetBaseStringLength() + 1;
+        resuri.SetUri();
+        return resuri;
+    }
+
+    //! Get the allocator of this GenericUri.
+    Allocator& GetAllocator() { return *allocator_; }
+
+private:
+    // Allocate memory for a URI
+    // Returns total amount allocated
+    std::size_t Allocate(std::size_t len) {
+        // Create own allocator if user did not supply.
+        if (!allocator_)
+            ownAllocator_ =  allocator_ = RAPIDJSON_NEW(Allocator)();
+
+        // Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated.
+        // Order: scheme, auth, path, query, frag, base, uri
+        // Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
+        size_t total = (3 * len + 7) * sizeof(Ch);
+        scheme_ = static_cast<Ch*>(allocator_->Malloc(total));
+        *scheme_ = '\0';
+        auth_ = scheme_;
+        auth_++;
+        *auth_ = '\0';
+        path_ = auth_;
+        path_++;
+        *path_ = '\0';
+        query_ = path_;
+        query_++;
+        *query_ = '\0';
+        frag_ = query_;
+        frag_++;
+        *frag_ = '\0';
+        base_ = frag_;
+        base_++;
+        *base_ = '\0';
+        uri_ = base_;
+        uri_++;
+        *uri_ = '\0';
+        return total;
+    }
+
+    // Free memory for a URI
+    void Free() {
+        if (scheme_) {
+            Allocator::Free(scheme_);
+            scheme_ = 0;
+        }
+    }
+
+    // Parse a URI into constituent scheme, authority, path, query, & fragment parts
+    // Supports URIs that match regex ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? as per
+    // https://tools.ietf.org/html/rfc3986
+    void Parse(const Ch* uri, std::size_t len) {
+        std::size_t start = 0, pos1 = 0, pos2 = 0;
+        Allocate(len);
+
+        // Look for scheme ([^:/?#]+):)?
+        if (start < len) {
+            while (pos1 < len) {
+                if (uri[pos1] == ':') break;
+                pos1++;
+            }
+            if (pos1 != len) {
+                while (pos2 < len) {
+                    if (uri[pos2] == '/') break;
+                    if (uri[pos2] == '?') break;
+                    if (uri[pos2] == '#') break;
+                    pos2++;
+                }
+                if (pos1 < pos2) {
+                    pos1++;
+                    std::memcpy(scheme_, &uri[start], pos1 * sizeof(Ch));
+                    scheme_[pos1] = '\0';
+                    start = pos1;
+                }
+            }
+        }
+        // Look for auth (//([^/?#]*))?
+        // Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
+        auth_ = scheme_ + GetSchemeStringLength();
+        auth_++;
+        *auth_ = '\0';
+        if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') {
+            pos2 = start + 2;
+            while (pos2 < len) {
+                if (uri[pos2] == '/') break;
+                if (uri[pos2] == '?') break;
+                if (uri[pos2] == '#') break;
+                pos2++;
+            }
+            std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch));
+            auth_[pos2 - start] = '\0';
+            start = pos2;
+        }
+        // Look for path ([^?#]*)
+        // Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
+        path_ = auth_ + GetAuthStringLength();
+        path_++;
+        *path_ = '\0';
+        if (start < len) {
+            pos2 = start;
+            while (pos2 < len) {
+                if (uri[pos2] == '?') break;
+                if (uri[pos2] == '#') break;
+                pos2++;
+            }
+            if (start != pos2) {
+                std::memcpy(path_, &uri[start], (pos2 - start) * sizeof(Ch));
+                path_[pos2 - start] = '\0';
+                if (path_[0] == '/')
+                    RemoveDotSegments();   // absolute path - normalize
+                start = pos2;
+            }
+        }
+        // Look for query (\?([^#]*))?
+        // Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
+        query_ = path_ + GetPathStringLength();
+        query_++;
+        *query_ = '\0';
+        if (start < len && uri[start] == '?') {
+            pos2 = start + 1;
+            while (pos2 < len) {
+                if (uri[pos2] == '#') break;
+                pos2++;
+            }
+            if (start != pos2) {
+                std::memcpy(query_, &uri[start], (pos2 - start) * sizeof(Ch));
+                query_[pos2 - start] = '\0';
+                start = pos2;
+            }
+        }
+        // Look for fragment (#(.*))?
+        // Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
+        frag_ = query_ + GetQueryStringLength();
+        frag_++;
+        *frag_ = '\0';
+        if (start < len && uri[start] == '#') {
+            std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch));
+            frag_[len - start] = '\0';
+        }
+
+        // Re-constitute base_ and uri_
+        base_ = frag_ + GetFragStringLength() + 1;
+        SetBase();
+        uri_ = base_ + GetBaseStringLength() + 1;
+        SetUri();
+    }
+
+    // Reconstitute base
+    void SetBase() {
+        Ch* next = base_;
+        std::memcpy(next, scheme_, GetSchemeStringLength() * sizeof(Ch));
+        next+= GetSchemeStringLength();
+        std::memcpy(next, auth_, GetAuthStringLength() * sizeof(Ch));
+        next+= GetAuthStringLength();
+        std::memcpy(next, path_, GetPathStringLength() * sizeof(Ch));
+        next+= GetPathStringLength();
+        std::memcpy(next, query_, GetQueryStringLength() * sizeof(Ch));
+        next+= GetQueryStringLength();
+        *next = '\0';
+    }
+
+    // Reconstitute uri
+    void SetUri() {
+        Ch* next = uri_;
+        std::memcpy(next, base_, GetBaseStringLength() * sizeof(Ch));
+        next+= GetBaseStringLength();
+        std::memcpy(next, frag_, GetFragStringLength() * sizeof(Ch));
+        next+= GetFragStringLength();
+        *next = '\0';
+    }
+
+    // Copy a part from one GenericUri to another
+    // Return the pointer to the next part to be copied to
+    Ch* CopyPart(Ch* to, Ch* from, std::size_t len) {
+        RAPIDJSON_ASSERT(to != 0);
+        RAPIDJSON_ASSERT(from != 0);
+        std::memcpy(to, from, len * sizeof(Ch));
+        to[len] = '\0';
+        Ch* next = to + len + 1;
+        return next;
+    }
+
+    // Remove . and .. segments from the path_ member.
+    // https://tools.ietf.org/html/rfc3986
+    // This is done in place as we are only removing segments.
+    void RemoveDotSegments() {
+        std::size_t pathlen = GetPathStringLength();
+        std::size_t pathpos = 0;  // Position in path_
+        std::size_t newpos = 0;   // Position in new path_
+
+        // Loop through each segment in original path_
+        while (pathpos < pathlen) {
+            // Get next segment, bounded by '/' or end
+            size_t slashpos = 0;
+            while ((pathpos + slashpos) < pathlen) {
+                if (path_[pathpos + slashpos] == '/') break;
+                slashpos++;
+            }
+            // Check for .. and . segments
+            if (slashpos == 2 && path_[pathpos] == '.' && path_[pathpos + 1] == '.') {
+                // Backup a .. segment in the new path_
+                // We expect to find a previously added slash at the end or nothing
+                RAPIDJSON_ASSERT(newpos == 0 || path_[newpos - 1] == '/');
+                size_t lastslashpos = newpos;
+                // Make sure we don't go beyond the start segment
+                if (lastslashpos > 1) {
+                    // Find the next to last slash and back up to it
+                    lastslashpos--;
+                    while (lastslashpos > 0) {
+                        if (path_[lastslashpos - 1] == '/') break;
+                        lastslashpos--;
+                    }
+                    // Set the new path_ position
+                    newpos = lastslashpos;
+                }
+            } else if (slashpos == 1 && path_[pathpos] == '.') {
+                // Discard . segment, leaves new path_ unchanged
+            } else {
+                // Move any other kind of segment to the new path_
+                RAPIDJSON_ASSERT(newpos <= pathpos);
+                std::memmove(&path_[newpos], &path_[pathpos], slashpos * sizeof(Ch));
+                newpos += slashpos;
+                // Add slash if not at end
+                if ((pathpos + slashpos) < pathlen) {
+                    path_[newpos] = '/';
+                    newpos++;
+                }
+            }
+            // Move to next segment
+            pathpos += slashpos + 1;
+        }
+        path_[newpos] = '\0';
+    }
+
+    Ch* uri_;    // Everything
+    Ch* base_;   // Everything except fragment
+    Ch* scheme_; // Includes the :
+    Ch* auth_;   // Includes the //
+    Ch* path_;   // Absolute if starts with /
+    Ch* query_;  // Includes the ?
+    Ch* frag_;   // Includes the #
+
+    Allocator* allocator_;      //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
+    Allocator* ownAllocator_;   //!< Allocator owned by this Uri.
+};
+
+//! GenericUri for Value (UTF-8, default allocator).
+typedef GenericUri<Value> Uri;
+
+RAPIDJSON_NAMESPACE_END
+
+#if defined(__clang__)
+RAPIDJSON_DIAG_POP
+#endif
+
+#endif // RAPIDJSON_URI_H_

+ 26 - 20
Source/ThirdParty/rapidjson/include/rapidjson/writer.h

@@ -1,6 +1,6 @@
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // Tencent is pleased to support the open source community by making RapidJSON available.
 // 
 // 
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 //
 //
 // Licensed under the MIT License (the "License"); you may not use this file except
 // Licensed under the MIT License (the "License"); you may not use this file except
 // in compliance with the License. You may obtain a copy of the License at
 // in compliance with the License. You may obtain a copy of the License at
@@ -16,6 +16,7 @@
 #define RAPIDJSON_WRITER_H_
 #define RAPIDJSON_WRITER_H_
 
 
 #include "stream.h"
 #include "stream.h"
+#include "internal/clzll.h"
 #include "internal/meta.h"
 #include "internal/meta.h"
 #include "internal/stack.h"
 #include "internal/stack.h"
 #include "internal/strfunc.h"
 #include "internal/strfunc.h"
@@ -36,16 +37,14 @@
 #include <arm_neon.h>
 #include <arm_neon.h>
 #endif
 #endif
 
 
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
-#endif
-
 #ifdef __clang__
 #ifdef __clang__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(padded)
 RAPIDJSON_DIAG_OFF(unreachable-code)
 RAPIDJSON_DIAG_OFF(unreachable-code)
 RAPIDJSON_DIAG_OFF(c++98-compat)
 RAPIDJSON_DIAG_OFF(c++98-compat)
+#elif defined(_MSC_VER)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
 #endif
 #endif
 
 
 RAPIDJSON_NAMESPACE_BEGIN
 RAPIDJSON_NAMESPACE_BEGIN
@@ -222,6 +221,13 @@ public:
 
 
     bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
     bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
 
 
+#if RAPIDJSON_HAS_STDSTRING
+    bool Key(const std::basic_string<Ch>& str)
+    {
+      return Key(str.data(), SizeType(str.size()));
+    }
+#endif
+
     bool EndObject(SizeType memberCount = 0) {
     bool EndObject(SizeType memberCount = 0) {
         (void)memberCount;
         (void)memberCount;
         RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
         RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
@@ -277,6 +283,8 @@ public:
         os_->Flush();
         os_->Flush();
     }
     }
 
 
+    static const size_t kDefaultLevelDepth = 32;
+
 protected:
 protected:
     //! Information for each nested level
     //! Information for each nested level
     struct Level {
     struct Level {
@@ -285,8 +293,6 @@ protected:
         bool inArray;       //!< true if in array, otherwise in object
         bool inArray;       //!< true if in array, otherwise in object
     };
     };
 
 
-    static const size_t kDefaultLevelDepth = 32;
-
     bool WriteNull()  {
     bool WriteNull()  {
         PutReserve(*os_, 4);
         PutReserve(*os_, 4);
         PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
         PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
@@ -453,9 +459,13 @@ protected:
 
 
     bool WriteRawValue(const Ch* json, size_t length) {
     bool WriteRawValue(const Ch* json, size_t length) {
         PutReserve(*os_, length);
         PutReserve(*os_, length);
-        for (size_t i = 0; i < length; i++) {
-            RAPIDJSON_ASSERT(json[i] != '\0');
-            PutUnsafe(*os_, json[i]);
+        GenericStringStream<SourceEncoding> is(json);
+        while (RAPIDJSON_LIKELY(is.Tell() < length)) {
+            RAPIDJSON_ASSERT(is.Peek() != '\0');
+            if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? 
+                Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
+                Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
+                return false;
         }
         }
         return true;
         return true;
     }
     }
@@ -659,19 +669,19 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
         x = vorrq_u8(x, vcltq_u8(s, s3));
         x = vorrq_u8(x, vcltq_u8(s, s3));
 
 
         x = vrev64q_u8(x);                     // Rev in 64
         x = vrev64q_u8(x);                     // Rev in 64
-        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
-        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
+        uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);   // extract
+        uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);  // extract
 
 
         SizeType len = 0;
         SizeType len = 0;
         bool escaped = false;
         bool escaped = false;
         if (low == 0) {
         if (low == 0) {
             if (high != 0) {
             if (high != 0) {
-                unsigned lz = (unsigned)__builtin_clzll(high);
+                uint32_t lz = internal::clzll(high);
                 len = 8 + (lz >> 3);
                 len = 8 + (lz >> 3);
                 escaped = true;
                 escaped = true;
             }
             }
         } else {
         } else {
-            unsigned lz = (unsigned)__builtin_clzll(low);
+            uint32_t lz = internal::clzll(low);
             len = lz >> 3;
             len = lz >> 3;
             escaped = true;
             escaped = true;
         }
         }
@@ -693,11 +703,7 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
 
 
 RAPIDJSON_NAMESPACE_END
 RAPIDJSON_NAMESPACE_END
 
 
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef __clang__
+#if defined(_MSC_VER) || defined(__clang__)
 RAPIDJSON_DIAG_POP
 RAPIDJSON_DIAG_POP
 #endif
 #endif
 
 

Some files were not shown because too many files changed in this diff