mirror of
https://github.com/xmrig/xmrig.git
synced 2025-03-09 10:16:05 +00:00
Update rapidjson.
This commit is contained in:
parent
df4532d9a1
commit
234de96784
49 changed files with 2673 additions and 568 deletions
520
src/3rdparty/rapidjson/allocators.h
vendored
520
src/3rdparty/rapidjson/allocators.h
vendored
|
@ -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
|
||||||
|
|
||||||
|
@ -77,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); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -113,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.
|
||||||
|
@ -136,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_SHARED_DATA + SIZEOF_CHUNK_HEADER);
|
||||||
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
shared_->chunkHead = GetChunkHead(shared_);
|
||||||
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
|
||||||
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
shared_->chunkHead->size = 0;
|
||||||
chunkHead_->size = 0;
|
shared_->chunkHead->next = 0;
|
||||||
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.
|
//! Deallocates all memory chunks, excluding the first/user one.
|
||||||
void Clear() {
|
void Clear() RAPIDJSON_NOEXCEPT {
|
||||||
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||||
ChunkHeader* next = chunkHead_->next;
|
for (;;) {
|
||||||
baseAllocator_->Free(chunkHead_);
|
ChunkHeader* c = shared_->chunkHead;
|
||||||
chunkHead_ = next;
|
if (!c->next) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shared_->chunkHead = c->next;
|
||||||
|
baseAllocator_->Free(c);
|
||||||
}
|
}
|
||||||
if (chunkHead_ && chunkHead_ == userBuffer_)
|
shared_->chunkHead->size = 0;
|
||||||
chunkHead_->size = 0; // Clear user buffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! 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;
|
||||||
}
|
}
|
||||||
|
@ -178,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;
|
void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
|
||||||
chunkHead_->size += size;
|
shared_->chunkHead->size += size;
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,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;
|
||||||
|
|
||||||
|
@ -216,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) {
|
if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
|
||||||
chunkHead_->size += increment;
|
shared_->chunkHead->size += increment;
|
||||||
return originalPtr;
|
return originalPtr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,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
|
||||||
|
|
||||||
|
//! 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:
|
private:
|
||||||
//! Copy constructor is not permitted.
|
|
||||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
|
|
||||||
//! Copy assignment operator is not permitted.
|
|
||||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
|
|
||||||
|
|
||||||
//! 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)();
|
shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
|
||||||
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
|
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_;
|
chunk->next = shared_->chunkHead;
|
||||||
chunkHead_ = chunk;
|
shared_->chunkHead = chunk;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//! Chunk header for perpending to each chunk.
|
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||||
/*! Chunks are stored as a singly linked list.
|
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||||
*/
|
SharedData *shared_; //!< The shared data of the allocator
|
||||||
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.
|
namespace internal {
|
||||||
ChunkHeader *next; //!< Next chunk in the linked list.
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
typedef typename traits_type::size_type size_type;
|
||||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
typedef typename traits_type::difference_type difference_type;
|
||||||
void *userBuffer_; //!< User supplied buffer.
|
|
||||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
typedef typename traits_type::value_type value_type;
|
||||||
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
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_
|
||||||
|
|
2
src/3rdparty/rapidjson/cursorstreamwrapper.h
vendored
2
src/3rdparty/rapidjson/cursorstreamwrapper.h
vendored
|
@ -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
|
||||||
|
|
541
src/3rdparty/rapidjson/document.h
vendored
541
src/3rdparty/rapidjson/document.h
vendored
|
@ -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
|
||||||
|
@ -24,6 +24,9 @@
|
||||||
#include "encodedstream.h"
|
#include "encodedstream.h"
|
||||||
#include <new> // placement new
|
#include <new> // placement new
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
|
#include <compare>
|
||||||
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@ -39,12 +42,21 @@ RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible lo
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#endif // __GNUC__
|
#endif // __GNUC__
|
||||||
|
|
||||||
|
#ifdef GetObject
|
||||||
|
// see https://github.com/Tencent/rapidjson/issues/1448
|
||||||
|
// a former included windows.h might have defined a macro called GetObject, which affects
|
||||||
|
// GetObject defined here. This ensures the macro does not get applied
|
||||||
|
#pragma push_macro("GetObject")
|
||||||
|
#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||||
|
#undef GetObject
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
#include <iterator> // std::random_access_iterator_tag
|
#include <iterator> // std::random_access_iterator_tag
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
#include <utility> // std::move
|
#include <map> // std::multimap
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
@ -56,6 +68,48 @@ class GenericValue;
|
||||||
template <typename Encoding, typename Allocator, typename StackAllocator>
|
template <typename Encoding, typename Allocator, typename StackAllocator>
|
||||||
class GenericDocument;
|
class GenericDocument;
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_DEFAULT_ALLOCATOR
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief Allows to choose default allocator.
|
||||||
|
|
||||||
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
||||||
|
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief Allows to choose default stack allocator for Document.
|
||||||
|
|
||||||
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
|
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User defined kDefaultObjectCapacity value.
|
||||||
|
|
||||||
|
User can define this as any natural number.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||||
|
// number of objects that rapidjson::Value allocates memory for by default
|
||||||
|
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User defined kDefaultArrayCapacity value.
|
||||||
|
|
||||||
|
User can define this as any natural number.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
|
||||||
|
// number of array elements that rapidjson::Value allocates memory for by default
|
||||||
|
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
|
||||||
|
#endif
|
||||||
|
|
||||||
//! Name-value pair in a JSON object value.
|
//! Name-value pair in a JSON object value.
|
||||||
/*!
|
/*!
|
||||||
This class was internal to GenericValue. It used to be a inner struct.
|
This class was internal to GenericValue. It used to be a inner struct.
|
||||||
|
@ -63,15 +117,45 @@ class GenericDocument;
|
||||||
https://code.google.com/p/rapidjson/issues/detail?id=64
|
https://code.google.com/p/rapidjson/issues/detail?id=64
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMember {
|
class GenericMember {
|
||||||
|
public:
|
||||||
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
||||||
GenericValue<Encoding, Allocator> value; //!< value of member.
|
GenericValue<Encoding, Allocator> value; //!< value of member.
|
||||||
|
|
||||||
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
|
//! Move constructor in C++11
|
||||||
|
GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
: name(std::move(rhs.name)),
|
||||||
|
value(std::move(rhs.value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Move assignment in C++11
|
||||||
|
GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
return *this = static_cast<GenericMember&>(rhs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Assignment with move semantics.
|
||||||
|
/*! \param rhs Source of the assignment. Its name and value will become a null value after assignment.
|
||||||
|
*/
|
||||||
|
GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||||
|
name = rhs.name;
|
||||||
|
value = rhs.value;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// swap() for std::sort() and other potential use in STL.
|
// swap() for std::sort() and other potential use in STL.
|
||||||
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
||||||
a.name.Swap(b.name);
|
a.name.Swap(b.name);
|
||||||
a.value.Swap(b.value);
|
a.value.Swap(b.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Copy constructor is not permitted.
|
||||||
|
GenericMember(const GenericMember& rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -175,12 +259,16 @@ public:
|
||||||
|
|
||||||
//! @name relations
|
//! @name relations
|
||||||
//@{
|
//@{
|
||||||
bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
|
template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
|
||||||
bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
|
template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
|
||||||
bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
|
template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
|
||||||
bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
|
template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
|
||||||
bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
|
template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
|
||||||
bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
|
template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
|
template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
|
||||||
|
#endif
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! @name dereference
|
//! @name dereference
|
||||||
|
@ -210,12 +298,14 @@ class GenericMemberIterator;
|
||||||
//! non-const GenericMemberIterator
|
//! non-const GenericMemberIterator
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
class GenericMemberIterator<false,Encoding,Allocator> {
|
class GenericMemberIterator<false,Encoding,Allocator> {
|
||||||
|
public:
|
||||||
//! use plain pointer as iterator type
|
//! use plain pointer as iterator type
|
||||||
typedef GenericMember<Encoding,Allocator>* Iterator;
|
typedef GenericMember<Encoding,Allocator>* Iterator;
|
||||||
};
|
};
|
||||||
//! const GenericMemberIterator
|
//! const GenericMemberIterator
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
class GenericMemberIterator<true,Encoding,Allocator> {
|
class GenericMemberIterator<true,Encoding,Allocator> {
|
||||||
|
public:
|
||||||
//! use plain const pointer as iterator type
|
//! use plain const pointer as iterator type
|
||||||
typedef const GenericMember<Encoding,Allocator>* Iterator;
|
typedef const GenericMember<Encoding,Allocator>* Iterator;
|
||||||
};
|
};
|
||||||
|
@ -574,7 +664,7 @@ template <bool, typename> class GenericObject;
|
||||||
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
|
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
|
||||||
\tparam Allocator Allocator type for allocating memory of object, array and string.
|
\tparam Allocator Allocator type for allocating memory of object, array and string.
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
|
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
|
||||||
class GenericValue {
|
class GenericValue {
|
||||||
public:
|
public:
|
||||||
//! Name-value pair in an object.
|
//! Name-value pair in an object.
|
||||||
|
@ -651,18 +741,8 @@ public:
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator>
|
||||||
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
|
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
|
||||||
switch (rhs.GetType()) {
|
switch (rhs.GetType()) {
|
||||||
case kObjectType: {
|
case kObjectType:
|
||||||
SizeType count = rhs.data_.o.size;
|
DoCopyMembers(rhs, allocator, copyConstStrings);
|
||||||
Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
|
||||||
const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
|
|
||||||
for (SizeType i = 0; i < count; i++) {
|
|
||||||
new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
|
|
||||||
new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
|
|
||||||
}
|
|
||||||
data_.f.flags = kObjectFlag;
|
|
||||||
data_.o.size = data_.o.capacity = count;
|
|
||||||
SetMembersPointer(lm);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case kArrayType: {
|
case kArrayType: {
|
||||||
SizeType count = rhs.data_.a.size;
|
SizeType count = rhs.data_.a.size;
|
||||||
|
@ -798,25 +878,30 @@ public:
|
||||||
/*! Need to destruct elements of array, members of object, or copy-string.
|
/*! Need to destruct elements of array, members of object, or copy-string.
|
||||||
*/
|
*/
|
||||||
~GenericValue() {
|
~GenericValue() {
|
||||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
// With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
|
||||||
|
// their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
|
||||||
|
if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
|
||||||
|
internal::IsRefCounted<Allocator>::Value)) {
|
||||||
switch(data_.f.flags) {
|
switch(data_.f.flags) {
|
||||||
case kArrayFlag:
|
case kArrayFlag:
|
||||||
{
|
{
|
||||||
GenericValue* e = GetElementsPointer();
|
GenericValue* e = GetElementsPointer();
|
||||||
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
||||||
v->~GenericValue();
|
v->~GenericValue();
|
||||||
Allocator::Free(e);
|
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||||
|
Allocator::Free(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kObjectFlag:
|
case kObjectFlag:
|
||||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
DoFreeMembers();
|
||||||
m->~Member();
|
|
||||||
Allocator::Free(GetMembersPointer());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kCopyStringFlag:
|
case kCopyStringFlag:
|
||||||
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||||
|
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -835,8 +920,13 @@ public:
|
||||||
*/
|
*/
|
||||||
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||||
|
// Can't destroy "this" before assigning "rhs", otherwise "rhs"
|
||||||
|
// could be used after free if it's an sub-Value of "this",
|
||||||
|
// hence the temporary danse.
|
||||||
|
GenericValue temp;
|
||||||
|
temp.RawAssign(rhs);
|
||||||
this->~GenericValue();
|
this->~GenericValue();
|
||||||
RawAssign(rhs);
|
RawAssign(temp);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -1002,6 +1092,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
|
#ifndef __cpp_lib_three_way_comparison
|
||||||
//! Equal-to operator with arbitrary types (symmetric version)
|
//! Equal-to operator with arbitrary types (symmetric version)
|
||||||
/*! \return (rhs == lhs)
|
/*! \return (rhs == lhs)
|
||||||
*/
|
*/
|
||||||
|
@ -1012,6 +1103,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
||||||
//@}
|
//@}
|
||||||
|
#endif
|
||||||
|
|
||||||
//!@name Type
|
//!@name Type
|
||||||
//@{
|
//@{
|
||||||
|
@ -1177,10 +1269,7 @@ public:
|
||||||
*/
|
*/
|
||||||
GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
|
GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
RAPIDJSON_ASSERT(IsObject());
|
||||||
if (newCapacity > data_.o.capacity) {
|
DoReserveMembers(newCapacity, allocator);
|
||||||
SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
|
|
||||||
data_.o.capacity = newCapacity;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,11 +1343,7 @@ public:
|
||||||
MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
RAPIDJSON_ASSERT(IsObject());
|
||||||
RAPIDJSON_ASSERT(name.IsString());
|
RAPIDJSON_ASSERT(name.IsString());
|
||||||
MemberIterator member = MemberBegin();
|
return DoFindMember(name);
|
||||||
for ( ; member != MemberEnd(); ++member)
|
|
||||||
if (name.StringEqual(member->name))
|
|
||||||
break;
|
|
||||||
return member;
|
|
||||||
}
|
}
|
||||||
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
||||||
|
|
||||||
|
@ -1287,14 +1372,7 @@ public:
|
||||||
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
RAPIDJSON_ASSERT(IsObject());
|
||||||
RAPIDJSON_ASSERT(name.IsString());
|
RAPIDJSON_ASSERT(name.IsString());
|
||||||
|
DoAddMember(name, value, allocator);
|
||||||
ObjectData& o = data_.o;
|
|
||||||
if (o.size >= o.capacity)
|
|
||||||
MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
|
|
||||||
Member* members = GetMembersPointer();
|
|
||||||
members[o.size].name.RawAssign(name);
|
|
||||||
members[o.size].value.RawAssign(value);
|
|
||||||
o.size++;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,9 +1506,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void RemoveAllMembers() {
|
void RemoveAllMembers() {
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
RAPIDJSON_ASSERT(IsObject());
|
||||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
DoClearMembers();
|
||||||
m->~Member();
|
|
||||||
data_.o.size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Remove a member in object by its name.
|
//! Remove a member in object by its name.
|
||||||
|
@ -1474,14 +1550,7 @@ public:
|
||||||
RAPIDJSON_ASSERT(data_.o.size > 0);
|
RAPIDJSON_ASSERT(data_.o.size > 0);
|
||||||
RAPIDJSON_ASSERT(GetMembersPointer() != 0);
|
RAPIDJSON_ASSERT(GetMembersPointer() != 0);
|
||||||
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
|
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
|
||||||
|
return DoRemoveMember(m);
|
||||||
MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
|
|
||||||
if (data_.o.size > 1 && m != last)
|
|
||||||
*m = *last; // Move the last one to this place
|
|
||||||
else
|
|
||||||
m->~Member(); // Only one left, just destroy
|
|
||||||
--data_.o.size;
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Remove a member from an object by iterator.
|
//! Remove a member from an object by iterator.
|
||||||
|
@ -1513,13 +1582,7 @@ public:
|
||||||
RAPIDJSON_ASSERT(first >= MemberBegin());
|
RAPIDJSON_ASSERT(first >= MemberBegin());
|
||||||
RAPIDJSON_ASSERT(first <= last);
|
RAPIDJSON_ASSERT(first <= last);
|
||||||
RAPIDJSON_ASSERT(last <= MemberEnd());
|
RAPIDJSON_ASSERT(last <= MemberEnd());
|
||||||
|
return DoEraseMembers(first, last);
|
||||||
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
|
||||||
for (MemberIterator itr = pos; itr != last; ++itr)
|
|
||||||
itr->~Member();
|
|
||||||
std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
|
||||||
data_.o.size -= static_cast<SizeType>(last - first);
|
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Erase a member in object by its name.
|
//! Erase a member in object by its name.
|
||||||
|
@ -1548,7 +1611,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||||
|
Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||||
ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||||
|
ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@ -1770,12 +1835,12 @@ public:
|
||||||
//!@name String
|
//!@name String
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
|
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
|
||||||
|
|
||||||
//! Get the length of string.
|
//! Get the length of string.
|
||||||
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
||||||
*/
|
*/
|
||||||
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
|
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
|
||||||
|
|
||||||
//! Set this value as a string without copying source string.
|
//! Set this value as a string without copying source string.
|
||||||
/*! This version has better performance with supplied length, and also support string containing null character.
|
/*! This version has better performance with supplied length, and also support string containing null character.
|
||||||
|
@ -1886,7 +1951,7 @@ public:
|
||||||
case kArrayType:
|
case kArrayType:
|
||||||
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
||||||
return false;
|
return false;
|
||||||
for (const GenericValue* v = Begin(); v != End(); ++v)
|
for (ConstValueIterator v = Begin(); v != End(); ++v)
|
||||||
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
|
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
|
||||||
return false;
|
return false;
|
||||||
return handler.EndArray(data_.a.size);
|
return handler.EndArray(data_.a.size);
|
||||||
|
@ -1922,25 +1987,26 @@ private:
|
||||||
|
|
||||||
// Initial flags of different types.
|
// Initial flags of different types.
|
||||||
kNullFlag = kNullType,
|
kNullFlag = kNullType,
|
||||||
kTrueFlag = kTrueType | kBoolFlag,
|
// These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
|
||||||
kFalseFlag = kFalseType | kBoolFlag,
|
kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
|
||||||
kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
|
kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
|
||||||
kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
|
kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
|
||||||
kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
|
kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
|
||||||
kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
|
kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
|
||||||
kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
|
kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
|
||||||
kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
|
kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
|
||||||
kConstStringFlag = kStringType | kStringFlag,
|
kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
|
||||||
kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
|
kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
|
||||||
kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
|
kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
|
||||||
|
kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
|
||||||
kObjectFlag = kObjectType,
|
kObjectFlag = kObjectType,
|
||||||
kArrayFlag = kArrayType,
|
kArrayFlag = kArrayType,
|
||||||
|
|
||||||
kTypeMask = 0x07
|
kTypeMask = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SizeType kDefaultArrayCapacity = 16;
|
static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
|
||||||
static const SizeType kDefaultObjectCapacity = 16;
|
static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
|
||||||
|
|
||||||
struct Flag {
|
struct Flag {
|
||||||
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
||||||
|
@ -2023,6 +2089,13 @@ private:
|
||||||
Flag f;
|
Flag f;
|
||||||
}; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
}; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
|
||||||
|
return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
|
||||||
|
}
|
||||||
|
static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
|
||||||
|
return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
|
||||||
|
}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
|
RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
|
||||||
RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
|
RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
|
||||||
RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
|
RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
|
||||||
|
@ -2030,6 +2103,286 @@ private:
|
||||||
RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
|
RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
|
||||||
RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
|
RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
|
||||||
|
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
|
||||||
|
struct MapTraits {
|
||||||
|
struct Less {
|
||||||
|
bool operator()(const Data& s1, const Data& s2) const {
|
||||||
|
SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
|
||||||
|
int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
|
||||||
|
return cmp < 0 || (cmp == 0 && n1 < n2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::pair<const Data, SizeType> Pair;
|
||||||
|
typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
|
||||||
|
typedef typename Map::iterator Iterator;
|
||||||
|
};
|
||||||
|
typedef typename MapTraits::Map Map;
|
||||||
|
typedef typename MapTraits::Less MapLess;
|
||||||
|
typedef typename MapTraits::Pair MapPair;
|
||||||
|
typedef typename MapTraits::Iterator MapIterator;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Layout of the members' map/array, re(al)located according to the needed capacity:
|
||||||
|
//
|
||||||
|
// {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
|
||||||
|
//
|
||||||
|
// (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
|
||||||
|
//
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
|
||||||
|
return RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(SizeType)) +
|
||||||
|
RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
|
||||||
|
capacity * sizeof(MapIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
|
||||||
|
return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(Map*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
|
||||||
|
return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(SizeType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
|
||||||
|
return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||||
|
RAPIDJSON_ALIGN(sizeof(SizeType)) +
|
||||||
|
RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
|
||||||
|
RAPIDJSON_ASSERT(members != 0);
|
||||||
|
return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
|
||||||
|
RAPIDJSON_ALIGN(sizeof(SizeType)) -
|
||||||
|
RAPIDJSON_ALIGN(sizeof(Map*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
|
||||||
|
RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
|
||||||
|
#if RAPIDJSON_HAS_CXX11
|
||||||
|
MapIterator ret = std::move(rhs);
|
||||||
|
#else
|
||||||
|
MapIterator ret = rhs;
|
||||||
|
#endif
|
||||||
|
rhs.~MapIterator();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
|
||||||
|
Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
|
||||||
|
GetMapCapacity(*newMap) = newCapacity;
|
||||||
|
if (!oldMap) {
|
||||||
|
*newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*newMap = *oldMap;
|
||||||
|
size_t count = (*oldMap)->size();
|
||||||
|
std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
|
||||||
|
static_cast<void*>(GetMapMembers(*oldMap)),
|
||||||
|
count * sizeof(Member));
|
||||||
|
MapIterator *oldIt = GetMapIterators(*oldMap),
|
||||||
|
*newIt = GetMapIterators(*newMap);
|
||||||
|
while (count--) {
|
||||||
|
new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
|
||||||
|
}
|
||||||
|
Allocator::Free(oldMap);
|
||||||
|
}
|
||||||
|
return *newMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
|
||||||
|
return GetMapMembers(DoReallocMap(0, capacity, allocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
|
||||||
|
ObjectData& o = data_.o;
|
||||||
|
if (newCapacity > o.capacity) {
|
||||||
|
Member* oldMembers = GetMembersPointer();
|
||||||
|
Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
|
||||||
|
*&newMap = DoReallocMap(oldMap, newCapacity, allocator);
|
||||||
|
RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
|
||||||
|
o.capacity = newCapacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SourceAllocator>
|
||||||
|
MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||||
|
if (Member* members = GetMembersPointer()) {
|
||||||
|
Map* &map = GetMap(members);
|
||||||
|
MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
|
||||||
|
if (mit != map->end()) {
|
||||||
|
return MemberIterator(&members[mit->second]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MemberEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoClearMembers() {
|
||||||
|
if (Member* members = GetMembersPointer()) {
|
||||||
|
Map* &map = GetMap(members);
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
for (SizeType i = 0; i < data_.o.size; i++) {
|
||||||
|
map->erase(DropMapIterator(mit[i]));
|
||||||
|
members[i].~Member();
|
||||||
|
}
|
||||||
|
data_.o.size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoFreeMembers() {
|
||||||
|
if (Member* members = GetMembersPointer()) {
|
||||||
|
GetMap(members)->~Map();
|
||||||
|
for (SizeType i = 0; i < data_.o.size; i++) {
|
||||||
|
members[i].~Member();
|
||||||
|
}
|
||||||
|
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||||
|
Map** map = &GetMap(members);
|
||||||
|
Allocator::Free(*map);
|
||||||
|
Allocator::Free(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
|
||||||
|
RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
|
||||||
|
return Malloc<Member>(allocator, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
|
||||||
|
ObjectData& o = data_.o;
|
||||||
|
if (newCapacity > o.capacity) {
|
||||||
|
Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
|
||||||
|
RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
|
||||||
|
o.capacity = newCapacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SourceAllocator>
|
||||||
|
MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||||
|
MemberIterator member = MemberBegin();
|
||||||
|
for ( ; member != MemberEnd(); ++member)
|
||||||
|
if (name.StringEqual(member->name))
|
||||||
|
break;
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoClearMembers() {
|
||||||
|
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||||
|
m->~Member();
|
||||||
|
data_.o.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoFreeMembers() {
|
||||||
|
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||||
|
m->~Member();
|
||||||
|
Allocator::Free(GetMembersPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
|
||||||
|
void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
||||||
|
ObjectData& o = data_.o;
|
||||||
|
if (o.size >= o.capacity)
|
||||||
|
DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
|
||||||
|
Member* members = GetMembersPointer();
|
||||||
|
Member* m = members + o.size;
|
||||||
|
m->name.RawAssign(name);
|
||||||
|
m->value.RawAssign(value);
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
Map* &map = GetMap(members);
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
|
||||||
|
#endif
|
||||||
|
++o.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemberIterator DoRemoveMember(MemberIterator m) {
|
||||||
|
ObjectData& o = data_.o;
|
||||||
|
Member* members = GetMembersPointer();
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
Map* &map = GetMap(members);
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
SizeType mpos = static_cast<SizeType>(&*m - members);
|
||||||
|
map->erase(DropMapIterator(mit[mpos]));
|
||||||
|
#endif
|
||||||
|
MemberIterator last(members + (o.size - 1));
|
||||||
|
if (o.size > 1 && m != last) {
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
|
||||||
|
mit[mpos]->second = mpos;
|
||||||
|
#endif
|
||||||
|
*m = *last; // Move the last one to this place
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m->~Member(); // Only one left, just destroy
|
||||||
|
}
|
||||||
|
--o.size;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
|
||||||
|
ObjectData& o = data_.o;
|
||||||
|
MemberIterator beg = MemberBegin(),
|
||||||
|
pos = beg + (first - beg),
|
||||||
|
end = MemberEnd();
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
Map* &map = GetMap(GetMembersPointer());
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
#endif
|
||||||
|
for (MemberIterator itr = pos; itr != last; ++itr) {
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
map->erase(DropMapIterator(mit[itr - beg]));
|
||||||
|
#endif
|
||||||
|
itr->~Member();
|
||||||
|
}
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
if (first != last) {
|
||||||
|
// Move remaining members/iterators
|
||||||
|
MemberIterator next = pos + (last - first);
|
||||||
|
for (MemberIterator itr = pos; next != end; ++itr, ++next) {
|
||||||
|
std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
|
||||||
|
SizeType mpos = static_cast<SizeType>(itr - beg);
|
||||||
|
new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
|
||||||
|
mit[mpos]->second = mpos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::memmove(static_cast<void*>(&*pos), &*last,
|
||||||
|
static_cast<size_t>(end - last) * sizeof(Member));
|
||||||
|
#endif
|
||||||
|
o.size -= static_cast<SizeType>(last - first);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SourceAllocator>
|
||||||
|
void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
|
||||||
|
RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
|
||||||
|
|
||||||
|
data_.f.flags = kObjectFlag;
|
||||||
|
SizeType count = rhs.data_.o.size;
|
||||||
|
Member* lm = DoAllocMembers(count, allocator);
|
||||||
|
const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
Map* &map = GetMap(lm);
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
#endif
|
||||||
|
for (SizeType i = 0; i < count; i++) {
|
||||||
|
new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
|
||||||
|
new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
data_.o.size = data_.o.capacity = count;
|
||||||
|
SetMembersPointer(lm);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize this value as array with initial data, without calling destructor.
|
// Initialize this value as array with initial data, without calling destructor.
|
||||||
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
||||||
data_.f.flags = kArrayFlag;
|
data_.f.flags = kArrayFlag;
|
||||||
|
@ -2047,9 +2400,16 @@ private:
|
||||||
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
||||||
data_.f.flags = kObjectFlag;
|
data_.f.flags = kObjectFlag;
|
||||||
if (count) {
|
if (count) {
|
||||||
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
Member* m = DoAllocMembers(count, allocator);
|
||||||
SetMembersPointer(m);
|
SetMembersPointer(m);
|
||||||
std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
|
std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
|
||||||
|
#if RAPIDJSON_USE_MEMBERSMAP
|
||||||
|
Map* &map = GetMap(m);
|
||||||
|
MapIterator* mit = GetMapIterators(map);
|
||||||
|
for (SizeType i = 0; i < count; i++) {
|
||||||
|
new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetMembersPointer(0);
|
SetMembersPointer(0);
|
||||||
|
@ -2120,7 +2480,7 @@ typedef GenericValue<UTF8<> > Value;
|
||||||
\tparam StackAllocator Allocator for allocating memory for stack during parsing.
|
\tparam StackAllocator Allocator for allocating memory for stack during parsing.
|
||||||
\warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
|
\warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
|
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
|
||||||
class GenericDocument : public GenericValue<Encoding, Allocator> {
|
class GenericDocument : public GenericValue<Encoding, Allocator> {
|
||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||||
|
@ -2170,6 +2530,13 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
~GenericDocument() {
|
~GenericDocument() {
|
||||||
|
// Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
|
||||||
|
// runs last and may access its elements or members which would be freed
|
||||||
|
// with an allocator like MemoryPoolAllocator (CrtAllocator does not
|
||||||
|
// free its data when destroyed, but MemoryPoolAllocator does).
|
||||||
|
if (ownAllocator_) {
|
||||||
|
ValueType::SetNull();
|
||||||
|
}
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2505,6 +2872,7 @@ private:
|
||||||
//! GenericDocument with UTF8 encoding
|
//! GenericDocument with UTF8 encoding
|
||||||
typedef GenericDocument<UTF8<> > Document;
|
typedef GenericDocument<UTF8<> > Document;
|
||||||
|
|
||||||
|
|
||||||
//! Helper class for accessing Value of array type.
|
//! Helper class for accessing Value of array type.
|
||||||
/*!
|
/*!
|
||||||
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
||||||
|
@ -2529,6 +2897,7 @@ public:
|
||||||
GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
|
GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
|
||||||
~GenericArray() {}
|
~GenericArray() {}
|
||||||
|
|
||||||
|
operator ValueType&() const { return value_; }
|
||||||
SizeType Size() const { return value_.Size(); }
|
SizeType Size() const { return value_.Size(); }
|
||||||
SizeType Capacity() const { return value_.Capacity(); }
|
SizeType Capacity() const { return value_.Capacity(); }
|
||||||
bool Empty() const { return value_.Empty(); }
|
bool Empty() const { return value_.Empty(); }
|
||||||
|
@ -2584,6 +2953,7 @@ public:
|
||||||
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
||||||
~GenericObject() {}
|
~GenericObject() {}
|
||||||
|
|
||||||
|
operator ValueType&() const { return value_; }
|
||||||
SizeType MemberCount() const { return value_.MemberCount(); }
|
SizeType MemberCount() const { return value_.MemberCount(); }
|
||||||
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
||||||
bool ObjectEmpty() const { return value_.ObjectEmpty(); }
|
bool ObjectEmpty() const { return value_.ObjectEmpty(); }
|
||||||
|
@ -2649,4 +3019,9 @@ private:
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
|
|
||||||
|
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||||
|
#pragma pop_macro("GetObject")
|
||||||
|
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // RAPIDJSON_DOCUMENT_H_
|
#endif // RAPIDJSON_DOCUMENT_H_
|
||||||
|
|
2
src/3rdparty/rapidjson/encodedstream.h
vendored
2
src/3rdparty/rapidjson/encodedstream.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/encodings.h
vendored
2
src/3rdparty/rapidjson/encodings.h
vendored
|
@ -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
|
||||||
|
|
50
src/3rdparty/rapidjson/error/en.h
vendored
50
src/3rdparty/rapidjson/error/en.h
vendored
|
@ -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__
|
||||||
|
|
57
src/3rdparty/rapidjson/error/error.h
vendored
57
src/3rdparty/rapidjson/error/error.h
vendored
|
@ -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
|
||||||
|
@ -152,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__
|
||||||
|
|
2
src/3rdparty/rapidjson/filereadstream.h
vendored
2
src/3rdparty/rapidjson/filereadstream.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/filewritestream.h
vendored
2
src/3rdparty/rapidjson/filewritestream.h
vendored
|
@ -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
|
||||||
|
|
4
src/3rdparty/rapidjson/fwd.h
vendored
4
src/3rdparty/rapidjson/fwd.h
vendored
|
@ -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;
|
||||||
|
|
19
src/3rdparty/rapidjson/internal/biginteger.h
vendored
19
src/3rdparty/rapidjson/internal/biginteger.h
vendored
|
@ -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"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !__INTEL_COMPILER && defined(_M_AMD64)
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
||||||
#include <intrin.h> // for _umul128
|
#include <intrin.h> // for _umul128
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,7 +37,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;
|
||||||
|
@ -221,7 +222,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 +238,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) {
|
for (const Ch* p = begin; p != end; ++p) {
|
||||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9'));
|
||||||
r = r * 10u + static_cast<unsigned>(*p - '0');
|
r = r * 10u + static_cast<unsigned>(*p - Ch('0'));
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
71
src/3rdparty/rapidjson/internal/clzll.h
vendored
Normal file
71
src/3rdparty/rapidjson/internal/clzll.h
vendored
Normal file
|
@ -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_
|
20
src/3rdparty/rapidjson/internal/diyfp.h
vendored
20
src/3rdparty/rapidjson/internal/diyfp.h
vendored
|
@ -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,11 +20,11 @@
|
||||||
#define RAPIDJSON_DIYFP_H_
|
#define RAPIDJSON_DIYFP_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
#include "clzll.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#pragma intrinsic(_BitScanReverse64)
|
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -100,22 +100,8 @@ struct DiyFp {
|
||||||
}
|
}
|
||||||
|
|
||||||
DiyFp Normalize() const {
|
DiyFp Normalize() const {
|
||||||
RAPIDJSON_ASSERT(f != 0); // https://stackoverflow.com/a/26809183/291737
|
int s = static_cast<int>(clzll(f));
|
||||||
#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);
|
|
||||||
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 {
|
||||||
|
|
12
src/3rdparty/rapidjson/internal/dtoa.h
vendored
12
src/3rdparty/rapidjson/internal/dtoa.h
vendored
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/ieee754.h
vendored
2
src/3rdparty/rapidjson/internal/ieee754.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/itoa.h
vendored
2
src/3rdparty/rapidjson/internal/itoa.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/meta.h
vendored
2
src/3rdparty/rapidjson/internal/meta.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/pow10.h
vendored
2
src/3rdparty/rapidjson/internal/pow10.h
vendored
|
@ -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
|
||||||
|
|
9
src/3rdparty/rapidjson/internal/regex.h
vendored
9
src/3rdparty/rapidjson/internal/regex.h
vendored
|
@ -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,7 +23,6 @@
|
||||||
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)
|
#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
|
||||||
|
@ -32,9 +31,6 @@ RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||||
|
@ -291,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);
|
||||||
|
@ -520,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) {
|
||||||
|
@ -529,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:
|
||||||
{
|
{
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/stack.h
vendored
2
src/3rdparty/rapidjson/internal/stack.h
vendored
|
@ -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
src/3rdparty/rapidjson/internal/strfunc.h
vendored
16
src/3rdparty/rapidjson/internal/strfunc.h
vendored
|
@ -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) {
|
||||||
|
|
17
src/3rdparty/rapidjson/internal/strtod.h
vendored
17
src/3rdparty/rapidjson/internal/strtod.h
vendored
|
@ -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
|
||||||
|
@ -128,17 +128,18 @@ 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, int dLen, int dExp, 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;
|
||||||
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
||||||
for (; i < dLen; i++) {
|
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 < dLen && decimals[i] >= '5') // Rounding
|
if (i < dLen && decimals[i] >= Ch('5')) // Rounding
|
||||||
significand++;
|
significand++;
|
||||||
|
|
||||||
int remaining = dLen - i;
|
int remaining = dLen - i;
|
||||||
|
@ -205,7 +206,8 @@ inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result
|
||||||
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, int dLen, int dExp) {
|
template<typename Ch>
|
||||||
|
inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) {
|
||||||
RAPIDJSON_ASSERT(dLen >= 0);
|
RAPIDJSON_ASSERT(dLen >= 0);
|
||||||
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
||||||
Double a(approx);
|
Double a(approx);
|
||||||
|
@ -223,7 +225,8 @@ inline double StrtodBigInteger(double approx, const char* decimals, int dLen, in
|
||||||
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);
|
||||||
|
|
||||||
|
|
2
src/3rdparty/rapidjson/internal/swap.h
vendored
2
src/3rdparty/rapidjson/internal/swap.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/istreamwrapper.h
vendored
2
src/3rdparty/rapidjson/istreamwrapper.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/memorybuffer.h
vendored
2
src/3rdparty/rapidjson/memorybuffer.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/memorystream.h
vendored
2
src/3rdparty/rapidjson/memorystream.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/ostreamwrapper.h
vendored
2
src/3rdparty/rapidjson/ostreamwrapper.h
vendored
|
@ -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
|
||||||
|
|
80
src/3rdparty/rapidjson/pointer.h
vendored
80
src/3rdparty/rapidjson/pointer.h
vendored
|
@ -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_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__
|
||||||
|
@ -80,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.
|
||||||
/*!
|
/*!
|
||||||
|
@ -163,7 +166,7 @@ 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_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||||
*this = rhs;
|
*this = rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,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
|
||||||
|
@ -519,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
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
@ -543,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;
|
||||||
|
@ -779,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;
|
||||||
|
|
6
src/3rdparty/rapidjson/prettywriter.h
vendored
6
src/3rdparty/rapidjson/prettywriter.h
vendored
|
@ -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
|
||||||
|
@ -60,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) :
|
||||||
|
@ -164,7 +164,7 @@ public:
|
||||||
(void)memberCount;
|
(void)memberCount;
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||||
typename Base::Level* level = Base::level_stack_.template Pop<typename Base::Level>(1);
|
auto level = Base::level_stack_.template Pop<typename Base::Level>(1);
|
||||||
bool empty = level->valueCount == 0;
|
bool empty = level->valueCount == 0;
|
||||||
|
|
||||||
if (!empty && !level->inLine) {
|
if (!empty && !level->inLine) {
|
||||||
|
|
107
src/3rdparty/rapidjson/rapidjson.h
vendored
107
src/3rdparty/rapidjson/rapidjson.h
vendored
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -403,7 +434,7 @@ RAPIDJSON_NAMESPACE_END
|
||||||
*/
|
*/
|
||||||
#ifndef RAPIDJSON_ASSERT
|
#ifndef RAPIDJSON_ASSERT
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#define RAPIDJSON_ASSERT(x)
|
#define RAPIDJSON_ASSERT(x) assert(x)
|
||||||
#endif // RAPIDJSON_ASSERT
|
#endif // RAPIDJSON_ASSERT
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -411,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
|
||||||
|
@ -490,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
|
||||||
|
|
||||||
|
@ -535,8 +572,14 @@ 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(_MSC_VER) || 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
|
||||||
|
@ -553,8 +596,14 @@ 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__)) || \
|
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
||||||
|
@ -564,11 +613,13 @@ RAPIDJSON_NAMESPACE_END
|
||||||
#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
|
||||||
|
@ -591,6 +642,27 @@ RAPIDJSON_NAMESPACE_END
|
||||||
#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).
|
//! Assertion (in non-throwing contexts).
|
||||||
|
@ -609,16 +681,29 @@ RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
#ifdef RAPIDJSON_ASSERT_THROWS
|
#ifdef RAPIDJSON_ASSERT_THROWS
|
||||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
#include <cassert>
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
|
||||||
#else
|
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||||
#endif // RAPIDJSON_ASSERT_THROWS
|
#endif // RAPIDJSON_ASSERT_THROWS
|
||||||
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
#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
|
||||||
|
|
||||||
|
|
114
src/3rdparty/rapidjson/reader.h
vendored
114
src/3rdparty/rapidjson/reader.h
vendored
|
@ -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"
|
||||||
|
@ -153,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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -443,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -990,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,
|
||||||
|
@ -1013,19 +1015,31 @@ private:
|
||||||
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)) {
|
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
|
||||||
// Handle UTF-16 surrogate pair
|
// high surrogate, check if followed by valid low surrogate
|
||||||
if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
|
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);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
TEncoding::Encode(os, codepoint);
|
TEncoding::Encode(os, codepoint);
|
||||||
}
|
}
|
||||||
|
@ -1244,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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;
|
||||||
}
|
}
|
||||||
|
@ -1314,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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;
|
||||||
}
|
}
|
||||||
|
@ -1370,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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;
|
||||||
}
|
}
|
||||||
|
@ -1390,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>
|
template<typename InputStream, typename StackCharacter>
|
||||||
class NumberStream<InputStream, false, false> {
|
class NumberStream<InputStream, StackCharacter, false, false> {
|
||||||
public:
|
public:
|
||||||
typedef typename InputStream::Ch Ch;
|
typedef typename InputStream::Ch Ch;
|
||||||
|
|
||||||
|
@ -1403,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&);
|
||||||
|
@ -1415,35 +1429,35 @@ private:
|
||||||
InputStream& is;
|
InputStream& is;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename InputStream>
|
template<typename InputStream, typename StackCharacter>
|
||||||
class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
|
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
||||||
typedef NumberStream<InputStream, false, false> Base;
|
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), 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>
|
template<typename InputStream, typename StackCharacter>
|
||||||
class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
|
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
||||||
typedef NumberStream<InputStream, true, false> Base;
|
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
||||||
|
|
||||||
|
@ -1452,8 +1466,10 @@ private:
|
||||||
|
|
||||||
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),
|
||||||
|
@ -1678,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();
|
||||||
|
@ -1691,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;
|
||||||
|
|
210
src/3rdparty/rapidjson/readme.md
vendored
Normal file
210
src/3rdparty/rapidjson/readme.md
vendored
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## A fast JSON parser/generator for C++ with both SAX/DOM style API
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
* [RapidJSON GitHub](https://github.com/Tencent/rapidjson/)
|
||||||
|
* RapidJSON Documentation
|
||||||
|
* [English](http://rapidjson.org/)
|
||||||
|
* [简体中文](http://rapidjson.org/zh-cn/)
|
||||||
|
* [GitBook](https://www.gitbook.com/book/miloyip/rapidjson/) with downloadable PDF/EPUB/MOBI, without API reference.
|
||||||
|
|
||||||
|
## Build status
|
||||||
|
|
||||||
|
| [Linux][lin-link] | [Windows][win-link] | [Coveralls][cov-link] |
|
||||||
|
| :---------------: | :-----------------: | :-------------------: |
|
||||||
|
| ![lin-badge] | ![win-badge] | ![cov-badge] |
|
||||||
|
|
||||||
|
[lin-badge]: https://travis-ci.org/Tencent/rapidjson.svg?branch=master "Travis build status"
|
||||||
|
[lin-link]: https://travis-ci.org/Tencent/rapidjson "Travis build status"
|
||||||
|
[win-badge]: https://ci.appveyor.com/api/projects/status/l6qulgqahcayidrf/branch/master?svg=true "AppVeyor build status"
|
||||||
|
[win-link]: https://ci.appveyor.com/project/miloyip/rapidjson-0fdqj/branch/master "AppVeyor build status"
|
||||||
|
[cov-badge]: https://coveralls.io/repos/Tencent/rapidjson/badge.svg?branch=master "Coveralls coverage"
|
||||||
|
[cov-link]: https://coveralls.io/r/Tencent/rapidjson?branch=master "Coveralls coverage"
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](http://rapidxml.sourceforge.net/).
|
||||||
|
|
||||||
|
* RapidJSON is **small** but **complete**. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
|
||||||
|
|
||||||
|
* RapidJSON is **fast**. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
|
||||||
|
|
||||||
|
* RapidJSON is **self-contained** and **header-only**. It does not depend on external libraries such as BOOST. It even does not depend on STL.
|
||||||
|
|
||||||
|
* RapidJSON is **memory-friendly**. Each JSON value occupies exactly 16 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||||
|
|
||||||
|
* RapidJSON is **Unicode-friendly**. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||||
|
|
||||||
|
More features can be read [here](doc/features.md).
|
||||||
|
|
||||||
|
JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in full compliance with RFC7159/ECMA-404, with optional support of relaxed syntax. More information about JSON can be obtained at
|
||||||
|
* [Introducing JSON](http://json.org/)
|
||||||
|
* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)
|
||||||
|
* [Standard ECMA-404: The JSON Data Interchange Format](https://www.ecma-international.org/publications/standards/Ecma-404.htm)
|
||||||
|
|
||||||
|
## Highlights in v1.1 (2016-8-25)
|
||||||
|
|
||||||
|
* Added [JSON Pointer](doc/pointer.md)
|
||||||
|
* Added [JSON Schema](doc/schema.md)
|
||||||
|
* Added [relaxed JSON syntax](doc/dom.md) (comment, trailing comma, NaN/Infinity)
|
||||||
|
* Iterating array/object with [C++11 Range-based for loop](doc/tutorial.md)
|
||||||
|
* Reduce memory overhead of each `Value` from 24 bytes to 16 bytes in x86-64 architecture.
|
||||||
|
|
||||||
|
For other changes please refer to [change log](CHANGELOG.md).
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
RapidJSON is cross-platform. Some platform/compiler combinations which have been tested are shown as follows.
|
||||||
|
* Visual C++ 2008/2010/2013 on Windows (32/64-bit)
|
||||||
|
* GNU C++ 3.8.x on Cygwin
|
||||||
|
* Clang 3.4 on Mac OS X (32/64-bit) and iOS
|
||||||
|
* Clang 3.4 on Android NDK
|
||||||
|
|
||||||
|
Users can build and run the unit tests on their platform/compiler.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path.
|
||||||
|
|
||||||
|
Alternatively, if you are using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager you can download and install rapidjson with CMake integration in a single command:
|
||||||
|
* vcpkg install rapidjson
|
||||||
|
|
||||||
|
RapidJSON uses following software as its dependencies:
|
||||||
|
* [CMake](https://cmake.org/) as a general build tool
|
||||||
|
* (optional) [Doxygen](http://www.doxygen.org) to build documentation
|
||||||
|
* (optional) [googletest](https://github.com/google/googletest) for unit and performance testing
|
||||||
|
|
||||||
|
To generate user documentation and run tests please proceed with the steps below:
|
||||||
|
|
||||||
|
1. Execute `git submodule update --init` to get the files of thirdparty submodules (google test).
|
||||||
|
2. Create directory called `build` in rapidjson source directory.
|
||||||
|
3. Change to `build` directory and run `cmake ..` command to configure your build. Windows users can do the same with cmake-gui application.
|
||||||
|
4. On Windows, build the solution found in the build directory. On Linux, run `make` from the build directory.
|
||||||
|
|
||||||
|
On successful build you will find compiled test and example binaries in `bin`
|
||||||
|
directory. The generated documentation will be available in `doc/html`
|
||||||
|
directory of the build tree. To run tests after finished build please run `make
|
||||||
|
test` or `ctest` from your build tree. You can get detailed output using `ctest
|
||||||
|
-V` command.
|
||||||
|
|
||||||
|
It is possible to install library system-wide by running `make install` command
|
||||||
|
from the build tree with administrative privileges. This will install all files
|
||||||
|
according to system preferences. Once RapidJSON is installed, it is possible
|
||||||
|
to use it from other CMake projects by adding `find_package(RapidJSON)` line to
|
||||||
|
your CMakeLists.txt.
|
||||||
|
|
||||||
|
## Usage at a glance
|
||||||
|
|
||||||
|
This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string.
|
||||||
|
|
||||||
|
~~~~~~~~~~cpp
|
||||||
|
// rapidjson/example/simpledom/simpledom.cpp`
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
#include "rapidjson/writer.h"
|
||||||
|
#include "rapidjson/stringbuffer.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// 1. Parse a JSON string into DOM.
|
||||||
|
const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
|
||||||
|
Document d;
|
||||||
|
d.Parse(json);
|
||||||
|
|
||||||
|
// 2. Modify it by DOM.
|
||||||
|
Value& s = d["stars"];
|
||||||
|
s.SetInt(s.GetInt() + 1);
|
||||||
|
|
||||||
|
// 3. Stringify the DOM
|
||||||
|
StringBuffer buffer;
|
||||||
|
Writer<StringBuffer> writer(buffer);
|
||||||
|
d.Accept(writer);
|
||||||
|
|
||||||
|
// Output {"project":"rapidjson","stars":11}
|
||||||
|
std::cout << buffer.GetString() << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
Note that this example did not handle potential errors.
|
||||||
|
|
||||||
|
The following diagram shows the process.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
More [examples](https://github.com/Tencent/rapidjson/tree/master/example) are available:
|
||||||
|
|
||||||
|
* DOM API
|
||||||
|
* [tutorial](https://github.com/Tencent/rapidjson/blob/master/example/tutorial/tutorial.cpp): Basic usage of DOM API.
|
||||||
|
|
||||||
|
* SAX API
|
||||||
|
* [simplereader](https://github.com/Tencent/rapidjson/blob/master/example/simplereader/simplereader.cpp): Dumps all SAX events while parsing a JSON by `Reader`.
|
||||||
|
* [condense](https://github.com/Tencent/rapidjson/blob/master/example/condense/condense.cpp): A command line tool to rewrite a JSON, with all whitespaces removed.
|
||||||
|
* [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp): A command line tool to rewrite a JSON with indents and newlines by `PrettyWriter`.
|
||||||
|
* [capitalize](https://github.com/Tencent/rapidjson/blob/master/example/capitalize/capitalize.cpp): A command line tool to capitalize strings in JSON.
|
||||||
|
* [messagereader](https://github.com/Tencent/rapidjson/blob/master/example/messagereader/messagereader.cpp): Parse a JSON message with SAX API.
|
||||||
|
* [serialize](https://github.com/Tencent/rapidjson/blob/master/example/serialize/serialize.cpp): Serialize a C++ object into JSON with SAX API.
|
||||||
|
* [jsonx](https://github.com/Tencent/rapidjson/blob/master/example/jsonx/jsonx.cpp): Implements a `JsonxWriter` which stringify SAX events into [JSONx](https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html) (a kind of XML) format. The example is a command line tool which converts input JSON into JSONx format.
|
||||||
|
|
||||||
|
* Schema
|
||||||
|
* [schemavalidator](https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp) : A command line tool to validate a JSON with a JSON schema.
|
||||||
|
|
||||||
|
* Advanced
|
||||||
|
* [prettyauto](https://github.com/Tencent/rapidjson/blob/master/example/prettyauto/prettyauto.cpp): A modified version of [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp) to automatically handle JSON with any UTF encodings.
|
||||||
|
* [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
|
||||||
|
* [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
|
||||||
|
* [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
RapidJSON welcomes contributions. When contributing, please follow the code below.
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
Feel free to submit issues and enhancement requests.
|
||||||
|
|
||||||
|
Please help us by providing **minimal reproducible examples**, because source code is easier to let other people understand what happens.
|
||||||
|
For crash problems on certain platforms, please bring stack dump content with the detail of the OS, compiler, etc.
|
||||||
|
|
||||||
|
Please try breakpoint debugging first, tell us what you found, see if we can start exploring based on more information been prepared.
|
||||||
|
|
||||||
|
### Workflow
|
||||||
|
|
||||||
|
In general, we follow the "fork-and-pull" Git workflow.
|
||||||
|
|
||||||
|
1. **Fork** the repo on GitHub
|
||||||
|
2. **Clone** the project to your own machine
|
||||||
|
3. **Checkout** a new branch on your fork, start developing on the branch
|
||||||
|
4. **Test** the change before commit, Make sure the changes pass all the tests, including `unittest` and `preftest`, please add test case for each new feature or bug-fix if needed.
|
||||||
|
5. **Commit** changes to your own branch
|
||||||
|
6. **Push** your work back up to your fork
|
||||||
|
7. Submit a **Pull request** so that we can review your changes
|
||||||
|
|
||||||
|
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
|
||||||
|
|
||||||
|
### Copyright and Licensing
|
||||||
|
|
||||||
|
You can copy and paste the license summary from below.
|
||||||
|
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
```
|
822
src/3rdparty/rapidjson/schema.h
vendored
822
src/3rdparty/rapidjson/schema.h
vendored
File diff suppressed because it is too large
Load diff
2
src/3rdparty/rapidjson/stream.h
vendored
2
src/3rdparty/rapidjson/stream.h
vendored
|
@ -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
|
||||||
|
|
2
src/3rdparty/rapidjson/stringbuffer.h
vendored
2
src/3rdparty/rapidjson/stringbuffer.h
vendored
|
@ -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
|
||||||
|
|
466
src/3rdparty/rapidjson/uri.h
vendored
Normal file
466
src/3rdparty/rapidjson/uri.h
vendored
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
// 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
|
||||||
|
size_t total = (3 * len + 7) * sizeof(Ch);
|
||||||
|
scheme_ = static_cast<Ch*>(allocator_->Malloc(total));
|
||||||
|
*scheme_ = '\0';
|
||||||
|
auth_ = scheme_ + 1;
|
||||||
|
*auth_ = '\0';
|
||||||
|
path_ = auth_ + 1;
|
||||||
|
*path_ = '\0';
|
||||||
|
query_ = path_ + 1;
|
||||||
|
*query_ = '\0';
|
||||||
|
frag_ = query_ + 1;
|
||||||
|
*frag_ = '\0';
|
||||||
|
base_ = frag_ + 1;
|
||||||
|
*base_ = '\0';
|
||||||
|
uri_ = base_ + 1;
|
||||||
|
*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 (//([^/?#]*))?
|
||||||
|
auth_ = scheme_ + GetSchemeStringLength() + 1;
|
||||||
|
*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 ([^?#]*)
|
||||||
|
path_ = auth_ + GetAuthStringLength() + 1;
|
||||||
|
*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 (\?([^#]*))?
|
||||||
|
query_ = path_ + GetPathStringLength() + 1;
|
||||||
|
*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 (#(.*))?
|
||||||
|
frag_ = query_ + GetQueryStringLength() + 1;
|
||||||
|
*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_
|
17
src/3rdparty/rapidjson/writer.h
vendored
17
src/3rdparty/rapidjson/writer.h
vendored
|
@ -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"
|
||||||
|
@ -226,7 +227,7 @@ public:
|
||||||
return Key(str.data(), SizeType(str.size()));
|
return Key(str.data(), SizeType(str.size()));
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
@ -282,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 {
|
||||||
|
@ -291,8 +294,6 @@ protected:
|
||||||
bool inLine = false;
|
bool inLine = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
|
@ -669,19 +670,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 low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,6 @@ const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const rapidjson::Value &xmrig::JsonChain::object() const
|
const rapidjson::Value &xmrig::JsonChain::object() const
|
||||||
{
|
{
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/json/JsonRequest.h"
|
#include "base/io/json/JsonRequest.h"
|
||||||
#include "3rdparty/rapidjson/document.h"
|
#include "3rdparty/rapidjson/document.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "base/tools/String.h"
|
#include "base/tools/String.h"
|
||||||
#include "3rdparty/rapidjson/document.h"
|
#include "3rdparty/rapidjson/document.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
Loading…
Reference in a new issue