mirror of
https://github.com/xmrig/xmrig.git
synced 2025-02-02 03:06:30 +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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -16,6 +16,13 @@
|
|||
#define RAPIDJSON_ALLOCATORS_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/meta.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -77,19 +84,26 @@ public:
|
|||
static const bool kNeedFree = true;
|
||||
void* Malloc(size_t size) {
|
||||
if (size) // behavior of malloc(0) is implementation defined.
|
||||
return std::malloc(size);
|
||||
return RAPIDJSON_MALLOC(size);
|
||||
else
|
||||
return NULL; // standardize to returning NULL.
|
||||
}
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
||||
(void)originalSize;
|
||||
if (newSize == 0) {
|
||||
std::free(originalPtr);
|
||||
RAPIDJSON_FREE(originalPtr);
|
||||
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>
|
||||
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:
|
||||
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.
|
||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||
\param baseAllocator The allocator for allocating memory chunks.
|
||||
*/
|
||||
explicit
|
||||
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.
|
||||
|
@ -136,41 +198,101 @@ public:
|
|||
\param baseAllocator The allocator for allocating memory chunks.
|
||||
*/
|
||||
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||
chunk_capacity_(chunkSize),
|
||||
baseAllocator_(baseAllocator),
|
||||
shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
|
||||
{
|
||||
RAPIDJSON_ASSERT(buffer != 0);
|
||||
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
||||
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
||||
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
||||
chunkHead_->size = 0;
|
||||
chunkHead_->next = 0;
|
||||
RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
|
||||
shared_->chunkHead = GetChunkHead(shared_);
|
||||
shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
|
||||
shared_->chunkHead->size = 0;
|
||||
shared_->chunkHead->next = 0;
|
||||
shared_->ownBaseAllocator = 0;
|
||||
shared_->ownBuffer = false;
|
||||
shared_->refcount = 1;
|
||||
}
|
||||
|
||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
chunk_capacity_(rhs.chunk_capacity_),
|
||||
baseAllocator_(rhs.baseAllocator_),
|
||||
shared_(rhs.shared_)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
++shared_->refcount;
|
||||
}
|
||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
++rhs.shared_->refcount;
|
||||
this->~MemoryPoolAllocator();
|
||||
baseAllocator_ = rhs.baseAllocator_;
|
||||
chunk_capacity_ = rhs.chunk_capacity_;
|
||||
shared_ = rhs.shared_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||
chunk_capacity_(rhs.chunk_capacity_),
|
||||
baseAllocator_(rhs.baseAllocator_),
|
||||
shared_(rhs.shared_)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
rhs.shared_ = 0;
|
||||
}
|
||||
MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
this->~MemoryPoolAllocator();
|
||||
baseAllocator_ = rhs.baseAllocator_;
|
||||
chunk_capacity_ = rhs.chunk_capacity_;
|
||||
shared_ = rhs.shared_;
|
||||
rhs.shared_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Destructor.
|
||||
/*! 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();
|
||||
RAPIDJSON_DELETE(ownBaseAllocator_);
|
||||
BaseAllocator *a = shared_->ownBaseAllocator;
|
||||
if (shared_->ownBuffer) {
|
||||
baseAllocator_->Free(shared_);
|
||||
}
|
||||
RAPIDJSON_DELETE(a);
|
||||
}
|
||||
|
||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
void Clear() {
|
||||
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
||||
ChunkHeader* next = chunkHead_->next;
|
||||
baseAllocator_->Free(chunkHead_);
|
||||
chunkHead_ = next;
|
||||
//! Deallocates all memory chunks, excluding the first/user one.
|
||||
void Clear() RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
for (;;) {
|
||||
ChunkHeader* c = shared_->chunkHead;
|
||||
if (!c->next) {
|
||||
break;
|
||||
}
|
||||
shared_->chunkHead = c->next;
|
||||
baseAllocator_->Free(c);
|
||||
}
|
||||
if (chunkHead_ && chunkHead_ == userBuffer_)
|
||||
chunkHead_->size = 0; // Clear user buffer
|
||||
shared_->chunkHead->size = 0;
|
||||
}
|
||||
|
||||
//! Computes the total capacity of allocated memory chunks.
|
||||
/*! \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;
|
||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||
for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
|
||||
capacity += c->capacity;
|
||||
return capacity;
|
||||
}
|
||||
|
@ -178,25 +300,35 @@ public:
|
|||
//! Computes the memory blocks allocated.
|
||||
/*! \return total used bytes.
|
||||
*/
|
||||
size_t Size() const {
|
||||
size_t Size() const RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 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;
|
||||
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)
|
||||
void* Malloc(size_t size) {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
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))
|
||||
return NULL;
|
||||
|
||||
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
|
||||
chunkHead_->size += size;
|
||||
void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
|
||||
shared_->chunkHead->size += size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -205,6 +337,7 @@ public:
|
|||
if (originalPtr == 0)
|
||||
return Malloc(newSize);
|
||||
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
if (newSize == 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -216,10 +349,10 @@ public:
|
|||
return originalPtr;
|
||||
|
||||
// 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);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
chunkHead_->size += increment;
|
||||
if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
|
||||
shared_->chunkHead->size += increment;
|
||||
return originalPtr;
|
||||
}
|
||||
}
|
||||
|
@ -235,50 +368,325 @@ public:
|
|||
}
|
||||
|
||||
//! 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:
|
||||
//! 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.
|
||||
/*! \param capacity Capacity of the chunk in bytes.
|
||||
\return true if success.
|
||||
*/
|
||||
bool AddChunk(size_t capacity) {
|
||||
if (!baseAllocator_)
|
||||
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
|
||||
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
|
||||
shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
|
||||
if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
|
||||
chunk->capacity = capacity;
|
||||
chunk->size = 0;
|
||||
chunk->next = chunkHead_;
|
||||
chunkHead_ = chunk;
|
||||
chunk->next = shared_->chunkHead;
|
||||
shared_->chunkHead = chunk;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
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.
|
||||
/*! 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.
|
||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||
SharedData *shared_; //!< The shared data of the allocator
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
template<typename, typename = void>
|
||||
struct IsRefCounted :
|
||||
public FalseType
|
||||
{ };
|
||||
template<typename T>
|
||||
struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> :
|
||||
public TrueType
|
||||
{ };
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
|
||||
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline T *Malloc(A& a, size_t n = 1)
|
||||
{
|
||||
return Realloc<T, A>(a, NULL, 0, n);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline void Free(A& a, T *p, size_t n = 1)
|
||||
{
|
||||
static_cast<void>(Realloc<T, A>(a, p, n, 0));
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
|
||||
#endif
|
||||
|
||||
template <typename T, typename BaseAllocator = CrtAllocator>
|
||||
class StdAllocator :
|
||||
public std::allocator<T>
|
||||
{
|
||||
typedef std::allocator<T> allocator_type;
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
typedef std::allocator_traits<allocator_type> traits_type;
|
||||
#else
|
||||
typedef allocator_type traits_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef BaseAllocator BaseAllocatorType;
|
||||
|
||||
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_()
|
||||
{ }
|
||||
|
||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(std::move(rhs)),
|
||||
baseAllocator_(std::move(rhs.baseAllocator_))
|
||||
{ }
|
||||
#endif
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
using propagate_on_container_swap = std::true_type;
|
||||
#endif
|
||||
|
||||
/* implicit */
|
||||
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_(allocator)
|
||||
{ }
|
||||
|
||||
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef StdAllocator<U, BaseAllocator> other;
|
||||
};
|
||||
|
||||
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||
void *userBuffer_; //!< User supplied buffer.
|
||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
||||
typedef typename traits_type::size_type size_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::pointer pointer;
|
||||
typedef typename traits_type::const_pointer const_pointer;
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
|
||||
typedef typename std::add_lvalue_reference<value_type>::type &reference;
|
||||
typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
|
||||
|
||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return std::addressof(r);
|
||||
}
|
||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return std::addressof(r);
|
||||
}
|
||||
|
||||
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return traits_type::max_size(*this);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
void construct(pointer p, Args&&... args)
|
||||
{
|
||||
traits_type::construct(*this, p, std::forward<Args>(args)...);
|
||||
}
|
||||
void destroy(pointer p)
|
||||
{
|
||||
traits_type::destroy(*this, p);
|
||||
}
|
||||
|
||||
#else // !RAPIDJSON_HAS_CXX11
|
||||
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
|
||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::address(r);
|
||||
}
|
||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::address(r);
|
||||
}
|
||||
|
||||
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::max_size();
|
||||
}
|
||||
|
||||
void construct(pointer p, const_reference r)
|
||||
{
|
||||
allocator_type::construct(p, r);
|
||||
}
|
||||
void destroy(pointer p)
|
||||
{
|
||||
allocator_type::destroy(p);
|
||||
}
|
||||
|
||||
#endif // !RAPIDJSON_HAS_CXX11
|
||||
|
||||
template <typename U>
|
||||
U* allocate(size_type n = 1, const void* = 0)
|
||||
{
|
||||
return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
|
||||
}
|
||||
template <typename U>
|
||||
void deallocate(U* p, size_type n = 1)
|
||||
{
|
||||
RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n = 1, const void* = 0)
|
||||
{
|
||||
return allocate<value_type>(n);
|
||||
}
|
||||
void deallocate(pointer p, size_type n = 1)
|
||||
{
|
||||
deallocate<value_type>(p, n);
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
using is_always_equal = std::is_empty<BaseAllocator>;
|
||||
#endif
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return baseAllocator_ == rhs.baseAllocator_;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
//! rapidjson Allocator concept
|
||||
static const bool kNeedFree = BaseAllocator::kNeedFree;
|
||||
static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
|
||||
void* Malloc(size_t size)
|
||||
{
|
||||
return baseAllocator_.Malloc(size);
|
||||
}
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
|
||||
{
|
||||
return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
|
||||
}
|
||||
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
BaseAllocator::Free(ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename, typename>
|
||||
friend class StdAllocator; // access to StdAllocator<!T>.*
|
||||
|
||||
BaseAllocator baseAllocator_;
|
||||
};
|
||||
|
||||
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
|
||||
template <typename BaseAllocator>
|
||||
class StdAllocator<void, BaseAllocator> :
|
||||
public std::allocator<void>
|
||||
{
|
||||
typedef std::allocator<void> allocator_type;
|
||||
|
||||
public:
|
||||
typedef BaseAllocator BaseAllocatorType;
|
||||
|
||||
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_()
|
||||
{ }
|
||||
|
||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
/* implicit */
|
||||
StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_(baseAllocator)
|
||||
{ }
|
||||
|
||||
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef StdAllocator<U, BaseAllocator> other;
|
||||
};
|
||||
|
||||
typedef typename allocator_type::value_type value_type;
|
||||
|
||||
private:
|
||||
template <typename, typename>
|
||||
friend class StdAllocator; // access to StdAllocator<!T>.*
|
||||
|
||||
BaseAllocator baseAllocator_;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -24,6 +24,9 @@
|
|||
#include "encodedstream.h"
|
||||
#include <new> // placement new
|
||||
#include <limits>
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
#ifdef __clang__
|
||||
|
@ -39,12 +42,21 @@ RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible lo
|
|||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#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
|
||||
#include <iterator> // std::random_access_iterator_tag
|
||||
#endif
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
#include <utility> // std::move
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
#include <map> // std::multimap
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -56,6 +68,48 @@ class GenericValue;
|
|||
template <typename Encoding, typename Allocator, typename StackAllocator>
|
||||
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.
|
||||
/*!
|
||||
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
|
||||
*/
|
||||
template <typename Encoding, typename Allocator>
|
||||
struct GenericMember {
|
||||
class GenericMember {
|
||||
public:
|
||||
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
||||
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.
|
||||
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
||||
a.name.Swap(b.name);
|
||||
a.value.Swap(b.value);
|
||||
}
|
||||
|
||||
private:
|
||||
//! Copy constructor is not permitted.
|
||||
GenericMember(const GenericMember& rhs);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -175,12 +259,16 @@ public:
|
|||
|
||||
//! @name relations
|
||||
//@{
|
||||
bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
|
||||
bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
|
||||
bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
|
||||
bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
|
||||
bool operator< (ConstIterator 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_; }
|
||||
template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
|
||||
template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
|
||||
template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
|
||||
template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& 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
|
||||
|
@ -210,12 +298,14 @@ class GenericMemberIterator;
|
|||
//! non-const GenericMemberIterator
|
||||
template <typename Encoding, typename Allocator>
|
||||
class GenericMemberIterator<false,Encoding,Allocator> {
|
||||
public:
|
||||
//! use plain pointer as iterator type
|
||||
typedef GenericMember<Encoding,Allocator>* Iterator;
|
||||
};
|
||||
//! const GenericMemberIterator
|
||||
template <typename Encoding, typename Allocator>
|
||||
class GenericMemberIterator<true,Encoding,Allocator> {
|
||||
public:
|
||||
//! use plain const pointer as iterator type
|
||||
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 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 {
|
||||
public:
|
||||
//! Name-value pair in an object.
|
||||
|
@ -651,18 +741,8 @@ public:
|
|||
template <typename SourceAllocator>
|
||||
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
|
||||
switch (rhs.GetType()) {
|
||||
case kObjectType: {
|
||||
SizeType count = rhs.data_.o.size;
|
||||
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);
|
||||
}
|
||||
case kObjectType:
|
||||
DoCopyMembers(rhs, allocator, copyConstStrings);
|
||||
break;
|
||||
case kArrayType: {
|
||||
SizeType count = rhs.data_.a.size;
|
||||
|
@ -798,25 +878,30 @@ public:
|
|||
/*! Need to destruct elements of array, members of object, or copy-string.
|
||||
*/
|
||||
~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) {
|
||||
case kArrayFlag:
|
||||
{
|
||||
GenericValue* e = GetElementsPointer();
|
||||
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
||||
v->~GenericValue();
|
||||
Allocator::Free(e);
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
Allocator::Free(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kObjectFlag:
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
Allocator::Free(GetMembersPointer());
|
||||
DoFreeMembers();
|
||||
break;
|
||||
|
||||
case kCopyStringFlag:
|
||||
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -835,8 +920,13 @@ public:
|
|||
*/
|
||||
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||
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();
|
||||
RawAssign(rhs);
|
||||
RawAssign(temp);
|
||||
}
|
||||
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); }
|
||||
|
||||
#ifndef __cpp_lib_three_way_comparison
|
||||
//! Equal-to operator with arbitrary types (symmetric version)
|
||||
/*! \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); }
|
||||
//@}
|
||||
#endif
|
||||
|
||||
//!@name Type
|
||||
//@{
|
||||
|
@ -1177,10 +1269,7 @@ public:
|
|||
*/
|
||||
GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
if (newCapacity > data_.o.capacity) {
|
||||
SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
|
||||
data_.o.capacity = newCapacity;
|
||||
}
|
||||
DoReserveMembers(newCapacity, allocator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1254,11 +1343,7 @@ public:
|
|||
MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
RAPIDJSON_ASSERT(name.IsString());
|
||||
MemberIterator member = MemberBegin();
|
||||
for ( ; member != MemberEnd(); ++member)
|
||||
if (name.StringEqual(member->name))
|
||||
break;
|
||||
return member;
|
||||
return DoFindMember(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) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
RAPIDJSON_ASSERT(name.IsString());
|
||||
|
||||
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++;
|
||||
DoAddMember(name, value, allocator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1428,9 +1506,7 @@ public:
|
|||
*/
|
||||
void RemoveAllMembers() {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
data_.o.size = 0;
|
||||
DoClearMembers();
|
||||
}
|
||||
|
||||
//! Remove a member in object by its name.
|
||||
|
@ -1474,14 +1550,7 @@ public:
|
|||
RAPIDJSON_ASSERT(data_.o.size > 0);
|
||||
RAPIDJSON_ASSERT(GetMembersPointer() != 0);
|
||||
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
|
||||
|
||||
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;
|
||||
return DoRemoveMember(m);
|
||||
}
|
||||
|
||||
//! Remove a member from an object by iterator.
|
||||
|
@ -1513,13 +1582,7 @@ public:
|
|||
RAPIDJSON_ASSERT(first >= MemberBegin());
|
||||
RAPIDJSON_ASSERT(first <= last);
|
||||
RAPIDJSON_ASSERT(last <= MemberEnd());
|
||||
|
||||
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;
|
||||
return DoEraseMembers(first, last);
|
||||
}
|
||||
|
||||
//! Erase a member in object by its name.
|
||||
|
@ -1548,7 +1611,9 @@ public:
|
|||
}
|
||||
|
||||
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 GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||
|
||||
//@}
|
||||
|
||||
|
@ -1770,12 +1835,12 @@ public:
|
|||
//!@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.
|
||||
/*! 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.
|
||||
/*! This version has better performance with supplied length, and also support string containing null character.
|
||||
|
@ -1886,7 +1951,7 @@ public:
|
|||
case kArrayType:
|
||||
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
||||
return false;
|
||||
for (const GenericValue* v = Begin(); v != End(); ++v)
|
||||
for (ConstValueIterator v = Begin(); v != End(); ++v)
|
||||
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
|
||||
return false;
|
||||
return handler.EndArray(data_.a.size);
|
||||
|
@ -1922,25 +1987,26 @@ private:
|
|||
|
||||
// Initial flags of different types.
|
||||
kNullFlag = kNullType,
|
||||
kTrueFlag = kTrueType | kBoolFlag,
|
||||
kFalseFlag = kFalseType | kBoolFlag,
|
||||
kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
|
||||
kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
|
||||
kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
|
||||
kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
|
||||
kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
|
||||
kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
|
||||
kConstStringFlag = kStringType | kStringFlag,
|
||||
kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
|
||||
kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
|
||||
// These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
|
||||
kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
|
||||
kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
|
||||
kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
|
||||
kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
|
||||
kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
|
||||
kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
|
||||
kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
|
||||
kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
|
||||
kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
|
||||
kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
|
||||
kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
|
||||
kObjectFlag = kObjectType,
|
||||
kArrayFlag = kArrayType,
|
||||
|
||||
kTypeMask = 0x07
|
||||
};
|
||||
|
||||
static const SizeType kDefaultArrayCapacity = 16;
|
||||
static const SizeType kDefaultObjectCapacity = 16;
|
||||
static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
|
||||
static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
|
||||
|
||||
struct Flag {
|
||||
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
||||
|
@ -2023,6 +2089,13 @@ private:
|
|||
Flag f;
|
||||
}; // 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* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
|
||||
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* 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.
|
||||
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
||||
data_.f.flags = kArrayFlag;
|
||||
|
@ -2047,9 +2400,16 @@ private:
|
|||
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
||||
data_.f.flags = kObjectFlag;
|
||||
if (count) {
|
||||
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
||||
Member* m = DoAllocMembers(count, allocator);
|
||||
SetMembersPointer(m);
|
||||
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
|
||||
SetMembersPointer(0);
|
||||
|
@ -2120,7 +2480,7 @@ typedef GenericValue<UTF8<> > Value;
|
|||
\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.
|
||||
*/
|
||||
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> {
|
||||
public:
|
||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||
|
@ -2170,6 +2530,13 @@ public:
|
|||
#endif
|
||||
|
||||
~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();
|
||||
}
|
||||
|
||||
|
@ -2505,6 +2872,7 @@ private:
|
|||
//! GenericDocument with UTF8 encoding
|
||||
typedef GenericDocument<UTF8<> > Document;
|
||||
|
||||
|
||||
//! Helper class for accessing Value of array type.
|
||||
/*!
|
||||
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 ValueType&() const { return value_; }
|
||||
SizeType Size() const { return value_.Size(); }
|
||||
SizeType Capacity() const { return value_.Capacity(); }
|
||||
bool Empty() const { return value_.Empty(); }
|
||||
|
@ -2584,6 +2953,7 @@ public:
|
|||
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
||||
~GenericObject() {}
|
||||
|
||||
operator ValueType&() const { return value_; }
|
||||
SizeType MemberCount() const { return value_.MemberCount(); }
|
||||
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
||||
bool ObjectEmpty() const { return value_.ObjectEmpty(); }
|
||||
|
@ -2649,4 +3019,9 @@ private:
|
|||
RAPIDJSON_NAMESPACE_END
|
||||
RAPIDJSON_DIAG_POP
|
||||
|
||||
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||
#pragma pop_macro("GetObject")
|
||||
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||
#endif
|
||||
|
||||
#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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
|
||||
#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.
|
||||
//
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
#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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -102,7 +102,7 @@ class PrettyWriter;
|
|||
// document.h
|
||||
|
||||
template <typename Encoding, typename Allocator>
|
||||
struct GenericMember;
|
||||
class GenericMember;
|
||||
|
||||
template <bool Const, typename Encoding, typename Allocator>
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
#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
|
||||
#pragma intrinsic(_umul128)
|
||||
#endif
|
||||
|
@ -37,7 +37,8 @@ public:
|
|||
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);
|
||||
digits_[0] = 0;
|
||||
size_t i = 0;
|
||||
|
@ -221,7 +222,8 @@ public:
|
|||
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
|
||||
|
||||
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);
|
||||
if (IsZero())
|
||||
*this = u;
|
||||
|
@ -236,11 +238,12 @@ private:
|
|||
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;
|
||||
for (const char* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
||||
r = r * 10u + static_cast<unsigned>(*p - '0');
|
||||
for (const Ch* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9'));
|
||||
r = r * 10u + static_cast<unsigned>(*p - Ch('0'));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -20,11 +20,11 @@
|
|||
#define RAPIDJSON_DIYFP_H_
|
||||
|
||||
#include "../rapidjson.h"
|
||||
#include "clzll.h"
|
||||
#include <limits>
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
#pragma intrinsic(_umul128)
|
||||
#endif
|
||||
|
||||
|
@ -100,22 +100,8 @@ struct DiyFp {
|
|||
}
|
||||
|
||||
DiyFp Normalize() const {
|
||||
RAPIDJSON_ASSERT(f != 0); // https://stackoverflow.com/a/26809183/291737
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, f);
|
||||
return DiyFp(f << (63 - index), e - (63 - index));
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
int s = __builtin_clzll(f);
|
||||
int s = static_cast<int>(clzll(f));
|
||||
return DiyFp(f << s, e - s);
|
||||
#else
|
||||
DiyFp res = *this;
|
||||
while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
|
||||
res.f <<= 1;
|
||||
res.e--;
|
||||
}
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// 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) {
|
||||
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 wp_w = Mp - W;
|
||||
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;
|
||||
if (tmp <= delta) {
|
||||
*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;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +107,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||
if (p2 < delta) {
|
||||
*K += 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;
|
||||
}
|
||||
}
|
||||
|
|
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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -23,7 +23,6 @@
|
|||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
||||
#elif defined(_MSC_VER)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||
|
@ -32,9 +31,6 @@ RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#if __GNUC__ >= 7
|
||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||
|
@ -291,6 +287,7 @@ private:
|
|||
if (!CharacterEscape(ds, &codepoint))
|
||||
return; // Unsupported escape character
|
||||
// fall through to default
|
||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||
|
||||
default: // Pattern character
|
||||
PushOperand(operandStack, codepoint);
|
||||
|
@ -520,6 +517,7 @@ private:
|
|||
else if (!CharacterEscape(ds, &codepoint))
|
||||
return false;
|
||||
// fall through to default
|
||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||
|
||||
default:
|
||||
switch (step) {
|
||||
|
@ -529,6 +527,7 @@ private:
|
|||
break;
|
||||
}
|
||||
// fall through to step 0 for other characters
|
||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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));
|
||||
}
|
||||
|
||||
//! 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.
|
||||
template<typename Encoding>
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
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;
|
||||
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
||||
for (; i < dLen; i++) {
|
||||
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;
|
||||
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++;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
||||
Double a(approx);
|
||||
|
@ -223,7 +225,8 @@ inline double StrtodBigInteger(double approx, const char* decimals, int dLen, in
|
|||
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(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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -16,6 +16,7 @@
|
|||
#define RAPIDJSON_POINTER_H_
|
||||
|
||||
#include "document.h"
|
||||
#include "uri.h"
|
||||
#include "internal/itoa.h"
|
||||
|
||||
#ifdef __clang__
|
||||
|
@ -80,6 +81,8 @@ class GenericPointer {
|
|||
public:
|
||||
typedef typename ValueType::EncodingType EncodingType; //!< Encoding 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.
|
||||
/*!
|
||||
|
@ -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) {}
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
|
@ -488,10 +491,11 @@ public:
|
|||
v = &((*v)[t->index]);
|
||||
}
|
||||
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()) {
|
||||
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;
|
||||
}
|
||||
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
|
||||
//@{
|
||||
|
||||
|
@ -543,7 +611,7 @@ public:
|
|||
switch (v->GetType()) {
|
||||
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())
|
||||
break;
|
||||
v = &m->value;
|
||||
|
@ -779,7 +847,7 @@ public:
|
|||
switch (v->GetType()) {
|
||||
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())
|
||||
return false;
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// 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) :
|
||||
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
||||
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
PrettyWriter(PrettyWriter&& rhs) :
|
||||
|
@ -164,7 +164,7 @@ public:
|
|||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||
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;
|
||||
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -124,6 +124,19 @@
|
|||
#define RAPIDJSON_NAMESPACE_END }
|
||||
#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
|
||||
|
||||
|
@ -149,6 +162,24 @@
|
|||
#include <string>
|
||||
#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
|
||||
|
||||
|
@ -403,7 +434,7 @@ RAPIDJSON_NAMESPACE_END
|
|||
*/
|
||||
#ifndef RAPIDJSON_ASSERT
|
||||
#include <cassert>
|
||||
#define RAPIDJSON_ASSERT(x)
|
||||
#define RAPIDJSON_ASSERT(x) assert(x)
|
||||
#endif // RAPIDJSON_ASSERT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -411,7 +442,7 @@ RAPIDJSON_NAMESPACE_END
|
|||
|
||||
// Prefer C++11 static_assert, if available
|
||||
#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) \
|
||||
static_assert(x, RAPIDJSON_STRINGIFY(x))
|
||||
#endif // C++11
|
||||
|
@ -490,6 +521,12 @@ RAPIDJSON_NAMESPACE_END
|
|||
#define RAPIDJSON_VERSION_CODE(x,y,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
|
||||
|
||||
|
@ -535,8 +572,14 @@ RAPIDJSON_NAMESPACE_END
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++11 features
|
||||
|
||||
#ifndef RAPIDJSON_HAS_CXX11
|
||||
#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L)
|
||||
#endif
|
||||
|
||||
#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) && \
|
||||
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
|
||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
||||
|
@ -553,8 +596,14 @@ RAPIDJSON_NAMESPACE_END
|
|||
#endif
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
#include <utility> // std::move
|
||||
#endif
|
||||
|
||||
#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)
|
||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
||||
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
||||
|
@ -564,11 +613,13 @@ RAPIDJSON_NAMESPACE_END
|
|||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef RAPIDJSON_NOEXCEPT
|
||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#define RAPIDJSON_NOEXCEPT noexcept
|
||||
#else
|
||||
#define RAPIDJSON_NOEXCEPT /* noexcept */
|
||||
#define RAPIDJSON_NOEXCEPT throw()
|
||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#endif
|
||||
|
||||
// no automatic detection, yet
|
||||
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
|
@ -591,6 +642,27 @@ RAPIDJSON_NAMESPACE_END
|
|||
#endif
|
||||
#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
|
||||
|
||||
//! Assertion (in non-throwing contexts).
|
||||
|
@ -609,16 +681,29 @@ RAPIDJSON_NAMESPACE_END
|
|||
|
||||
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
||||
#ifdef RAPIDJSON_ASSERT_THROWS
|
||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
||||
#else
|
||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#include <cassert>
|
||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
|
||||
#else
|
||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||
#endif // RAPIDJSON_ASSERT_THROWS
|
||||
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// malloc/realloc/free
|
||||
|
||||
#ifndef RAPIDJSON_MALLOC
|
||||
///! customization point for global \c malloc
|
||||
#define RAPIDJSON_MALLOC(size) std::malloc(size)
|
||||
#endif
|
||||
#ifndef RAPIDJSON_REALLOC
|
||||
///! customization point for global \c realloc
|
||||
#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
|
||||
#endif
|
||||
#ifndef RAPIDJSON_FREE
|
||||
///! customization point for global \c free
|
||||
#define RAPIDJSON_FREE(ptr) std::free(ptr)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// new/delete
|
||||
|
||||
|
|
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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include "allocators.h"
|
||||
#include "stream.h"
|
||||
#include "encodedstream.h"
|
||||
#include "internal/clzll.h"
|
||||
#include "internal/meta.h"
|
||||
#include "internal/stack.h"
|
||||
#include "internal/strtod.h"
|
||||
|
@ -153,6 +154,7 @@ enum ParseFlag {
|
|||
kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
|
||||
kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -443,16 +445,16 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
|||
|
||||
x = vmvnq_u8(x); // Negate
|
||||
x = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
int lz =__builtin_clzll(high);;
|
||||
uint32_t lz = internal::clzll(high);
|
||||
return p + 8 + (lz >> 3);
|
||||
}
|
||||
} else {
|
||||
int lz = __builtin_clzll(low);;
|
||||
uint32_t lz = internal::clzll(low);
|
||||
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 = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
int lz = __builtin_clzll(high);
|
||||
uint32_t lz = internal::clzll(high);
|
||||
return p + 8 + (lz >> 3);
|
||||
}
|
||||
} else {
|
||||
int lz = __builtin_clzll(low);
|
||||
uint32_t lz = internal::clzll(low);
|
||||
return p + (lz >> 3);
|
||||
}
|
||||
}
|
||||
|
@ -990,7 +992,7 @@ private:
|
|||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
static const char escape[256] = {
|
||||
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
|
||||
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/',
|
||||
Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
|
||||
0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
|
||||
0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -1013,19 +1015,31 @@ private:
|
|||
is.Take();
|
||||
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
|
||||
is.Take();
|
||||
unsigned codepoint = ParseHex4(is, escapeOffset);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
|
||||
// Handle UTF-16 surrogate pair
|
||||
if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
|
||||
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
|
||||
// high surrogate, check if followed by valid low surrogate
|
||||
if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) {
|
||||
// Handle UTF-16 surrogate pair
|
||||
if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
||||
unsigned codepoint2 = ParseHex4(is, escapeOffset);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
||||
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
// single low surrogate
|
||||
else
|
||||
{
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
||||
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);
|
||||
}
|
||||
|
@ -1244,19 +1258,19 @@ private:
|
|||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||
|
||||
x = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
SizeType length = 0;
|
||||
bool escaped = false;
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
unsigned lz = (unsigned)__builtin_clzll(high);;
|
||||
uint32_t lz = internal::clzll(high);
|
||||
length = 8 + (lz >> 3);
|
||||
escaped = true;
|
||||
}
|
||||
} else {
|
||||
unsigned lz = (unsigned)__builtin_clzll(low);;
|
||||
uint32_t lz = internal::clzll(low);
|
||||
length = lz >> 3;
|
||||
escaped = true;
|
||||
}
|
||||
|
@ -1314,19 +1328,19 @@ private:
|
|||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||
|
||||
x = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
SizeType length = 0;
|
||||
bool escaped = false;
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
unsigned lz = (unsigned)__builtin_clzll(high);
|
||||
uint32_t lz = internal::clzll(high);
|
||||
length = 8 + (lz >> 3);
|
||||
escaped = true;
|
||||
}
|
||||
} else {
|
||||
unsigned lz = (unsigned)__builtin_clzll(low);
|
||||
uint32_t lz = internal::clzll(low);
|
||||
length = lz >> 3;
|
||||
escaped = true;
|
||||
}
|
||||
|
@ -1370,17 +1384,17 @@ private:
|
|||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||
|
||||
x = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
int lz = __builtin_clzll(high);
|
||||
uint32_t lz = internal::clzll(high);
|
||||
p += 8 + (lz >> 3);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int lz = __builtin_clzll(low);
|
||||
uint32_t lz = internal::clzll(low);
|
||||
p += lz >> 3;
|
||||
break;
|
||||
}
|
||||
|
@ -1390,11 +1404,11 @@ private:
|
|||
}
|
||||
#endif // RAPIDJSON_NEON
|
||||
|
||||
template<typename InputStream, bool backup, bool pushOnTake>
|
||||
template<typename InputStream, typename StackCharacter, bool backup, bool pushOnTake>
|
||||
class NumberStream;
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, false, false> {
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, false, false> {
|
||||
public:
|
||||
typedef typename InputStream::Ch Ch;
|
||||
|
||||
|
@ -1403,11 +1417,11 @@ private:
|
|||
RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
|
||||
RAPIDJSON_FORCEINLINE Ch TakePush() { 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 Length() { return 0; }
|
||||
const char* Pop() { return 0; }
|
||||
const StackCharacter* Pop() { return 0; }
|
||||
|
||||
protected:
|
||||
NumberStream& operator=(const NumberStream&);
|
||||
|
@ -1415,35 +1429,35 @@ private:
|
|||
InputStream& is;
|
||||
};
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
|
||||
typedef NumberStream<InputStream, false, false> Base;
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
||||
stackStream.Put(static_cast<char>(Base::is.Peek()));
|
||||
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
|
||||
return Base::is.Take();
|
||||
}
|
||||
|
||||
RAPIDJSON_FORCEINLINE void Push(char c) {
|
||||
RAPIDJSON_FORCEINLINE void Push(StackCharacter c) {
|
||||
stackStream.Put(c);
|
||||
}
|
||||
|
||||
size_t Length() { return stackStream.Length(); }
|
||||
|
||||
const char* Pop() {
|
||||
const StackCharacter* Pop() {
|
||||
stackStream.Put('\0');
|
||||
return stackStream.Pop();
|
||||
}
|
||||
|
||||
private:
|
||||
StackStream<char> stackStream;
|
||||
StackStream<StackCharacter> stackStream;
|
||||
};
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
|
||||
typedef NumberStream<InputStream, true, false> Base;
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
||||
|
||||
|
@ -1452,8 +1466,10 @@ private:
|
|||
|
||||
template<unsigned parseFlags, typename InputStream, typename 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);
|
||||
NumberStream<InputStream,
|
||||
NumberStream<InputStream, NumberCharacter,
|
||||
((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
|
||||
((parseFlags & kParseInsituFlag) == 0) :
|
||||
((parseFlags & kParseFullPrecisionFlag) != 0),
|
||||
|
@ -1678,10 +1694,10 @@ private:
|
|||
}
|
||||
else {
|
||||
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
|
||||
StringStream srcStream(s.Pop());
|
||||
GenericStringStream<UTF8<NumberCharacter>> srcStream(s.Pop());
|
||||
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
|
||||
while (numCharsToCopy--) {
|
||||
Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||
}
|
||||
dstStream.Put('\0');
|
||||
const typename TargetEncoding::Ch* str = dstStream.Pop();
|
||||
|
@ -1691,7 +1707,7 @@ private:
|
|||
}
|
||||
else {
|
||||
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) {
|
||||
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 @@
|
|||
![RapidJSON logo](doc/logo/rapidjson.png)
|
||||
|
||||
![Release version](https://img.shields.io/badge/release-v1.1.0-blue.svg)
|
||||
|
||||
## 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.
|
||||
|
||||
![simpledom](doc/diagram/simpledom.png)
|
||||
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -16,6 +16,7 @@
|
|||
#define RAPIDJSON_WRITER_H_
|
||||
|
||||
#include "stream.h"
|
||||
#include "internal/clzll.h"
|
||||
#include "internal/meta.h"
|
||||
#include "internal/stack.h"
|
||||
#include "internal/strfunc.h"
|
||||
|
@ -226,7 +227,7 @@ public:
|
|||
return Key(str.data(), SizeType(str.size()));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool EndObject(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
|
||||
|
@ -282,6 +283,8 @@ public:
|
|||
os_->Flush();
|
||||
}
|
||||
|
||||
static const size_t kDefaultLevelDepth = 32;
|
||||
|
||||
protected:
|
||||
//! Information for each nested level
|
||||
struct Level {
|
||||
|
@ -291,8 +294,6 @@ protected:
|
|||
bool inLine = false;
|
||||
};
|
||||
|
||||
static const size_t kDefaultLevelDepth = 32;
|
||||
|
||||
bool WriteNull() {
|
||||
PutReserve(*os_, 4);
|
||||
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 = vrev64q_u8(x); // Rev in 64
|
||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||
|
||||
SizeType len = 0;
|
||||
bool escaped = false;
|
||||
if (low == 0) {
|
||||
if (high != 0) {
|
||||
unsigned lz = (unsigned)__builtin_clzll(high);
|
||||
uint32_t lz = internal::clzll(high);
|
||||
len = 8 + (lz >> 3);
|
||||
escaped = true;
|
||||
}
|
||||
} else {
|
||||
unsigned lz = (unsigned)__builtin_clzll(low);
|
||||
uint32_t lz = internal::clzll(low);
|
||||
len = lz >> 3;
|
||||
escaped = true;
|
||||
}
|
||||
|
|
|
@ -174,7 +174,6 @@ const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
|
|||
}
|
||||
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::object() const
|
||||
{
|
||||
assert(false);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/json/JsonRequest.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
Loading…
Reference in a new issue