mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-02-03 05:14:44 +01:00
fixes
This commit is contained in:
parent
07294034f6
commit
db8f736d58
@ -146,10 +146,12 @@ class MemoryPoolAllocator {
|
|||||||
static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
|
static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
|
||||||
static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
|
static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
|
||||||
|
|
||||||
static inline ChunkHeader* GetChunkHead(SharedData* shared) {
|
static inline ChunkHeader *GetChunkHead(SharedData *shared)
|
||||||
|
{
|
||||||
return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
|
return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
|
||||||
}
|
}
|
||||||
static inline uint8_t* GetChunkBuffer(SharedData* shared) {
|
static inline uint8_t *GetChunkBuffer(SharedData *shared)
|
||||||
|
{
|
||||||
return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
|
return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,9 +165,12 @@ public:
|
|||||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
\param baseAllocator The allocator for allocating memory chunks.
|
||||||
*/
|
*/
|
||||||
explicit MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : chunk_capacity_(chunkSize),
|
explicit
|
||||||
|
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||||
|
chunk_capacity_(chunkSize),
|
||||||
baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
|
baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
|
||||||
shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0)) {
|
shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
|
||||||
|
{
|
||||||
RAPIDJSON_ASSERT(baseAllocator_ != 0);
|
RAPIDJSON_ASSERT(baseAllocator_ != 0);
|
||||||
RAPIDJSON_ASSERT(shared_ != 0);
|
RAPIDJSON_ASSERT(shared_ != 0);
|
||||||
if (baseAllocator) {
|
if (baseAllocator) {
|
||||||
@ -192,9 +197,11 @@ public:
|
|||||||
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
\param baseAllocator The allocator for allocating memory chunks.
|
||||||
*/
|
*/
|
||||||
MemoryPoolAllocator(void* buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : chunk_capacity_(chunkSize),
|
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||||
|
chunk_capacity_(chunkSize),
|
||||||
baseAllocator_(baseAllocator),
|
baseAllocator_(baseAllocator),
|
||||||
shared_(static_cast<SharedData*>(AlignBuffer(buffer, size))) {
|
shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
|
||||||
|
{
|
||||||
RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
|
RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
|
||||||
shared_->chunkHead = GetChunkHead(shared_);
|
shared_->chunkHead = GetChunkHead(shared_);
|
||||||
shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
|
shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
|
||||||
@ -205,13 +212,16 @@ public:
|
|||||||
shared_->refcount = 1;
|
shared_->refcount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT : chunk_capacity_(rhs.chunk_capacity_),
|
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
|
chunk_capacity_(rhs.chunk_capacity_),
|
||||||
baseAllocator_(rhs.baseAllocator_),
|
baseAllocator_(rhs.baseAllocator_),
|
||||||
shared_(rhs.shared_) {
|
shared_(rhs.shared_)
|
||||||
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||||
++shared_->refcount;
|
++shared_->refcount;
|
||||||
}
|
}
|
||||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT {
|
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||||
++rhs.shared_->refcount;
|
++rhs.shared_->refcount;
|
||||||
this->~MemoryPoolAllocator();
|
this->~MemoryPoolAllocator();
|
||||||
@ -222,13 +232,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT : chunk_capacity_(rhs.chunk_capacity_),
|
MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
|
chunk_capacity_(rhs.chunk_capacity_),
|
||||||
baseAllocator_(rhs.baseAllocator_),
|
baseAllocator_(rhs.baseAllocator_),
|
||||||
shared_(rhs.shared_) {
|
shared_(rhs.shared_)
|
||||||
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||||
rhs.shared_ = 0;
|
rhs.shared_ = 0;
|
||||||
}
|
}
|
||||||
MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT {
|
MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||||
this->~MemoryPoolAllocator();
|
this->~MemoryPoolAllocator();
|
||||||
baseAllocator_ = rhs.baseAllocator_;
|
baseAllocator_ = rhs.baseAllocator_;
|
||||||
@ -387,7 +400,8 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void* AlignBuffer(void* buf, size_t& size) {
|
static inline void* AlignBuffer(void* buf, size_t &size)
|
||||||
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(buf != 0);
|
RAPIDJSON_NOEXCEPT_ASSERT(buf != 0);
|
||||||
const uintptr_t mask = sizeof(void*) - 1;
|
const uintptr_t mask = sizeof(void*) - 1;
|
||||||
const uintptr_t ubuf = reinterpret_cast<uintptr_t>(buf);
|
const uintptr_t ubuf = reinterpret_cast<uintptr_t>(buf);
|
||||||
@ -407,24 +421,31 @@ private:
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename, typename = void>
|
template<typename, typename = void>
|
||||||
struct IsRefCounted : public FalseType {};
|
struct IsRefCounted :
|
||||||
|
public FalseType
|
||||||
|
{ };
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> : public TrueType {};
|
struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> :
|
||||||
|
public TrueType
|
||||||
|
{ };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n) {
|
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));
|
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)));
|
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
inline T* Malloc(A& a, size_t n = 1) {
|
inline T *Malloc(A& a, size_t n = 1)
|
||||||
|
{
|
||||||
return Realloc<T, A>(a, NULL, 0, n);
|
return Realloc<T, A>(a, NULL, 0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
inline void Free(A& a, T* p, size_t n = 1) {
|
inline void Free(A& a, T *p, size_t n = 1)
|
||||||
|
{
|
||||||
static_cast<void>(Realloc<T, A>(a, p, n, 0));
|
static_cast<void>(Realloc<T, A>(a, p, n, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +455,9 @@ RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T, typename BaseAllocator = CrtAllocator>
|
template <typename T, typename BaseAllocator = CrtAllocator>
|
||||||
class StdAllocator : public std::allocator<T> {
|
class StdAllocator :
|
||||||
|
public std::allocator<T>
|
||||||
|
{
|
||||||
typedef std::allocator<T> allocator_type;
|
typedef std::allocator<T> allocator_type;
|
||||||
#if RAPIDJSON_HAS_CXX11
|
#if RAPIDJSON_HAS_CXX11
|
||||||
typedef std::allocator_traits<allocator_type> traits_type;
|
typedef std::allocator_traits<allocator_type> traits_type;
|
||||||
@ -445,19 +468,27 @@ class StdAllocator : public std::allocator<T> {
|
|||||||
public:
|
public:
|
||||||
typedef BaseAllocator BaseAllocatorType;
|
typedef BaseAllocator BaseAllocatorType;
|
||||||
|
|
||||||
StdAllocator() RAPIDJSON_NOEXCEPT : allocator_type(),
|
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_() {}
|
allocator_type(),
|
||||||
|
baseAllocator_()
|
||||||
|
{ }
|
||||||
|
|
||||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : allocator_type(rhs),
|
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(rhs.baseAllocator_) {}
|
allocator_type(rhs),
|
||||||
|
baseAllocator_(rhs.baseAllocator_)
|
||||||
|
{ }
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT : allocator_type(rhs),
|
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(rhs.baseAllocator_) {}
|
allocator_type(rhs),
|
||||||
|
baseAllocator_(rhs.baseAllocator_)
|
||||||
|
{ }
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT : allocator_type(std::move(rhs)),
|
StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(std::move(rhs.baseAllocator_)) {}
|
allocator_type(std::move(rhs)),
|
||||||
|
baseAllocator_(std::move(rhs.baseAllocator_))
|
||||||
|
{ }
|
||||||
#endif
|
#endif
|
||||||
#if RAPIDJSON_HAS_CXX11
|
#if RAPIDJSON_HAS_CXX11
|
||||||
using propagate_on_container_move_assignment = std::true_type;
|
using propagate_on_container_move_assignment = std::true_type;
|
||||||
@ -465,10 +496,13 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* implicit */
|
/* implicit */
|
||||||
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT : allocator_type(),
|
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(allocator) {}
|
allocator_type(),
|
||||||
|
baseAllocator_(allocator)
|
||||||
|
{ }
|
||||||
|
|
||||||
~StdAllocator() RAPIDJSON_NOEXCEPT {}
|
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||||
|
{ }
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
struct rebind {
|
struct rebind {
|
||||||
@ -487,22 +521,27 @@ public:
|
|||||||
typedef typename std::add_lvalue_reference<value_type>::type &reference;
|
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;
|
typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
|
||||||
|
|
||||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT {
|
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return std::addressof(r);
|
return std::addressof(r);
|
||||||
}
|
}
|
||||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT {
|
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return std::addressof(r);
|
return std::addressof(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type max_size() const RAPIDJSON_NOEXCEPT {
|
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return traits_type::max_size(*this);
|
return traits_type::max_size(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
void construct(pointer p, Args&&... args) {
|
void construct(pointer p, Args&&... args)
|
||||||
|
{
|
||||||
traits_type::construct(*this, p, std::forward<Args>(args)...);
|
traits_type::construct(*this, p, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
void destroy(pointer p) {
|
void destroy(pointer p)
|
||||||
|
{
|
||||||
traits_type::destroy(*this, p);
|
traits_type::destroy(*this, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,39 +550,48 @@ public:
|
|||||||
typedef typename allocator_type::reference reference;
|
typedef typename allocator_type::reference reference;
|
||||||
typedef typename allocator_type::const_reference const_reference;
|
typedef typename allocator_type::const_reference const_reference;
|
||||||
|
|
||||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT {
|
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return allocator_type::address(r);
|
return allocator_type::address(r);
|
||||||
}
|
}
|
||||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT {
|
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return allocator_type::address(r);
|
return allocator_type::address(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type max_size() const RAPIDJSON_NOEXCEPT {
|
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return allocator_type::max_size();
|
return allocator_type::max_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct(pointer p, const_reference r) {
|
void construct(pointer p, const_reference r)
|
||||||
|
{
|
||||||
allocator_type::construct(p, r);
|
allocator_type::construct(p, r);
|
||||||
}
|
}
|
||||||
void destroy(pointer p) {
|
void destroy(pointer p)
|
||||||
|
{
|
||||||
allocator_type::destroy(p);
|
allocator_type::destroy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !RAPIDJSON_HAS_CXX11
|
#endif // !RAPIDJSON_HAS_CXX11
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
U* allocate(size_type n = 1, const void* = 0) {
|
U* allocate(size_type n = 1, const void* = 0)
|
||||||
|
{
|
||||||
return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
|
return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void deallocate(U* p, size_type n = 1) {
|
void deallocate(U* p, size_type n = 1)
|
||||||
|
{
|
||||||
RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
|
RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer allocate(size_type n = 1, const void* = 0) {
|
pointer allocate(size_type n = 1, const void* = 0)
|
||||||
|
{
|
||||||
return allocate<value_type>(n);
|
return allocate<value_type>(n);
|
||||||
}
|
}
|
||||||
void deallocate(pointer p, size_type n = 1) {
|
void deallocate(pointer p, size_type n = 1)
|
||||||
|
{
|
||||||
deallocate<value_type>(p, n);
|
deallocate<value_type>(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,24 +600,29 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT {
|
bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return baseAllocator_ == rhs.baseAllocator_;
|
return baseAllocator_ == rhs.baseAllocator_;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT {
|
bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
return !operator==(rhs);
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! rapidjson Allocator concept
|
//! rapidjson Allocator concept
|
||||||
static const bool kNeedFree = BaseAllocator::kNeedFree;
|
static const bool kNeedFree = BaseAllocator::kNeedFree;
|
||||||
static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
|
static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
|
||||||
void* Malloc(size_t size) {
|
void* Malloc(size_t size)
|
||||||
|
{
|
||||||
return baseAllocator_.Malloc(size);
|
return baseAllocator_.Malloc(size);
|
||||||
}
|
}
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
|
||||||
|
{
|
||||||
return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
|
return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
|
||||||
}
|
}
|
||||||
static void Free(void* ptr) RAPIDJSON_NOEXCEPT {
|
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
BaseAllocator::Free(ptr);
|
BaseAllocator::Free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,27 +635,38 @@ private:
|
|||||||
|
|
||||||
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
|
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
|
||||||
template <typename BaseAllocator>
|
template <typename BaseAllocator>
|
||||||
class StdAllocator<void, BaseAllocator> : public std::allocator<void> {
|
class StdAllocator<void, BaseAllocator> :
|
||||||
|
public std::allocator<void>
|
||||||
|
{
|
||||||
typedef std::allocator<void> allocator_type;
|
typedef std::allocator<void> allocator_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef BaseAllocator BaseAllocatorType;
|
typedef BaseAllocator BaseAllocatorType;
|
||||||
|
|
||||||
StdAllocator() RAPIDJSON_NOEXCEPT : allocator_type(),
|
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_() {}
|
allocator_type(),
|
||||||
|
baseAllocator_()
|
||||||
|
{ }
|
||||||
|
|
||||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : allocator_type(rhs),
|
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(rhs.baseAllocator_) {}
|
allocator_type(rhs),
|
||||||
|
baseAllocator_(rhs.baseAllocator_)
|
||||||
|
{ }
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT : allocator_type(rhs),
|
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(rhs.baseAllocator_) {}
|
allocator_type(rhs),
|
||||||
|
baseAllocator_(rhs.baseAllocator_)
|
||||||
|
{ }
|
||||||
|
|
||||||
/* implicit */
|
/* implicit */
|
||||||
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT : allocator_type(),
|
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
|
||||||
baseAllocator_(allocator) {}
|
allocator_type(),
|
||||||
|
baseAllocator_(allocator)
|
||||||
|
{ }
|
||||||
|
|
||||||
~StdAllocator() RAPIDJSON_NOEXCEPT {}
|
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||||
|
{ }
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
struct rebind {
|
struct rebind {
|
||||||
|
@ -40,7 +40,8 @@ class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
|
|||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
CursorStreamWrapper(InputStream& is) : GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
|
CursorStreamWrapper(InputStream& is):
|
||||||
|
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
|
||||||
|
|
||||||
// counting line and column number
|
// counting line and column number
|
||||||
Ch Take() {
|
Ch Take() {
|
||||||
@ -48,8 +49,7 @@ public:
|
|||||||
if(ch == '\n') {
|
if(ch == '\n') {
|
||||||
line_ ++;
|
line_ ++;
|
||||||
col_ = 0;
|
col_ = 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
col_ ++;
|
col_ ++;
|
||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
|
@ -126,7 +126,8 @@ public:
|
|||||||
//! Move constructor in C++11
|
//! Move constructor in C++11
|
||||||
GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
|
GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
: name(std::move(rhs.name)),
|
: name(std::move(rhs.name)),
|
||||||
value(std::move(rhs.value)) {
|
value(std::move(rhs.value))
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Move assignment in C++11
|
//! Move assignment in C++11
|
||||||
@ -185,8 +186,7 @@ template <bool Const, typename Encoding, typename Allocator>
|
|||||||
class GenericMemberIterator {
|
class GenericMemberIterator {
|
||||||
|
|
||||||
friend class GenericValue<Encoding,Allocator>;
|
friend class GenericValue<Encoding,Allocator>;
|
||||||
template <bool, typename, typename>
|
template <bool, typename, typename> friend class GenericMemberIterator;
|
||||||
friend class GenericMemberIterator;
|
|
||||||
|
|
||||||
typedef GenericMember<Encoding,Allocator> PlainType;
|
typedef GenericMember<Encoding,Allocator> PlainType;
|
||||||
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
|
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
|
||||||
@ -238,31 +238,14 @@ public:
|
|||||||
Otherwise, the copy constructor is implicitly defined.
|
Otherwise, the copy constructor is implicitly defined.
|
||||||
*/
|
*/
|
||||||
GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
|
GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
|
||||||
Iterator& operator=(const NonConstIterator& it) {
|
Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
|
||||||
ptr_ = it.ptr_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @name stepping
|
//! @name stepping
|
||||||
//@{
|
//@{
|
||||||
Iterator& operator++() {
|
Iterator& operator++(){ ++ptr_; return *this; }
|
||||||
++ptr_;
|
Iterator& operator--(){ --ptr_; return *this; }
|
||||||
return *this;
|
Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
|
||||||
}
|
Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
|
||||||
Iterator& operator--() {
|
|
||||||
--ptr_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Iterator operator++(int) {
|
|
||||||
Iterator old(*this);
|
|
||||||
++ptr_;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
Iterator operator--(int) {
|
|
||||||
Iterator old(*this);
|
|
||||||
--ptr_;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! @name increment/decrement
|
//! @name increment/decrement
|
||||||
@ -270,34 +253,21 @@ public:
|
|||||||
Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
|
Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
|
||||||
Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
|
Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
|
||||||
|
|
||||||
Iterator& operator+=(DifferenceType n) {
|
Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
|
||||||
ptr_ += n;
|
Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Iterator& operator-=(DifferenceType n) {
|
|
||||||
ptr_ -= n;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! @name relations
|
//! @name relations
|
||||||
//@{
|
//@{
|
||||||
template <bool Const_>
|
template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
|
||||||
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_>
|
template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
|
||||||
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_>
|
template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
|
||||||
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
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
template <bool Const_>
|
template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
|
||||||
std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
|
|
||||||
#endif
|
#endif
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@ -403,8 +373,7 @@ struct GenericStringRef {
|
|||||||
#endif
|
#endif
|
||||||
template<SizeType N>
|
template<SizeType N>
|
||||||
GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
|
GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
|
||||||
: s(str),
|
: s(str), length(N-1) {}
|
||||||
length(N - 1) {}
|
|
||||||
|
|
||||||
//! Explicitly create string reference from \c const character pointer
|
//! Explicitly create string reference from \c const character pointer
|
||||||
#ifndef __clang__ // -Wdocumentation
|
#ifndef __clang__ // -Wdocumentation
|
||||||
@ -533,13 +502,11 @@ namespace internal {
|
|||||||
struct IsGenericValueImpl : FalseType {};
|
struct IsGenericValueImpl : FalseType {};
|
||||||
|
|
||||||
// select candidates according to nested encoding and allocator types
|
// select candidates according to nested encoding and allocator types
|
||||||
template <typename T>
|
template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
|
||||||
struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
|
|
||||||
: IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
|
: IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
|
||||||
|
|
||||||
// helper to match arbitrary GenericValue instantiations, including derived classes
|
// helper to match arbitrary GenericValue instantiations, including derived classes
|
||||||
template <typename T>
|
template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
|
||||||
struct IsGenericValue : IsGenericValueImpl<T>::Type {};
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
@ -681,10 +648,8 @@ namespace internal {
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
template <bool, typename>
|
template <bool, typename> class GenericArray;
|
||||||
class GenericArray;
|
template <bool, typename> class GenericObject;
|
||||||
template <bool, typename>
|
|
||||||
class GenericObject;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// GenericValue
|
// GenericValue
|
||||||
@ -746,6 +711,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructor with JSON value type.
|
//! Constructor with JSON value type.
|
||||||
/*! This creates a Value of specified type with default content.
|
/*! This creates a Value of specified type with default content.
|
||||||
\param type Type of the value.
|
\param type Type of the value.
|
||||||
@ -787,7 +753,8 @@ public:
|
|||||||
data_.f.flags = kArrayFlag;
|
data_.f.flags = kArrayFlag;
|
||||||
data_.a.size = data_.a.capacity = count;
|
data_.a.size = data_.a.capacity = count;
|
||||||
SetElementsPointer(le);
|
SetElementsPointer(le);
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case kStringType:
|
case kStringType:
|
||||||
if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
|
if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
|
||||||
data_.f.flags = rhs.data_.f.flags;
|
data_.f.flags = rhs.data_.f.flags;
|
||||||
@ -861,16 +828,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Constructor for double value.
|
//! Constructor for double value.
|
||||||
explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() {
|
explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
|
||||||
data_.n.d = d;
|
|
||||||
data_.f.flags = kNumberDoubleFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Constructor for float value.
|
//! Constructor for float value.
|
||||||
explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() {
|
explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
|
||||||
data_.n.d = static_cast<double>(f);
|
|
||||||
data_.f.flags = kNumberDoubleFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Constructor for constant string (i.e. do not make a copy of string)
|
//! Constructor for constant string (i.e. do not make a copy of string)
|
||||||
GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
|
GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
|
||||||
@ -922,14 +883,16 @@ public:
|
|||||||
if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
|
if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
|
||||||
internal::IsRefCounted<Allocator>::Value)) {
|
internal::IsRefCounted<Allocator>::Value)) {
|
||||||
switch(data_.f.flags) {
|
switch(data_.f.flags) {
|
||||||
case kArrayFlag: {
|
case kArrayFlag:
|
||||||
|
{
|
||||||
GenericValue* e = GetElementsPointer();
|
GenericValue* e = GetElementsPointer();
|
||||||
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
||||||
v->~GenericValue();
|
v->~GenericValue();
|
||||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||||
Allocator::Free(e);
|
Allocator::Free(e);
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case kObjectFlag:
|
case kObjectFlag:
|
||||||
DoFreeMembers();
|
DoFreeMembers();
|
||||||
@ -1113,9 +1076,7 @@ public:
|
|||||||
//! Equal-to operator with primitive types
|
//! Equal-to operator with primitive types
|
||||||
/*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
|
/*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (bool))
|
|
||||||
operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
|
||||||
|
|
||||||
//! Not-equal-to operator
|
//! Not-equal-to operator
|
||||||
/*! \return !(*this == rhs)
|
/*! \return !(*this == rhs)
|
||||||
@ -1129,22 +1090,18 @@ public:
|
|||||||
//! Not-equal-to operator with arbitrary types
|
//! Not-equal-to operator with arbitrary types
|
||||||
/*! \return !(*this == rhs)
|
/*! \return !(*this == rhs)
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool))
|
|
||||||
operator!=(const T& rhs) const { return !(*this == rhs); }
|
|
||||||
|
|
||||||
#ifndef __cpp_lib_three_way_comparison
|
#ifndef __cpp_lib_three_way_comparison
|
||||||
//! Equal-to operator with arbitrary types (symmetric version)
|
//! Equal-to operator with arbitrary types (symmetric version)
|
||||||
/*! \return (rhs == lhs)
|
/*! \return (rhs == lhs)
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
|
||||||
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
|
|
||||||
|
|
||||||
//! Not-Equal-to operator with arbitrary types (symmetric version)
|
//! Not-Equal-to operator with arbitrary types (symmetric version)
|
||||||
/*! \return !(rhs == lhs)
|
/*! \return !(rhs == lhs)
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
||||||
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
|
||||||
//@}
|
//@}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1172,12 +1129,16 @@ public:
|
|||||||
if (IsUint64()) {
|
if (IsUint64()) {
|
||||||
uint64_t u = GetUint64();
|
uint64_t u = GetUint64();
|
||||||
volatile double d = static_cast<double>(u);
|
volatile double d = static_cast<double>(u);
|
||||||
return (d >= 0.0) && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)())) && (u == static_cast<uint64_t>(d));
|
return (d >= 0.0)
|
||||||
|
&& (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
|
||||||
|
&& (u == static_cast<uint64_t>(d));
|
||||||
}
|
}
|
||||||
if (IsInt64()) {
|
if (IsInt64()) {
|
||||||
int64_t i = GetInt64();
|
int64_t i = GetInt64();
|
||||||
volatile double d = static_cast<double>(i);
|
volatile double d = static_cast<double>(i);
|
||||||
return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)())) && (d < static_cast<double>((std::numeric_limits<int64_t>::max)())) && (i == static_cast<int64_t>(d));
|
return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
|
||||||
|
&& (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
|
||||||
|
&& (i == static_cast<int64_t>(d));
|
||||||
}
|
}
|
||||||
return true; // double, int, uint are always lossless
|
return true; // double, int, uint are always lossless
|
||||||
}
|
}
|
||||||
@ -1193,7 +1154,8 @@ public:
|
|||||||
bool IsLosslessFloat() const {
|
bool IsLosslessFloat() const {
|
||||||
if (!IsNumber()) return false;
|
if (!IsNumber()) return false;
|
||||||
double a = GetDouble();
|
double a = GetDouble();
|
||||||
if (a < static_cast<double>(-(std::numeric_limits<float>::max)()) || a > static_cast<double>((std::numeric_limits<float>::max)()))
|
if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
|
||||||
|
|| a > static_cast<double>((std::numeric_limits<float>::max)()))
|
||||||
return false;
|
return false;
|
||||||
double b = static_cast<double>(static_cast<float>(a));
|
double b = static_cast<double>(static_cast<float>(a));
|
||||||
return a >= b && a <= b; // Prevent -Wfloat-equal
|
return a >= b && a <= b; // Prevent -Wfloat-equal
|
||||||
@ -1204,28 +1166,17 @@ public:
|
|||||||
//!@name Null
|
//!@name Null
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
GenericValue& SetNull() {
|
GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//!@name Bool
|
//!@name Bool
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
bool GetBool() const {
|
bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
|
||||||
RAPIDJSON_ASSERT(IsBool());
|
|
||||||
return data_.f.flags == kTrueFlag;
|
|
||||||
}
|
|
||||||
//!< Set boolean value
|
//!< Set boolean value
|
||||||
/*! \post IsBool() == true */
|
/*! \post IsBool() == true */
|
||||||
GenericValue& SetBool(bool b) {
|
GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(b);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@ -1234,29 +1185,16 @@ public:
|
|||||||
|
|
||||||
//! Set this value as an empty object.
|
//! Set this value as an empty object.
|
||||||
/*! \post IsObject() == true */
|
/*! \post IsObject() == true */
|
||||||
GenericValue& SetObject() {
|
GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(kObjectType);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the number of members in the object.
|
//! Get the number of members in the object.
|
||||||
SizeType MemberCount() const {
|
SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return data_.o.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the capacity of object.
|
//! Get the capacity of object.
|
||||||
SizeType MemberCapacity() const {
|
SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return data_.o.capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Check whether the object is empty.
|
//! Check whether the object is empty.
|
||||||
bool ObjectEmpty() const {
|
bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return data_.o.size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get a value from an object associated with the name.
|
//! Get a value from an object associated with the name.
|
||||||
/*! \pre IsObject() == true
|
/*! \pre IsObject() == true
|
||||||
@ -1268,14 +1206,12 @@ public:
|
|||||||
\note Linear time complexity.
|
\note Linear time complexity.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>), (GenericValue&))
|
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
|
||||||
operator[](T* name) {
|
|
||||||
GenericValue n(StringRef(name));
|
GenericValue n(StringRef(name));
|
||||||
return (*this)[n];
|
return (*this)[n];
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>), (const GenericValue&))
|
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
|
||||||
operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
|
|
||||||
|
|
||||||
//! Get a value from an object associated with the name.
|
//! Get a value from an object associated with the name.
|
||||||
/*! \pre IsObject() == true
|
/*! \pre IsObject() == true
|
||||||
@ -1314,28 +1250,16 @@ public:
|
|||||||
|
|
||||||
//! Const member iterator
|
//! Const member iterator
|
||||||
/*! \pre IsObject() == true */
|
/*! \pre IsObject() == true */
|
||||||
ConstMemberIterator MemberBegin() const {
|
ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return ConstMemberIterator(GetMembersPointer());
|
|
||||||
}
|
|
||||||
//! Const \em past-the-end member iterator
|
//! Const \em past-the-end member iterator
|
||||||
/*! \pre IsObject() == true */
|
/*! \pre IsObject() == true */
|
||||||
ConstMemberIterator MemberEnd() const {
|
ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return ConstMemberIterator(GetMembersPointer() + data_.o.size);
|
|
||||||
}
|
|
||||||
//! Member iterator
|
//! Member iterator
|
||||||
/*! \pre IsObject() == true */
|
/*! \pre IsObject() == true */
|
||||||
MemberIterator MemberBegin() {
|
MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return MemberIterator(GetMembersPointer());
|
|
||||||
}
|
|
||||||
//! \em Past-the-end member iterator
|
//! \em Past-the-end member iterator
|
||||||
/*! \pre IsObject() == true */
|
/*! \pre IsObject() == true */
|
||||||
MemberIterator MemberEnd() {
|
MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
|
||||||
return MemberIterator(GetMembersPointer() + data_.o.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Request the object to have enough capacity to store members.
|
//! Request the object to have enough capacity to store members.
|
||||||
/*! \param newCapacity The capacity that the object at least need to have.
|
/*! \param newCapacity The capacity that the object at least need to have.
|
||||||
@ -1421,8 +1345,7 @@ public:
|
|||||||
RAPIDJSON_ASSERT(name.IsString());
|
RAPIDJSON_ASSERT(name.IsString());
|
||||||
return DoFindMember(name);
|
return DoFindMember(name);
|
||||||
}
|
}
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
||||||
ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
//! Find member by string object name.
|
//! Find member by string object name.
|
||||||
@ -1687,22 +1610,10 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object GetObject() {
|
Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||||
RAPIDJSON_ASSERT(IsObject());
|
Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||||
return Object(*this);
|
ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||||
}
|
ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@ -1711,29 +1622,16 @@ public:
|
|||||||
|
|
||||||
//! Set this value as an empty array.
|
//! Set this value as an empty array.
|
||||||
/*! \post IsArray == true */
|
/*! \post IsArray == true */
|
||||||
GenericValue& SetArray() {
|
GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(kArrayType);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the number of elements in array.
|
//! Get the number of elements in array.
|
||||||
SizeType Size() const {
|
SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return data_.a.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the capacity of array.
|
//! Get the capacity of array.
|
||||||
SizeType Capacity() const {
|
SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return data_.a.capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Check whether the array is empty.
|
//! Check whether the array is empty.
|
||||||
bool Empty() const {
|
bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return data_.a.size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Remove all elements in the array.
|
//! Remove all elements in the array.
|
||||||
/*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
|
/*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
|
||||||
@ -1761,16 +1659,10 @@ public:
|
|||||||
|
|
||||||
//! Element iterator
|
//! Element iterator
|
||||||
/*! \pre IsArray() == true */
|
/*! \pre IsArray() == true */
|
||||||
ValueIterator Begin() {
|
ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return GetElementsPointer();
|
|
||||||
}
|
|
||||||
//! \em Past-the-end element iterator
|
//! \em Past-the-end element iterator
|
||||||
/*! \pre IsArray() == true */
|
/*! \pre IsArray() == true */
|
||||||
ValueIterator End() {
|
ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return GetElementsPointer() + data_.a.size;
|
|
||||||
}
|
|
||||||
//! Constant element iterator
|
//! Constant element iterator
|
||||||
/*! \pre IsArray() == true */
|
/*! \pre IsArray() == true */
|
||||||
ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
|
ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
|
||||||
@ -1899,36 +1791,18 @@ public:
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array GetArray() {
|
Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
|
||||||
return Array(*this);
|
|
||||||
}
|
|
||||||
ConstArray GetArray() const {
|
|
||||||
RAPIDJSON_ASSERT(IsArray());
|
|
||||||
return ConstArray(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//!@name Number
|
//!@name Number
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
int GetInt() const {
|
int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
|
||||||
RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);
|
unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
|
||||||
return data_.n.i.i;
|
int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
|
||||||
}
|
uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
|
||||||
unsigned GetUint() const {
|
|
||||||
RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);
|
|
||||||
return data_.n.u.u;
|
|
||||||
}
|
|
||||||
int64_t GetInt64() const {
|
|
||||||
RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag);
|
|
||||||
return data_.n.i64;
|
|
||||||
}
|
|
||||||
uint64_t GetUint64() const {
|
|
||||||
RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag);
|
|
||||||
return data_.n.u64;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the value as double type.
|
//! Get the value as double type.
|
||||||
/*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
|
/*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
|
||||||
@ -1939,8 +1813,7 @@ public:
|
|||||||
if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
|
if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
|
||||||
if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
|
if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
|
||||||
if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
|
if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
|
||||||
RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);
|
RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
|
||||||
return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get the value as float type.
|
//! Get the value as float type.
|
||||||
@ -1950,54 +1823,24 @@ public:
|
|||||||
return static_cast<float>(GetDouble());
|
return static_cast<float>(GetDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericValue& SetInt(int i) {
|
GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
|
||||||
this->~GenericValue();
|
GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
|
||||||
new (this) GenericValue(i);
|
GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
|
||||||
return *this;
|
GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
|
||||||
}
|
GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
|
||||||
GenericValue& SetUint(unsigned u) {
|
GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(u);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericValue& SetInt64(int64_t i64) {
|
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(i64);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericValue& SetUint64(uint64_t u64) {
|
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(u64);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericValue& SetDouble(double d) {
|
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericValue& SetFloat(float f) {
|
|
||||||
this->~GenericValue();
|
|
||||||
new (this) GenericValue(static_cast<double>(f));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//!@name String
|
//!@name String
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
const Ch* GetString() const {
|
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
|
||||||
RAPIDJSON_ASSERT(IsString());
|
|
||||||
return DataString(data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the length of string.
|
//! Get the length of string.
|
||||||
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
||||||
*/
|
*/
|
||||||
SizeType GetStringLength() const {
|
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
|
||||||
RAPIDJSON_ASSERT(IsString());
|
|
||||||
return DataStringLength(data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Set this value as a string without copying source string.
|
//! Set this value as a string without copying source string.
|
||||||
/*! This version has better performance with supplied length, and also support string containing null character.
|
/*! This version has better performance with supplied length, and also support string containing null character.
|
||||||
@ -2014,11 +1857,7 @@ public:
|
|||||||
\return The value itself for fluent API.
|
\return The value itself for fluent API.
|
||||||
\post IsString() == true && GetString() == s && GetStringLength() == s.length
|
\post IsString() == true && GetString() == s && GetStringLength() == s.length
|
||||||
*/
|
*/
|
||||||
GenericValue& SetString(StringRefType s) {
|
GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
SetStringRaw(s);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Set this value as a string by copying from source string.
|
//! Set this value as a string by copying from source string.
|
||||||
/*! This version has better performance with supplied length, and also support string containing null character.
|
/*! This version has better performance with supplied length, and also support string containing null character.
|
||||||
@ -2044,11 +1883,7 @@ public:
|
|||||||
\return The value itself for fluent API.
|
\return The value itself for fluent API.
|
||||||
\post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
|
\post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
|
||||||
*/
|
*/
|
||||||
GenericValue& SetString(StringRefType s, Allocator& allocator) {
|
GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
|
||||||
this->~GenericValue();
|
|
||||||
SetStringRaw(s, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
//! Set this value as a string by copying from source string.
|
//! Set this value as a string by copying from source string.
|
||||||
@ -2097,12 +1932,9 @@ public:
|
|||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
bool Accept(Handler& handler) const {
|
bool Accept(Handler& handler) const {
|
||||||
switch(GetType()) {
|
switch(GetType()) {
|
||||||
case kNullType:
|
case kNullType: return handler.Null();
|
||||||
return handler.Null();
|
case kFalseType: return handler.Bool(false);
|
||||||
case kFalseType:
|
case kTrueType: return handler.Bool(true);
|
||||||
return handler.Bool(false);
|
|
||||||
case kTrueType:
|
|
||||||
return handler.Bool(true);
|
|
||||||
|
|
||||||
case kObjectType:
|
case kObjectType:
|
||||||
if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
|
if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
|
||||||
@ -2129,24 +1961,17 @@ public:
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
RAPIDJSON_ASSERT(GetType() == kNumberType);
|
RAPIDJSON_ASSERT(GetType() == kNumberType);
|
||||||
if (IsDouble())
|
if (IsDouble()) return handler.Double(data_.n.d);
|
||||||
return handler.Double(data_.n.d);
|
else if (IsInt()) return handler.Int(data_.n.i.i);
|
||||||
else if (IsInt())
|
else if (IsUint()) return handler.Uint(data_.n.u.u);
|
||||||
return handler.Int(data_.n.i.i);
|
else if (IsInt64()) return handler.Int64(data_.n.i64);
|
||||||
else if (IsUint())
|
else return handler.Uint64(data_.n.u64);
|
||||||
return handler.Uint(data_.n.u.u);
|
|
||||||
else if (IsInt64())
|
|
||||||
return handler.Int64(data_.n.i64);
|
|
||||||
else
|
|
||||||
return handler.Uint64(data_.n.u64);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename, typename>
|
template <typename, typename> friend class GenericValue;
|
||||||
friend class GenericValue;
|
template <typename, typename, typename> friend class GenericDocument;
|
||||||
template <typename, typename, typename>
|
|
||||||
friend class GenericDocument;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kBoolFlag = 0x0008,
|
kBoolFlag = 0x0008,
|
||||||
@ -2209,9 +2034,7 @@ private:
|
|||||||
// This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
|
// This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
|
||||||
// 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
|
// 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
|
||||||
struct ShortString {
|
struct ShortString {
|
||||||
enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch),
|
enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
|
||||||
MaxSize = MaxChars - 1,
|
|
||||||
LenPos = MaxSize };
|
|
||||||
Ch str[MaxChars];
|
Ch str[MaxChars];
|
||||||
|
|
||||||
inline static bool Usable(SizeType len) { return (MaxSize >= len); }
|
inline static bool Usable(SizeType len) { return (MaxSize >= len); }
|
||||||
@ -2607,8 +2430,7 @@ private:
|
|||||||
data_.f.flags = kShortStringFlag;
|
data_.f.flags = kShortStringFlag;
|
||||||
data_.ss.SetLength(s.length);
|
data_.ss.SetLength(s.length);
|
||||||
str = data_.ss.str;
|
str = data_.ss.str;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
data_.f.flags = kCopyStringFlag;
|
data_.f.flags = kCopyStringFlag;
|
||||||
data_.s.length = s.length;
|
data_.s.length = s.length;
|
||||||
str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
|
str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
|
||||||
@ -2672,7 +2494,9 @@ public:
|
|||||||
\param stackCapacity Optional initial capacity of stack in bytes.
|
\param stackCapacity Optional initial capacity of stack in bytes.
|
||||||
\param stackAllocator Optional allocator for allocating memory for stack.
|
\param stackAllocator Optional allocator for allocating memory for stack.
|
||||||
*/
|
*/
|
||||||
explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() {
|
explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
|
||||||
|
GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
|
||||||
|
{
|
||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||||
}
|
}
|
||||||
@ -2683,7 +2507,9 @@ public:
|
|||||||
\param stackCapacity Optional initial capacity of stack in bytes.
|
\param stackCapacity Optional initial capacity of stack in bytes.
|
||||||
\param stackAllocator Optional allocator for allocating memory for stack.
|
\param stackAllocator Optional allocator for allocating memory for stack.
|
||||||
*/
|
*/
|
||||||
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() {
|
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
|
||||||
|
allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
|
||||||
|
{
|
||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||||
}
|
}
|
||||||
@ -2695,7 +2521,8 @@ public:
|
|||||||
allocator_(rhs.allocator_),
|
allocator_(rhs.allocator_),
|
||||||
ownAllocator_(rhs.ownAllocator_),
|
ownAllocator_(rhs.ownAllocator_),
|
||||||
stack_(std::move(rhs.stack_)),
|
stack_(std::move(rhs.stack_)),
|
||||||
parseResult_(rhs.parseResult_) {
|
parseResult_(rhs.parseResult_)
|
||||||
|
{
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
rhs.parseResult_ = ParseResult();
|
rhs.parseResult_ = ParseResult();
|
||||||
@ -2715,7 +2542,8 @@ public:
|
|||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
//! Move assignment in C++11
|
//! Move assignment in C++11
|
||||||
GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT {
|
GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
{
|
||||||
// The cast to ValueType is necessary here, because otherwise it would
|
// The cast to ValueType is necessary here, because otherwise it would
|
||||||
// attempt to call GenericValue's templated assignment operator.
|
// attempt to call GenericValue's templated assignment operator.
|
||||||
ValueType::operator=(std::forward<ValueType>(rhs));
|
ValueType::operator=(std::forward<ValueType>(rhs));
|
||||||
@ -2961,7 +2789,6 @@ private:
|
|||||||
struct ClearStackOnExit {
|
struct ClearStackOnExit {
|
||||||
explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
|
explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
|
||||||
~ClearStackOnExit() { d_.ClearStack(); }
|
~ClearStackOnExit() { d_.ClearStack(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClearStackOnExit(const ClearStackOnExit&);
|
ClearStackOnExit(const ClearStackOnExit&);
|
||||||
ClearStackOnExit& operator=(const ClearStackOnExit&);
|
ClearStackOnExit& operator=(const ClearStackOnExit&);
|
||||||
@ -2970,39 +2797,17 @@ private:
|
|||||||
|
|
||||||
// callers of the following private Handler functions
|
// callers of the following private Handler functions
|
||||||
// template <typename,typename,typename> friend class GenericReader; // for parsing
|
// template <typename,typename,typename> friend class GenericReader; // for parsing
|
||||||
template <typename, typename>
|
template <typename, typename> friend class GenericValue; // for deep copying
|
||||||
friend class GenericValue; // for deep copying
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Implementation of Handler
|
// Implementation of Handler
|
||||||
bool Null() {
|
bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
|
||||||
new (stack_.template Push<ValueType>()) ValueType();
|
bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
|
||||||
return true;
|
bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
|
||||||
}
|
bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
|
||||||
bool Bool(bool b) {
|
bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
|
||||||
new (stack_.template Push<ValueType>()) ValueType(b);
|
bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
|
||||||
return true;
|
bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
|
||||||
}
|
|
||||||
bool Int(int i) {
|
|
||||||
new (stack_.template Push<ValueType>()) ValueType(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Uint(unsigned i) {
|
|
||||||
new (stack_.template Push<ValueType>()) ValueType(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Int64(int64_t i) {
|
|
||||||
new (stack_.template Push<ValueType>()) ValueType(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Uint64(uint64_t i) {
|
|
||||||
new (stack_.template Push<ValueType>()) ValueType(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Double(double d) {
|
|
||||||
new (stack_.template Push<ValueType>()) ValueType(d);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy) {
|
bool RawNumber(const Ch* str, SizeType length, bool copy) {
|
||||||
if (copy)
|
if (copy)
|
||||||
@ -3020,10 +2825,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartObject() {
|
bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
|
||||||
new (stack_.template Push<ValueType>()) ValueType(kObjectType);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
|
bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
|
||||||
|
|
||||||
@ -3033,10 +2835,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartArray() {
|
bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
|
||||||
new (stack_.template Push<ValueType>()) ValueType(kArrayType);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EndArray(SizeType elementCount) {
|
bool EndArray(SizeType elementCount) {
|
||||||
ValueType* elements = stack_.template Pop<ValueType>(elementCount);
|
ValueType* elements = stack_.template Pop<ValueType>(elementCount);
|
||||||
@ -3095,10 +2894,7 @@ public:
|
|||||||
friend class GenericValue;
|
friend class GenericValue;
|
||||||
|
|
||||||
GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
|
GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
|
||||||
GenericArray& operator=(const GenericArray& rhs) {
|
GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
|
||||||
value_ = rhs.value_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~GenericArray() {}
|
~GenericArray() {}
|
||||||
|
|
||||||
operator ValueType&() const { return value_; }
|
operator ValueType&() const { return value_; }
|
||||||
@ -3109,34 +2905,14 @@ public:
|
|||||||
ValueType& operator[](SizeType index) const { return value_[index]; }
|
ValueType& operator[](SizeType index) const { return value_[index]; }
|
||||||
ValueIterator Begin() const { return value_.Begin(); }
|
ValueIterator Begin() const { return value_.Begin(); }
|
||||||
ValueIterator End() const { return value_.End(); }
|
ValueIterator End() const { return value_.End(); }
|
||||||
GenericArray Reserve(SizeType newCapacity, AllocatorType& allocator) const {
|
GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
|
||||||
value_.Reserve(newCapacity, allocator);
|
GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericArray PushBack(ValueType& value, AllocatorType& allocator) const {
|
|
||||||
value_.PushBack(value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const {
|
GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
|
||||||
value_.PushBack(value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
GenericArray PushBack(StringRefType value, AllocatorType& allocator) const {
|
GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
|
||||||
value_.PushBack(value, allocator);
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
|
||||||
return *this;
|
GenericArray PopBack() const { value_.PopBack(); return *this; }
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (const GenericArray&))
|
|
||||||
PushBack(T value, AllocatorType& allocator) const {
|
|
||||||
value_.PushBack(value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericArray PopBack() const {
|
|
||||||
value_.PopBack();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
|
ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
|
||||||
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
|
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
|
||||||
|
|
||||||
@ -3174,100 +2950,52 @@ public:
|
|||||||
friend class GenericValue;
|
friend class GenericValue;
|
||||||
|
|
||||||
GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
|
GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
|
||||||
GenericObject& operator=(const GenericObject& rhs) {
|
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
||||||
value_ = rhs.value_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~GenericObject() {}
|
~GenericObject() {}
|
||||||
|
|
||||||
operator ValueType&() const { return value_; }
|
operator ValueType&() const { return value_; }
|
||||||
SizeType MemberCount() const { return value_.MemberCount(); }
|
SizeType MemberCount() const { return value_.MemberCount(); }
|
||||||
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
||||||
bool ObjectEmpty() const { return value_.ObjectEmpty(); }
|
bool ObjectEmpty() const { return value_.ObjectEmpty(); }
|
||||||
template <typename T>
|
template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
|
||||||
ValueType& operator[](T* name) const { return value_[name]; }
|
template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
|
||||||
template <typename SourceAllocator>
|
|
||||||
ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
|
ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
|
||||||
#endif
|
#endif
|
||||||
MemberIterator MemberBegin() const { return value_.MemberBegin(); }
|
MemberIterator MemberBegin() const { return value_.MemberBegin(); }
|
||||||
MemberIterator MemberEnd() const { return value_.MemberEnd(); }
|
MemberIterator MemberEnd() const { return value_.MemberEnd(); }
|
||||||
GenericObject MemberReserve(SizeType newCapacity, AllocatorType& allocator) const {
|
GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
|
||||||
value_.MemberReserve(newCapacity, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
bool HasMember(const Ch* name) const { return value_.HasMember(name); }
|
bool HasMember(const Ch* name) const { return value_.HasMember(name); }
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
|
bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
|
||||||
#endif
|
#endif
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
|
||||||
bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
|
|
||||||
MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
|
MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
|
||||||
MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
|
MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
|
||||||
#endif
|
#endif
|
||||||
GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const {
|
GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
value_.AddMember(name, value, allocator);
|
GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const {
|
GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
template <typename T>
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
|
|
||||||
AddMember(ValueType& name, T value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const {
|
GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
value_.AddMember(name, value, allocator);
|
GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
return *this;
|
GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
}
|
GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const {
|
GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
value_.AddMember(name, value, allocator);
|
GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
return *this;
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
|
||||||
}
|
|
||||||
GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (GenericObject))
|
|
||||||
AddMember(StringRefType name, T value, AllocatorType& allocator) const {
|
|
||||||
value_.AddMember(name, value, allocator);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
void RemoveAllMembers() { value_.RemoveAllMembers(); }
|
void RemoveAllMembers() { value_.RemoveAllMembers(); }
|
||||||
bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
|
bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
|
bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
|
||||||
#endif
|
#endif
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
|
||||||
bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
|
|
||||||
MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
|
MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
|
||||||
MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
|
MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
|
||||||
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
|
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
|
||||||
@ -3275,8 +3003,7 @@ public:
|
|||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
|
bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
|
||||||
#endif
|
#endif
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
|
||||||
bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
|
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||||
MemberIterator begin() const { return value_.MemberBegin(); }
|
MemberIterator begin() const { return value_.MemberBegin(); }
|
||||||
|
@ -38,7 +38,6 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
template <typename Encoding, typename InputByteStream>
|
template <typename Encoding, typename InputByteStream>
|
||||||
class EncodedInputStream {
|
class EncodedInputStream {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
@ -47,24 +46,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ch Peek() const { return current_; }
|
Ch Peek() const { return current_; }
|
||||||
Ch Take() {
|
Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
|
||||||
Ch c = current_;
|
|
||||||
current_ = Encoding::Take(is_);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
size_t Tell() const { return is_.Tell(); }
|
size_t Tell() const { return is_.Tell(); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EncodedInputStream(const EncodedInputStream&);
|
EncodedInputStream(const EncodedInputStream&);
|
||||||
@ -110,7 +99,6 @@ private:
|
|||||||
template <typename Encoding, typename OutputByteStream>
|
template <typename Encoding, typename OutputByteStream>
|
||||||
class EncodedOutputStream {
|
class EncodedOutputStream {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
@ -123,26 +111,11 @@ public:
|
|||||||
void Flush() { os_.Flush(); }
|
void Flush() { os_.Flush(); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
Ch Peek() const {
|
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
RAPIDJSON_ASSERT(false);
|
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
return 0;
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
}
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
Ch Take() {
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t Tell() const {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Ch* PutBegin() {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EncodedOutputStream(const EncodedOutputStream&);
|
EncodedOutputStream(const EncodedOutputStream&);
|
||||||
@ -161,7 +134,6 @@ private:
|
|||||||
template <typename CharType, typename InputByteStream>
|
template <typename CharType, typename InputByteStream>
|
||||||
class AutoUTFInputStream {
|
class AutoUTFInputStream {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef CharType Ch;
|
typedef CharType Ch;
|
||||||
|
|
||||||
@ -182,24 +154,14 @@ public:
|
|||||||
bool HasBOM() const { return hasBOM_; }
|
bool HasBOM() const { return hasBOM_; }
|
||||||
|
|
||||||
Ch Peek() const { return current_; }
|
Ch Peek() const { return current_; }
|
||||||
Ch Take() {
|
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
|
||||||
Ch c = current_;
|
|
||||||
current_ = takeFunc_(*is_);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
size_t Tell() const { return is_->Tell(); }
|
size_t Tell() const { return is_->Tell(); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoUTFInputStream(const AutoUTFInputStream&);
|
AutoUTFInputStream(const AutoUTFInputStream&);
|
||||||
@ -220,41 +182,11 @@ private:
|
|||||||
|
|
||||||
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
||||||
hasBOM_ = false;
|
hasBOM_ = false;
|
||||||
if (bom == 0xFFFE0000) {
|
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||||
type_ = kUTF32BE;
|
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||||
hasBOM_ = true;
|
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
||||||
is_->Take();
|
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
||||||
is_->Take();
|
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
}
|
|
||||||
else if (bom == 0x0000FEFF) {
|
|
||||||
type_ = kUTF32LE;
|
|
||||||
hasBOM_ = true;
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
}
|
|
||||||
else if ((bom & 0xFFFF) == 0xFFFE) {
|
|
||||||
type_ = kUTF16BE;
|
|
||||||
hasBOM_ = true;
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
}
|
|
||||||
else if ((bom & 0xFFFF) == 0xFEFF) {
|
|
||||||
type_ = kUTF16LE;
|
|
||||||
hasBOM_ = true;
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
}
|
|
||||||
else if ((bom & 0xFFFFFF) == 0xBFBBEF) {
|
|
||||||
type_ = kUTF8;
|
|
||||||
hasBOM_ = true;
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
is_->Take();
|
|
||||||
}
|
|
||||||
|
|
||||||
// RFC 4627: Section 3
|
// RFC 4627: Section 3
|
||||||
// "Since the first two characters of a JSON text will always be ASCII
|
// "Since the first two characters of a JSON text will always be ASCII
|
||||||
@ -270,23 +202,12 @@ private:
|
|||||||
if (!hasBOM_) {
|
if (!hasBOM_) {
|
||||||
int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
||||||
switch (pattern) {
|
switch (pattern) {
|
||||||
case 0x08:
|
case 0x08: type_ = kUTF32BE; break;
|
||||||
type_ = kUTF32BE;
|
case 0x0A: type_ = kUTF16BE; break;
|
||||||
break;
|
case 0x01: type_ = kUTF32LE; break;
|
||||||
case 0x0A:
|
case 0x05: type_ = kUTF16LE; break;
|
||||||
type_ = kUTF16BE;
|
case 0x0F: type_ = kUTF8; break;
|
||||||
break;
|
default: break; // Use type defined by user.
|
||||||
case 0x01:
|
|
||||||
type_ = kUTF32LE;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
type_ = kUTF16LE;
|
|
||||||
break;
|
|
||||||
case 0x0F:
|
|
||||||
type_ = kUTF8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break; // Use type defined by user.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +232,6 @@ private:
|
|||||||
template <typename CharType, typename OutputByteStream>
|
template <typename CharType, typename OutputByteStream>
|
||||||
class AutoUTFOutputStream {
|
class AutoUTFOutputStream {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef CharType Ch;
|
typedef CharType Ch;
|
||||||
|
|
||||||
@ -341,26 +261,11 @@ public:
|
|||||||
void Flush() { os_->Flush(); }
|
void Flush() { os_->Flush(); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
Ch Peek() const {
|
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
RAPIDJSON_ASSERT(false);
|
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
return 0;
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
}
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
Ch Take() {
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t Tell() const {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Ch* PutBegin() {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
||||||
|
@ -144,13 +144,9 @@ struct UTF8 {
|
|||||||
|
|
||||||
template <typename InputStream>
|
template <typename InputStream>
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||||
#define RAPIDJSON_COPY() \
|
#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
||||||
c = is.Take(); \
|
|
||||||
*codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
|
||||||
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
||||||
#define RAPIDJSON_TAIL() \
|
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
||||||
RAPIDJSON_COPY(); \
|
|
||||||
RAPIDJSON_TRANS(0x70)
|
|
||||||
typename InputStream::Ch c = is.Take();
|
typename InputStream::Ch c = is.Take();
|
||||||
if (!(c & 0x80)) {
|
if (!(c & 0x80)) {
|
||||||
*codepoint = static_cast<unsigned char>(c);
|
*codepoint = static_cast<unsigned char>(c);
|
||||||
@ -160,48 +156,19 @@ struct UTF8 {
|
|||||||
unsigned char type = GetRange(static_cast<unsigned char>(c));
|
unsigned char type = GetRange(static_cast<unsigned char>(c));
|
||||||
if (type >= 32) {
|
if (type >= 32) {
|
||||||
*codepoint = 0;
|
*codepoint = 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
*codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
|
*codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
|
||||||
}
|
}
|
||||||
bool result = true;
|
bool result = true;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 2:
|
case 2: RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
return result;
|
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
||||||
case 3:
|
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
||||||
return result;
|
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 4:
|
default: return false;
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x50);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 5:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x10);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 6:
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 10:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x20);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 11:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x60);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#undef RAPIDJSON_COPY
|
#undef RAPIDJSON_COPY
|
||||||
#undef RAPIDJSON_TRANS
|
#undef RAPIDJSON_TRANS
|
||||||
@ -212,9 +179,7 @@ struct UTF8 {
|
|||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
static bool Validate(InputStream& is, OutputStream& os) {
|
||||||
#define RAPIDJSON_COPY() os.Put(c = is.Take())
|
#define RAPIDJSON_COPY() os.Put(c = is.Take())
|
||||||
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
||||||
#define RAPIDJSON_TAIL() \
|
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
||||||
RAPIDJSON_COPY(); \
|
|
||||||
RAPIDJSON_TRANS(0x70)
|
|
||||||
Ch c;
|
Ch c;
|
||||||
RAPIDJSON_COPY();
|
RAPIDJSON_COPY();
|
||||||
if (!(c & 0x80))
|
if (!(c & 0x80))
|
||||||
@ -222,42 +187,14 @@ struct UTF8 {
|
|||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
switch (GetRange(static_cast<unsigned char>(c))) {
|
switch (GetRange(static_cast<unsigned char>(c))) {
|
||||||
case 2:
|
case 2: RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
return result;
|
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
||||||
case 3:
|
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
RAPIDJSON_TAIL();
|
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
||||||
return result;
|
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 4:
|
default: return false;
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x50);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 5:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x10);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 6:
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 10:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x20);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
case 11:
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
RAPIDJSON_TRANS(0x60);
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
RAPIDJSON_TAIL();
|
|
||||||
return result;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#undef RAPIDJSON_COPY
|
#undef RAPIDJSON_COPY
|
||||||
#undef RAPIDJSON_TRANS
|
#undef RAPIDJSON_TRANS
|
||||||
@ -268,262 +205,16 @@ struct UTF8 {
|
|||||||
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||||
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
|
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
|
||||||
static const unsigned char type[] = {
|
static const unsigned char type[] = {
|
||||||
0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,
|
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
|
||||||
0,
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||||
0,
|
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||||
0,
|
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||||
0,
|
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||||
0,
|
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x10,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x40,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
0x20,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
10,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
11,
|
|
||||||
6,
|
|
||||||
6,
|
|
||||||
6,
|
|
||||||
5,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
};
|
};
|
||||||
return type[c];
|
return type[c];
|
||||||
}
|
}
|
||||||
|
@ -35,52 +35,33 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
*/
|
*/
|
||||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
|
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
|
||||||
switch (parseErrorCode) {
|
switch (parseErrorCode) {
|
||||||
case kParseErrorNone:
|
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||||
return RAPIDJSON_ERROR_STRING("No error.");
|
|
||||||
|
|
||||||
case kParseErrorDocumentEmpty:
|
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
||||||
return RAPIDJSON_ERROR_STRING("The document is empty.");
|
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
||||||
case kParseErrorDocumentRootNotSingular:
|
|
||||||
return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
|
||||||
|
|
||||||
case kParseErrorValueInvalid:
|
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||||
return RAPIDJSON_ERROR_STRING("Invalid value.");
|
|
||||||
|
|
||||||
case kParseErrorObjectMissName:
|
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
||||||
return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
||||||
case kParseErrorObjectMissColon:
|
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
||||||
return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
|
||||||
case kParseErrorObjectMissCommaOrCurlyBracket:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
|
||||||
|
|
||||||
case kParseErrorArrayMissCommaOrSquareBracket:
|
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
||||||
return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
|
||||||
|
|
||||||
case kParseErrorStringUnicodeEscapeInvalidHex:
|
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
||||||
return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
|
||||||
case kParseErrorStringUnicodeSurrogateInvalid:
|
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
|
||||||
return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
|
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
|
||||||
case kParseErrorStringEscapeInvalid:
|
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
|
||||||
return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
|
|
||||||
case kParseErrorStringMissQuotationMark:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
|
|
||||||
case kParseErrorStringInvalidEncoding:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
|
|
||||||
|
|
||||||
case kParseErrorNumberTooBig:
|
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
|
||||||
return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
|
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
|
||||||
case kParseErrorNumberMissFraction:
|
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
|
||||||
return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
|
|
||||||
case kParseErrorNumberMissExponent:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
|
|
||||||
|
|
||||||
case kParseErrorTermination:
|
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
||||||
return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
||||||
case kParseErrorUnspecificSyntaxError:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
|
||||||
|
|
||||||
default:
|
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,69 +75,41 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
|||||||
*/
|
*/
|
||||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) {
|
inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) {
|
||||||
switch (validateErrorCode) {
|
switch (validateErrorCode) {
|
||||||
case kValidateErrors:
|
case kValidateErrors: return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred");
|
||||||
return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred");
|
case kValidateErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||||
case kValidateErrorNone:
|
|
||||||
return RAPIDJSON_ERROR_STRING("No error.");
|
|
||||||
|
|
||||||
case kValidateErrorMultipleOf:
|
case kValidateErrorMultipleOf: return RAPIDJSON_ERROR_STRING("Number '%actual' is not a multiple of the 'multipleOf' value '%expected'.");
|
||||||
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 kValidateErrorMaximum:
|
case kValidateErrorExclusiveMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than or equal to the 'exclusiveMaximum' value '%expected'.");
|
||||||
return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than the 'maximum' value '%expected'.");
|
case kValidateErrorMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than the 'minimum' value '%expected'.");
|
||||||
case kValidateErrorExclusiveMaximum:
|
case kValidateErrorExclusiveMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than or equal to the 'exclusiveMinimum' value '%expected'.");
|
||||||
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:
|
case kValidateErrorMaxLength: return RAPIDJSON_ERROR_STRING("String '%actual' is longer than the 'maxLength' value '%expected'.");
|
||||||
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 kValidateErrorMinLength:
|
case kValidateErrorPattern: return RAPIDJSON_ERROR_STRING("String '%actual' does not match the 'pattern' regular expression.");
|
||||||
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:
|
case kValidateErrorMaxItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is longer than the 'maxItems' value '%expected'.");
|
||||||
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 kValidateErrorMinItems:
|
case kValidateErrorUniqueItems: return RAPIDJSON_ERROR_STRING("Array has duplicate items at indices '%duplicates' but 'uniqueItems' is true.");
|
||||||
return RAPIDJSON_ERROR_STRING("Array of length '%actual' is shorter than the 'minItems' value '%expected'.");
|
case kValidateErrorAdditionalItems: return RAPIDJSON_ERROR_STRING("Array has an additional item at index '%disallowed' that is not allowed by the schema.");
|
||||||
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:
|
case kValidateErrorMaxProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is more than 'maxProperties' value '%expected'.");
|
||||||
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 kValidateErrorMinProperties:
|
case kValidateErrorRequired: return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'.");
|
||||||
return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is less than 'minProperties' value '%expected'.");
|
case kValidateErrorAdditionalProperties: return RAPIDJSON_ERROR_STRING("Object has an additional member '%disallowed' that is not allowed by the schema.");
|
||||||
case kValidateErrorRequired:
|
case kValidateErrorPatternProperties: return RAPIDJSON_ERROR_STRING("Object has 'patternProperties' that are not allowed by the schema.");
|
||||||
return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'.");
|
case kValidateErrorDependencies: return RAPIDJSON_ERROR_STRING("Object has missing property or schema dependencies, refer to following errors.");
|
||||||
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:
|
case kValidateErrorEnum: return RAPIDJSON_ERROR_STRING("Property has a value that is not one of its allowed enumerated values.");
|
||||||
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 kValidateErrorType:
|
|
||||||
return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
|
||||||
|
|
||||||
case kValidateErrorOneOf:
|
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
||||||
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 kValidateErrorOneOfMatch:
|
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
||||||
return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
|
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
||||||
case kValidateErrorAllOf:
|
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
||||||
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:
|
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,6 @@ enum ParseErrorCode {
|
|||||||
struct ParseResult {
|
struct ParseResult {
|
||||||
//!! Unspecified boolean type
|
//!! Unspecified boolean type
|
||||||
typedef bool (ParseResult::*BooleanType)() const;
|
typedef bool (ParseResult::*BooleanType)() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Default constructor, no error.
|
//! Default constructor, no error.
|
||||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
||||||
@ -134,10 +133,7 @@ public:
|
|||||||
//! Reset error code.
|
//! Reset error code.
|
||||||
void Clear() { Set(kParseErrorNone); }
|
void Clear() { Set(kParseErrorNone); }
|
||||||
//! Update error code and offset.
|
//! Update error code and offset.
|
||||||
void Set(ParseErrorCode code, size_t offset = 0) {
|
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
|
||||||
code_ = code;
|
|
||||||
offset_ = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParseErrorCode code_;
|
ParseErrorCode code_;
|
||||||
|
@ -48,24 +48,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ch Peek() const { return *current_; }
|
Ch Peek() const { return *current_; }
|
||||||
Ch Take() {
|
Ch Take() { Ch c = *current_; Read(); return c; }
|
||||||
Ch c = *current_;
|
|
||||||
Read();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
|
@ -72,26 +72,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
char Peek() const {
|
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
}
|
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
char Take() {
|
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t Tell() const {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char* PutBegin() {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(char*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Prohibit copy constructor & assignment operator.
|
// Prohibit copy constructor & assignment operator.
|
||||||
|
@ -21,24 +21,15 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
// encodings.h
|
// encodings.h
|
||||||
|
|
||||||
template <typename CharType>
|
template<typename CharType> struct UTF8;
|
||||||
struct UTF8;
|
template<typename CharType> struct UTF16;
|
||||||
template <typename CharType>
|
template<typename CharType> struct UTF16BE;
|
||||||
struct UTF16;
|
template<typename CharType> struct UTF16LE;
|
||||||
template <typename CharType>
|
template<typename CharType> struct UTF32;
|
||||||
struct UTF16BE;
|
template<typename CharType> struct UTF32BE;
|
||||||
template <typename CharType>
|
template<typename CharType> struct UTF32LE;
|
||||||
struct UTF16LE;
|
template<typename CharType> struct ASCII;
|
||||||
template <typename CharType>
|
template<typename CharType> struct AutoUTF;
|
||||||
struct UTF32;
|
|
||||||
template <typename CharType>
|
|
||||||
struct UTF32BE;
|
|
||||||
template <typename CharType>
|
|
||||||
struct UTF32LE;
|
|
||||||
template <typename CharType>
|
|
||||||
struct ASCII;
|
|
||||||
template <typename CharType>
|
|
||||||
struct AutoUTF;
|
|
||||||
|
|
||||||
template<typename SourceEncoding, typename TargetEncoding>
|
template<typename SourceEncoding, typename TargetEncoding>
|
||||||
struct Transcoder;
|
struct Transcoder;
|
||||||
|
@ -52,7 +52,8 @@ namespace internal {
|
|||||||
AppendDecimal64(decimals + i, decimals + i + length);
|
AppendDecimal64(decimals + i, decimals + i + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger& operator=(const BigInteger& rhs) {
|
BigInteger& operator=(const BigInteger &rhs)
|
||||||
|
{
|
||||||
if (this != &rhs) {
|
if (this != &rhs) {
|
||||||
count_ = rhs.count_;
|
count_ = rhs.count_;
|
||||||
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
|
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
|
||||||
@ -187,16 +188,8 @@ namespace internal {
|
|||||||
RAPIDJSON_ASSERT(cmp != 0);
|
RAPIDJSON_ASSERT(cmp != 0);
|
||||||
const BigInteger *a, *b; // Makes a > b
|
const BigInteger *a, *b; // Makes a > b
|
||||||
bool ret;
|
bool ret;
|
||||||
if (cmp < 0) {
|
if (cmp < 0) { a = &rhs; b = this; ret = true; }
|
||||||
a = &rhs;
|
else { a = this; b = &rhs; ret = false; }
|
||||||
b = this;
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
a = this;
|
|
||||||
b = &rhs;
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type borrow = 0;
|
Type borrow = 0;
|
||||||
for (size_t i = 0; i < a->count_; i++) {
|
for (size_t i = 0; i < a->count_; i++) {
|
||||||
@ -224,10 +217,7 @@ namespace internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t GetCount() const { return count_; }
|
size_t GetCount() const { return count_; }
|
||||||
Type GetDigit(size_t index) const {
|
Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }
|
||||||
RAPIDJSON_ASSERT(index < count_);
|
|
||||||
return digits_[index];
|
|
||||||
}
|
|
||||||
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
|
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -138,7 +138,8 @@ namespace internal {
|
|||||||
// Overflow.
|
// Overflow.
|
||||||
return std::numeric_limits<double>::infinity();
|
return std::numeric_limits<double>::infinity();
|
||||||
}
|
}
|
||||||
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : static_cast<uint64_t>(e + kDpExponentBias);
|
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
|
||||||
|
static_cast<uint64_t>(e + kDpExponentBias);
|
||||||
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
||||||
return u.d;
|
return u.d;
|
||||||
}
|
}
|
||||||
|
@ -69,42 +69,15 @@ namespace internal {
|
|||||||
while (kappa > 0) {
|
while (kappa > 0) {
|
||||||
uint32_t d = 0;
|
uint32_t d = 0;
|
||||||
switch (kappa) {
|
switch (kappa) {
|
||||||
case 9:
|
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
||||||
d = p1 / 100000000;
|
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
||||||
p1 %= 100000000;
|
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
||||||
break;
|
case 6: d = p1 / 100000; p1 %= 100000; break;
|
||||||
case 8:
|
case 5: d = p1 / 10000; p1 %= 10000; break;
|
||||||
d = p1 / 10000000;
|
case 4: d = p1 / 1000; p1 %= 1000; break;
|
||||||
p1 %= 10000000;
|
case 3: d = p1 / 100; p1 %= 100; break;
|
||||||
break;
|
case 2: d = p1 / 10; p1 %= 10; break;
|
||||||
case 7:
|
case 1: d = p1; p1 = 0; break;
|
||||||
d = p1 / 1000000;
|
|
||||||
p1 %= 1000000;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
d = p1 / 100000;
|
|
||||||
p1 %= 100000;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
d = p1 / 10000;
|
|
||||||
p1 %= 10000;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
d = p1 / 1000;
|
|
||||||
p1 %= 1000;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
d = p1 / 100;
|
|
||||||
p1 %= 100;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
d = p1 / 10;
|
|
||||||
p1 %= 10;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
d = p1;
|
|
||||||
p1 = 0;
|
|
||||||
break;
|
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
if (d || *len)
|
if (d || *len)
|
||||||
|
@ -36,14 +36,12 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
|
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
|
||||||
template <typename T>
|
template <typename T> struct Void { typedef void Type; };
|
||||||
struct Void { typedef void Type; };
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// BoolType, TrueType, FalseType
|
// BoolType, TrueType, FalseType
|
||||||
//
|
//
|
||||||
template <bool Cond>
|
template <bool Cond> struct BoolType {
|
||||||
struct BoolType {
|
|
||||||
static const bool Value = Cond;
|
static const bool Value = Cond;
|
||||||
typedef BoolType Type;
|
typedef BoolType Type;
|
||||||
};
|
};
|
||||||
@ -55,88 +53,58 @@ namespace internal {
|
|||||||
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
|
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
|
||||||
//
|
//
|
||||||
|
|
||||||
template <bool C>
|
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
|
||||||
struct SelectIfImpl {
|
template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
|
||||||
template <typename T1, typename T2>
|
template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
|
||||||
struct Apply { typedef T1 Type; };
|
template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct SelectIfImpl<false> {
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct Apply { typedef T2 Type; };
|
|
||||||
};
|
|
||||||
template <bool C, typename T1, typename T2>
|
|
||||||
struct SelectIfCond : SelectIfImpl<C>::template Apply<T1, T2> {};
|
|
||||||
template <typename C, typename T1, typename T2>
|
|
||||||
struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
|
|
||||||
|
|
||||||
template <bool Cond1, bool Cond2>
|
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
|
||||||
struct AndExprCond : FalseType {};
|
template <> struct AndExprCond<true, true> : TrueType {};
|
||||||
template <>
|
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
|
||||||
struct AndExprCond<true, true> : TrueType {};
|
template <> struct OrExprCond<false, false> : FalseType {};
|
||||||
template <bool Cond1, bool Cond2>
|
|
||||||
struct OrExprCond : TrueType {};
|
|
||||||
template <>
|
|
||||||
struct OrExprCond<false, false> : FalseType {};
|
|
||||||
|
|
||||||
template <typename C>
|
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
|
||||||
struct BoolExpr : SelectIf<C, TrueType, FalseType>::Type {};
|
template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
|
||||||
template <typename C>
|
template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
|
||||||
struct NotExpr : SelectIf<C, FalseType, TrueType>::Type {};
|
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
|
||||||
template <typename C1, typename C2>
|
|
||||||
struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
|
|
||||||
template <typename C1, typename C2>
|
|
||||||
struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// AddConst, MaybeAddConst, RemoveConst
|
// AddConst, MaybeAddConst, RemoveConst
|
||||||
template <typename T>
|
template <typename T> struct AddConst { typedef const T Type; };
|
||||||
struct AddConst { typedef const T Type; };
|
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
||||||
template <bool Constify, typename T>
|
template <typename T> struct RemoveConst { typedef T Type; };
|
||||||
struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
||||||
template <typename T>
|
|
||||||
struct RemoveConst { typedef T Type; };
|
|
||||||
template <typename T>
|
|
||||||
struct RemoveConst<const T> { typedef T Type; };
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// IsSame, IsConst, IsMoreConst, IsPointer
|
// IsSame, IsConst, IsMoreConst, IsPointer
|
||||||
//
|
//
|
||||||
template <typename T, typename U>
|
template <typename T, typename U> struct IsSame : FalseType {};
|
||||||
struct IsSame : FalseType {};
|
template <typename T> struct IsSame<T, T> : TrueType {};
|
||||||
template <typename T>
|
|
||||||
struct IsSame<T, T> : TrueType {};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct IsConst : FalseType {};
|
||||||
struct IsConst : FalseType {};
|
template <typename T> struct IsConst<const T> : TrueType {};
|
||||||
template <typename T>
|
|
||||||
struct IsConst<const T> : TrueType {};
|
|
||||||
|
|
||||||
template <typename CT, typename T>
|
template <typename CT, typename T>
|
||||||
struct IsMoreConst
|
struct IsMoreConst
|
||||||
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
|
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
|
||||||
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
|
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct IsPointer : FalseType {};
|
||||||
struct IsPointer : FalseType {};
|
template <typename T> struct IsPointer<T*> : TrueType {};
|
||||||
template <typename T>
|
|
||||||
struct IsPointer<T*> : TrueType {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// IsBaseOf
|
// IsBaseOf
|
||||||
//
|
//
|
||||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
|
|
||||||
template <typename B, typename D>
|
template <typename B, typename D> struct IsBaseOf
|
||||||
struct IsBaseOf
|
|
||||||
: BoolType< ::std::is_base_of<B,D>::value> {};
|
: BoolType< ::std::is_base_of<B,D>::value> {};
|
||||||
|
|
||||||
#else // simplified version adopted from Boost
|
#else // simplified version adopted from Boost
|
||||||
|
|
||||||
template <typename B, typename D>
|
template<typename B, typename D> struct IsBaseOfImpl {
|
||||||
struct IsBaseOfImpl {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
|
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
|
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
|
||||||
|
|
||||||
@ -155,8 +123,7 @@ namespace internal {
|
|||||||
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
|
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename B, typename D>
|
template <typename B, typename D> struct IsBaseOf
|
||||||
struct IsBaseOf
|
|
||||||
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
|
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
|
||||||
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
@ -165,17 +132,11 @@ namespace internal {
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// EnableIf / DisableIf
|
// EnableIf / DisableIf
|
||||||
//
|
//
|
||||||
template <bool Condition, typename T = void>
|
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
|
||||||
struct EnableIfCond { typedef T Type; };
|
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
||||||
template <typename T>
|
|
||||||
struct EnableIfCond<false, T> { /* empty */
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool Condition, typename T = void>
|
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
|
||||||
struct DisableIfCond { typedef T Type; };
|
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
|
||||||
template <typename T>
|
|
||||||
struct DisableIfCond<true, T> { /* empty */
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Condition, typename T = void>
|
template <typename Condition, typename T = void>
|
||||||
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
||||||
@ -185,26 +146,29 @@ namespace internal {
|
|||||||
|
|
||||||
// SFINAE helpers
|
// SFINAE helpers
|
||||||
struct SfinaeTag {};
|
struct SfinaeTag {};
|
||||||
template <typename T>
|
template <typename T> struct RemoveSfinaeTag;
|
||||||
struct RemoveSfinaeTag;
|
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
|
||||||
template <typename T>
|
|
||||||
struct RemoveSfinaeTag<SfinaeTag& (*)(T)> { typedef T Type; };
|
|
||||||
|
|
||||||
#define RAPIDJSON_REMOVEFPTR_(type) \
|
#define RAPIDJSON_REMOVEFPTR_(type) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag<::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*)type>::Type
|
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
|
||||||
|
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF(cond) \
|
#define RAPIDJSON_ENABLEIF(cond) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf<RAPIDJSON_REMOVEFPTR_(cond)>::Type* = NULL
|
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
||||||
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF(cond) \
|
#define RAPIDJSON_DISABLEIF(cond) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf<RAPIDJSON_REMOVEFPTR_(cond)>::Type* = NULL
|
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
||||||
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf<RAPIDJSON_REMOVEFPTR_(cond), \
|
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
||||||
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf<RAPIDJSON_REMOVEFPTR_(cond), \
|
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
||||||
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -111,18 +111,20 @@ namespace internal {
|
|||||||
public:
|
public:
|
||||||
typedef Encoding EncodingType;
|
typedef Encoding EncodingType;
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
template <typename, typename>
|
template <typename, typename> friend class GenericRegexSearch;
|
||||||
friend class GenericRegexSearch;
|
|
||||||
|
|
||||||
GenericRegex(const Ch* source, Allocator* allocator = 0) : ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_),
|
GenericRegex(const Ch* source, Allocator* allocator = 0) :
|
||||||
|
ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_),
|
||||||
states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
||||||
anchorBegin_(), anchorEnd_() {
|
anchorBegin_(), anchorEnd_()
|
||||||
|
{
|
||||||
GenericStringStream<Encoding> ss(source);
|
GenericStringStream<Encoding> ss(source);
|
||||||
DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);
|
DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);
|
||||||
Parse(ds);
|
Parse(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GenericRegex() {
|
~GenericRegex()
|
||||||
|
{
|
||||||
RAPIDJSON_DELETE(ownAllocator_);
|
RAPIDJSON_DELETE(ownAllocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +244,8 @@ namespace internal {
|
|||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '{': {
|
case '{':
|
||||||
|
{
|
||||||
unsigned n, m;
|
unsigned n, m;
|
||||||
if (!ParseUnsigned(ds, &n))
|
if (!ParseUnsigned(ds, &n))
|
||||||
return;
|
return;
|
||||||
@ -260,14 +263,16 @@ namespace internal {
|
|||||||
if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')
|
if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')
|
||||||
return;
|
return;
|
||||||
ds.Take();
|
ds.Take();
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
PushOperand(operandStack, kAnyCharacterClass);
|
PushOperand(operandStack, kAnyCharacterClass);
|
||||||
ImplicitConcatenation(atomCountStack, operatorStack);
|
ImplicitConcatenation(atomCountStack, operatorStack);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[': {
|
case '[':
|
||||||
|
{
|
||||||
SizeType range;
|
SizeType range;
|
||||||
if (!ParseRange(ds, &range))
|
if (!ParseRange(ds, &range))
|
||||||
return;
|
return;
|
||||||
@ -524,7 +529,8 @@ namespace internal {
|
|||||||
// fall through to step 0 for other characters
|
// fall through to step 0 for other characters
|
||||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
case 0: {
|
case 0:
|
||||||
|
{
|
||||||
SizeType r = NewRange(codepoint);
|
SizeType r = NewRange(codepoint);
|
||||||
if (current != kRegexInvalidRange)
|
if (current != kRegexInvalidRange)
|
||||||
GetRange(current).next = r;
|
GetRange(current).next = r;
|
||||||
@ -570,23 +576,12 @@ namespace internal {
|
|||||||
case '{':
|
case '{':
|
||||||
case '}':
|
case '}':
|
||||||
case '\\':
|
case '\\':
|
||||||
*escapedCodepoint = codepoint;
|
*escapedCodepoint = codepoint; return true;
|
||||||
return true;
|
case 'f': *escapedCodepoint = 0x000C; return true;
|
||||||
case 'f':
|
case 'n': *escapedCodepoint = 0x000A; return true;
|
||||||
*escapedCodepoint = 0x000C;
|
case 'r': *escapedCodepoint = 0x000D; return true;
|
||||||
return true;
|
case 't': *escapedCodepoint = 0x0009; return true;
|
||||||
case 'n':
|
case 'v': *escapedCodepoint = 0x000B; return true;
|
||||||
*escapedCodepoint = 0x000A;
|
|
||||||
return true;
|
|
||||||
case 'r':
|
|
||||||
*escapedCodepoint = 0x000D;
|
|
||||||
return true;
|
|
||||||
case 't':
|
|
||||||
*escapedCodepoint = 0x0009;
|
|
||||||
return true;
|
|
||||||
case 'v':
|
|
||||||
*escapedCodepoint = 0x000B;
|
|
||||||
return true;
|
|
||||||
default:
|
default:
|
||||||
return false; // Unsupported escape character
|
return false; // Unsupported escape character
|
||||||
}
|
}
|
||||||
@ -613,8 +608,10 @@ namespace internal {
|
|||||||
typedef typename RegexType::EncodingType Encoding;
|
typedef typename RegexType::EncodingType Encoding;
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : regex_(regex), allocator_(allocator), ownAllocator_(0),
|
GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) :
|
||||||
state0_(allocator, 0), state1_(allocator, 0), stateSet_() {
|
regex_(regex), allocator_(allocator), ownAllocator_(0),
|
||||||
|
state0_(allocator, 0), state1_(allocator, 0), stateSet_()
|
||||||
|
{
|
||||||
RAPIDJSON_ASSERT(regex_.IsValid());
|
RAPIDJSON_ASSERT(regex_.IsValid());
|
||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||||
@ -671,7 +668,8 @@ namespace internal {
|
|||||||
const State& sr = regex_.GetState(*s);
|
const State& sr = regex_.GetState(*s);
|
||||||
if (sr.codepoint == codepoint ||
|
if (sr.codepoint == codepoint ||
|
||||||
sr.codepoint == RegexType::kAnyCharacterClass ||
|
sr.codepoint == RegexType::kAnyCharacterClass ||
|
||||||
(sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) {
|
(sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))
|
||||||
|
{
|
||||||
matched = AddState(*next, sr.out) || matched;
|
matched = AddState(*next, sr.out) || matched;
|
||||||
if (!anchorEnd && matched)
|
if (!anchorEnd && matched)
|
||||||
return true;
|
return true;
|
||||||
|
@ -48,7 +48,8 @@ namespace internal {
|
|||||||
stack_(rhs.stack_),
|
stack_(rhs.stack_),
|
||||||
stackTop_(rhs.stackTop_),
|
stackTop_(rhs.stackTop_),
|
||||||
stackEnd_(rhs.stackEnd_),
|
stackEnd_(rhs.stackEnd_),
|
||||||
initialCapacity_(rhs.initialCapacity_) {
|
initialCapacity_(rhs.initialCapacity_)
|
||||||
|
{
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
rhs.stack_ = 0;
|
rhs.stack_ = 0;
|
||||||
@ -64,7 +65,8 @@ namespace internal {
|
|||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
Stack& operator=(Stack&& rhs) {
|
Stack& operator=(Stack&& rhs) {
|
||||||
if (&rhs != this) {
|
if (&rhs != this)
|
||||||
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
allocator_ = rhs.allocator_;
|
allocator_ = rhs.allocator_;
|
||||||
@ -185,8 +187,7 @@ namespace internal {
|
|||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||||
newCapacity = initialCapacity_;
|
newCapacity = initialCapacity_;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newCapacity = GetCapacity();
|
newCapacity = GetCapacity();
|
||||||
newCapacity += (newCapacity + 1) / 2;
|
newCapacity += (newCapacity + 1) / 2;
|
||||||
}
|
}
|
||||||
|
@ -70,24 +70,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ch Peek() const { return *current_; }
|
Ch Peek() const { return *current_; }
|
||||||
Ch Take() {
|
Ch Take() { Ch c = *current_; Read(); return c; }
|
||||||
Ch c = *current_;
|
|
||||||
Read();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(Ch*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
|
@ -46,16 +46,10 @@ struct MemoryStream {
|
|||||||
Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
|
Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
|
||||||
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
|
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
|
||||||
|
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
size_t PutEnd(Ch*) {
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
|
@ -287,7 +287,8 @@ static
|
|||||||
#else // STATIC_IMAXDIV ][
|
#else // STATIC_IMAXDIV ][
|
||||||
_inline
|
_inline
|
||||||
#endif // STATIC_IMAXDIV ]
|
#endif // STATIC_IMAXDIV ]
|
||||||
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) {
|
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
|
||||||
|
{
|
||||||
imaxdiv_t result;
|
imaxdiv_t result;
|
||||||
|
|
||||||
result.quot = numer / denom;
|
result.quot = numer / denom;
|
||||||
|
@ -56,26 +56,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
char Peek() const {
|
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
return 0;
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
}
|
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
char Take() {
|
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t Tell() const {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char* PutBegin() {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size_t PutEnd(char*) {
|
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BasicOStreamWrapper(const BasicOStreamWrapper&);
|
BasicOStreamWrapper(const BasicOStreamWrapper&);
|
||||||
|
@ -371,7 +371,8 @@ public:
|
|||||||
for (size_t i = 0; i < tokenCount_; i++) {
|
for (size_t i = 0; i < tokenCount_; i++) {
|
||||||
if (tokens_[i].index != rhs.tokens_[i].index ||
|
if (tokens_[i].index != rhs.tokens_[i].index ||
|
||||||
tokens_[i].length != rhs.tokens_[i].length ||
|
tokens_[i].length != rhs.tokens_[i].length ||
|
||||||
(tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length) != 0)) {
|
(tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,7 +542,8 @@ public:
|
|||||||
ValueType* v = &root;
|
ValueType* v = &root;
|
||||||
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType: {
|
case kObjectType:
|
||||||
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
break;
|
break;
|
||||||
@ -776,12 +778,14 @@ public:
|
|||||||
const Token* last = tokens_ + (tokenCount_ - 1);
|
const Token* last = tokens_ + (tokenCount_ - 1);
|
||||||
for (const Token *t = tokens_; t != last; ++t) {
|
for (const Token *t = tokens_; t != last; ++t) {
|
||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType: {
|
case kObjectType:
|
||||||
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
return false;
|
return false;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case kArrayType:
|
case kArrayType:
|
||||||
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
|
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
|
||||||
return false;
|
return false;
|
||||||
@ -929,10 +933,8 @@ private:
|
|||||||
if (c == '~') {
|
if (c == '~') {
|
||||||
if (i < length) {
|
if (i < length) {
|
||||||
c = source[i];
|
c = source[i];
|
||||||
if (c == '0')
|
if (c == '0') c = '~';
|
||||||
c = '~';
|
else if (c == '1') c = '/';
|
||||||
else if (c == '1')
|
|
||||||
c = '/';
|
|
||||||
else {
|
else {
|
||||||
parseErrorCode_ = kPointerParseErrorInvalidEscape;
|
parseErrorCode_ = kPointerParseErrorInvalidEscape;
|
||||||
goto error;
|
goto error;
|
||||||
@ -1057,12 +1059,9 @@ private:
|
|||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
c = static_cast<Ch>(c << 4);
|
c = static_cast<Ch>(c << 4);
|
||||||
Ch h = *src_;
|
Ch h = *src_;
|
||||||
if (h >= '0' && h <= '9')
|
if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
|
||||||
c = static_cast<Ch>(c + h - '0');
|
else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
|
||||||
else if (h >= 'A' && h <= 'F')
|
else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
|
||||||
c = static_cast<Ch>(c + h - 'A' + 10);
|
|
||||||
else if (h >= 'a' && h <= 'f')
|
|
||||||
c = static_cast<Ch>(c + h - 'a' + 10);
|
|
||||||
else {
|
else {
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1094,7 +1093,6 @@ private:
|
|||||||
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
|
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
|
||||||
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
|
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OutputStream& os_;
|
OutputStream& os_;
|
||||||
};
|
};
|
||||||
|
@ -55,13 +55,16 @@ public:
|
|||||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
\param allocator User supplied allocator. If it is null, it will create a private one.
|
||||||
\param levelDepth Initial capacity of stack.
|
\param levelDepth Initial capacity of stack.
|
||||||
*/
|
*/
|
||||||
explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
|
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
||||||
|
|
||||||
|
|
||||||
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
|
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
PrettyWriter(PrettyWriter&& rhs) : Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
|
PrettyWriter(PrettyWriter&& rhs) :
|
||||||
|
Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Set custom indentation.
|
//! Set custom indentation.
|
||||||
@ -89,34 +92,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
bool Null() {
|
bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
|
||||||
PrettyPrefix(kNullType);
|
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
|
||||||
return Base::EndValue(Base::WriteNull());
|
bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
|
||||||
}
|
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
|
||||||
bool Bool(bool b) {
|
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
|
||||||
PrettyPrefix(b ? kTrueType : kFalseType);
|
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
|
||||||
return Base::EndValue(Base::WriteBool(b));
|
bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
|
||||||
}
|
|
||||||
bool Int(int i) {
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteInt(i));
|
|
||||||
}
|
|
||||||
bool Uint(unsigned u) {
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteUint(u));
|
|
||||||
}
|
|
||||||
bool Int64(int64_t i64) {
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteInt64(i64));
|
|
||||||
}
|
|
||||||
bool Uint64(uint64_t u64) {
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteUint64(u64));
|
|
||||||
}
|
|
||||||
bool Double(double d) {
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteDouble(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
|
@ -379,7 +379,8 @@
|
|||||||
If any of these symbols is defined, RapidJSON defines the macro
|
If any of these symbols is defined, RapidJSON defines the macro
|
||||||
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
|
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
|
||||||
*/
|
*/
|
||||||
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
|
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
|
||||||
|
|| defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
|
||||||
#define RAPIDJSON_SIMD
|
#define RAPIDJSON_SIMD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -453,14 +454,9 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||||
#endif
|
#endif
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
template <bool x>
|
template <bool x> struct STATIC_ASSERTION_FAILURE;
|
||||||
struct STATIC_ASSERTION_FAILURE;
|
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
||||||
template <>
|
template <size_t x> struct StaticAssertTest {};
|
||||||
struct STATIC_ASSERTION_FAILURE<true> {
|
|
||||||
enum { value = 1 };
|
|
||||||
};
|
|
||||||
template <size_t x>
|
|
||||||
struct StaticAssertTest {};
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
@ -519,8 +515,7 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
|
|
||||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
||||||
#define RAPIDJSON_MULTILINEMACRO_END \
|
#define RAPIDJSON_MULTILINEMACRO_END \
|
||||||
} \
|
} while((void)0, 0)
|
||||||
while ((void)0, 0)
|
|
||||||
|
|
||||||
// adopted from Boost
|
// adopted from Boost
|
||||||
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
||||||
@ -562,8 +557,7 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
#define RAPIDJSON_PRAGMA(x) __pragma(x)
|
#define RAPIDJSON_PRAGMA(x) __pragma(x)
|
||||||
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
|
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
|
||||||
|
|
||||||
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable \
|
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
|
||||||
: x)
|
|
||||||
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
||||||
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
||||||
|
|
||||||
|
@ -347,8 +347,7 @@ inline const char* SkipWhitespace_SIMD(const char* p) {
|
|||||||
return p;
|
return p;
|
||||||
|
|
||||||
// The rest of string
|
// The rest of string
|
||||||
#define C16(c) \
|
#define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
|
||||||
{ c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
|
|
||||||
static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
|
static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
|
||||||
#undef C16
|
#undef C16
|
||||||
|
|
||||||
@ -384,8 +383,7 @@ inline const char* SkipWhitespace_SIMD(const char* p, const char* end) {
|
|||||||
return p;
|
return p;
|
||||||
|
|
||||||
// The rest of string
|
// The rest of string
|
||||||
#define C16(c) \
|
#define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
|
||||||
{ c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
|
|
||||||
static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
|
static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
|
||||||
#undef C16
|
#undef C16
|
||||||
|
|
||||||
@ -455,8 +453,7 @@ inline const char* SkipWhitespace_SIMD(const char* p) {
|
|||||||
uint32_t lz = internal::clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
return p + 8 + (lz >> 3);
|
return p + 8 + (lz >> 3);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
return p + (lz >> 3);
|
return p + (lz >> 3);
|
||||||
}
|
}
|
||||||
@ -492,8 +489,7 @@ inline const char* SkipWhitespace_SIMD(const char* p, const char* end) {
|
|||||||
uint32_t lz = internal::clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
return p + 8 + (lz >> 3);
|
return p + 8 + (lz >> 3);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
return p + (lz >> 3);
|
return p + (lz >> 3);
|
||||||
}
|
}
|
||||||
@ -506,19 +502,16 @@ inline const char* SkipWhitespace_SIMD(const char* p, const char* end) {
|
|||||||
|
|
||||||
#ifdef RAPIDJSON_SIMD
|
#ifdef RAPIDJSON_SIMD
|
||||||
//! Template function specialization for InsituStringStream
|
//! Template function specialization for InsituStringStream
|
||||||
template <>
|
template<> inline void SkipWhitespace(InsituStringStream& is) {
|
||||||
inline void SkipWhitespace(InsituStringStream& is) {
|
|
||||||
is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
|
is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Template function specialization for StringStream
|
//! Template function specialization for StringStream
|
||||||
template <>
|
template<> inline void SkipWhitespace(StringStream& is) {
|
||||||
inline void SkipWhitespace(StringStream& is) {
|
|
||||||
is.src_ = SkipWhitespace_SIMD(is.src_);
|
is.src_ = SkipWhitespace_SIMD(is.src_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
|
||||||
inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
|
|
||||||
is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
|
is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
|
||||||
}
|
}
|
||||||
#endif // RAPIDJSON_SIMD
|
#endif // RAPIDJSON_SIMD
|
||||||
@ -551,7 +544,8 @@ public:
|
|||||||
/*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
|
/*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
|
||||||
\param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
|
\param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
|
||||||
*/
|
*/
|
||||||
GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
|
GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
|
||||||
|
stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
|
||||||
|
|
||||||
//! Parse JSON text.
|
//! Parse JSON text.
|
||||||
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
||||||
@ -707,7 +701,6 @@ private:
|
|||||||
struct ClearStackOnExit {
|
struct ClearStackOnExit {
|
||||||
explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
|
explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
|
||||||
~ClearStackOnExit() { r_.ClearStack(); }
|
~ClearStackOnExit() { r_.ClearStack(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GenericReader& r_;
|
GenericReader& r_;
|
||||||
ClearStackOnExit(const ClearStackOnExit&);
|
ClearStackOnExit(const ClearStackOnExit&);
|
||||||
@ -796,8 +789,7 @@ private:
|
|||||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
|
||||||
break; // This useless break is only for making warning and coverage happy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseFlags & kParseTrailingCommasFlag) {
|
if (parseFlags & kParseTrailingCommasFlag) {
|
||||||
@ -1044,7 +1036,8 @@ private:
|
|||||||
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
|
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
|
||||||
}
|
}
|
||||||
// single low surrogate
|
// single low surrogate
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1066,7 +1059,9 @@ private:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t offset = is.Tell();
|
size_t offset = is.Tell();
|
||||||
if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? !Transcoder<SEncoding, TEncoding>::Validate(is, os) : !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
|
if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
|
||||||
|
!Transcoder<SEncoding, TEncoding>::Validate(is, os) :
|
||||||
|
!Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
|
RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1274,8 +1269,7 @@ private:
|
|||||||
length = 8 + (lz >> 3);
|
length = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
length = lz >> 3;
|
length = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
@ -1345,8 +1339,7 @@ private:
|
|||||||
length = 8 + (lz >> 3);
|
length = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
length = lz >> 3;
|
length = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
@ -1400,8 +1393,7 @@ private:
|
|||||||
p += 8 + (lz >> 3);
|
p += 8 + (lz >> 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
p += lz >> 3;
|
p += lz >> 3;
|
||||||
break;
|
break;
|
||||||
@ -1440,7 +1432,6 @@ private:
|
|||||||
template<typename InputStream>
|
template<typename InputStream>
|
||||||
class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
|
class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
|
||||||
typedef NumberStream<InputStream, false, false> Base;
|
typedef NumberStream<InputStream, false, false> Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
||||||
|
|
||||||
@ -1467,7 +1458,6 @@ private:
|
|||||||
template<typename InputStream>
|
template<typename InputStream>
|
||||||
class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
|
class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
|
||||||
typedef NumberStream<InputStream, true, false> Base;
|
typedef NumberStream<InputStream, true, false> Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
||||||
|
|
||||||
@ -1478,10 +1468,11 @@ private:
|
|||||||
void ParseNumber(InputStream& is, Handler& handler) {
|
void ParseNumber(InputStream& is, Handler& handler) {
|
||||||
internal::StreamLocalCopy<InputStream> copy(is);
|
internal::StreamLocalCopy<InputStream> copy(is);
|
||||||
NumberStream<InputStream,
|
NumberStream<InputStream,
|
||||||
((parseFlags & kParseNumbersAsStringsFlag) != 0) ? ((parseFlags & kParseInsituFlag) == 0) : ((parseFlags & kParseFullPrecisionFlag) != 0),
|
((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
|
||||||
|
((parseFlags & kParseInsituFlag) == 0) :
|
||||||
|
((parseFlags & kParseFullPrecisionFlag) != 0),
|
||||||
(parseFlags & kParseNumbersAsStringsFlag) != 0 &&
|
(parseFlags & kParseNumbersAsStringsFlag) != 0 &&
|
||||||
(parseFlags & kParseInsituFlag) == 0>
|
(parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
|
||||||
s(*this, copy.s);
|
|
||||||
|
|
||||||
size_t startOffset = s.Tell();
|
size_t startOffset = s.Tell();
|
||||||
double d = 0.0;
|
double d = 0.0;
|
||||||
@ -1540,7 +1531,8 @@ private:
|
|||||||
d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
|
d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
|
||||||
useNanOrInf = true;
|
useNanOrInf = true;
|
||||||
|
|
||||||
if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
|
if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
|
||||||
|
&& Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1757,27 +1749,16 @@ private:
|
|||||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||||
void ParseValue(InputStream& is, Handler& handler) {
|
void ParseValue(InputStream& is, Handler& handler) {
|
||||||
switch (is.Peek()) {
|
switch (is.Peek()) {
|
||||||
case 'n':
|
case 'n': ParseNull <parseFlags>(is, handler); break;
|
||||||
ParseNull<parseFlags>(is, handler);
|
case 't': ParseTrue <parseFlags>(is, handler); break;
|
||||||
break;
|
case 'f': ParseFalse <parseFlags>(is, handler); break;
|
||||||
case 't':
|
case '"': ParseString<parseFlags>(is, handler); break;
|
||||||
ParseTrue<parseFlags>(is, handler);
|
case '{': ParseObject<parseFlags>(is, handler); break;
|
||||||
break;
|
case '[': ParseArray <parseFlags>(is, handler); break;
|
||||||
case 'f':
|
|
||||||
ParseFalse<parseFlags>(is, handler);
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
ParseString<parseFlags>(is, handler);
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
ParseObject<parseFlags>(is, handler);
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
ParseArray<parseFlags>(is, handler);
|
|
||||||
break;
|
|
||||||
default :
|
default :
|
||||||
ParseNumber<parseFlags>(is, handler);
|
ParseNumber<parseFlags>(is, handler);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1865,12 +1846,14 @@ private:
|
|||||||
{
|
{
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState },
|
IterativeParsingErrorState
|
||||||
|
},
|
||||||
// Error(sink state)
|
// Error(sink state)
|
||||||
{
|
{
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState },
|
IterativeParsingErrorState
|
||||||
|
},
|
||||||
// Start
|
// Start
|
||||||
{
|
{
|
||||||
IterativeParsingArrayInitialState, // Left bracket
|
IterativeParsingArrayInitialState, // Left bracket
|
||||||
@ -1931,7 +1914,8 @@ private:
|
|||||||
{
|
{
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState },
|
IterativeParsingErrorState
|
||||||
|
},
|
||||||
// ArrayInitial
|
// ArrayInitial
|
||||||
{
|
{
|
||||||
IterativeParsingArrayInitialState, // Left bracket(push Element state)
|
IterativeParsingArrayInitialState, // Left bracket(push Element state)
|
||||||
@ -1964,12 +1948,14 @@ private:
|
|||||||
{
|
{
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState },
|
IterativeParsingErrorState
|
||||||
|
},
|
||||||
// Single Value (sink state)
|
// Single Value (sink state)
|
||||||
{
|
{
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
|
||||||
IterativeParsingErrorState },
|
IterativeParsingErrorState
|
||||||
|
},
|
||||||
// ElementDelimiter
|
// ElementDelimiter
|
||||||
{
|
{
|
||||||
IterativeParsingArrayInitialState, // Left bracket(push Element state)
|
IterativeParsingArrayInitialState, // Left bracket(push Element state)
|
||||||
@ -2028,7 +2014,8 @@ private:
|
|||||||
return dst;
|
return dst;
|
||||||
|
|
||||||
case IterativeParsingObjectInitialState:
|
case IterativeParsingObjectInitialState:
|
||||||
case IterativeParsingArrayInitialState: {
|
case IterativeParsingArrayInitialState:
|
||||||
|
{
|
||||||
// Push the state(Element or MemeberValue) if we are nested in another array or value of member.
|
// Push the state(Element or MemeberValue) if we are nested in another array or value of member.
|
||||||
// In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
|
// In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
|
||||||
IterativeParsingState n = src;
|
IterativeParsingState n = src;
|
||||||
@ -2088,7 +2075,8 @@ private:
|
|||||||
*stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
|
*stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
|
||||||
return dst;
|
return dst;
|
||||||
|
|
||||||
case IterativeParsingObjectFinishState: {
|
case IterativeParsingObjectFinishState:
|
||||||
|
{
|
||||||
// Transit from delimiter is only allowed when trailing commas are enabled
|
// Transit from delimiter is only allowed when trailing commas are enabled
|
||||||
if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
|
if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
|
||||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
|
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
|
||||||
@ -2117,7 +2105,8 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case IterativeParsingArrayFinishState: {
|
case IterativeParsingArrayFinishState:
|
||||||
|
{
|
||||||
// Transit from delimiter is only allowed when trailing commas are enabled
|
// Transit from delimiter is only allowed when trailing commas are enabled
|
||||||
if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
|
if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
|
||||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
|
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
|
||||||
@ -2176,31 +2165,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (src) {
|
switch (src) {
|
||||||
case IterativeParsingStartState:
|
case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell());
|
case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
|
||||||
return;
|
|
||||||
case IterativeParsingFinishState:
|
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell());
|
|
||||||
return;
|
|
||||||
case IterativeParsingObjectInitialState:
|
case IterativeParsingObjectInitialState:
|
||||||
case IterativeParsingMemberDelimiterState:
|
case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
|
case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
|
||||||
return;
|
case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
|
||||||
case IterativeParsingMemberKeyState:
|
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
|
||||||
return;
|
|
||||||
case IterativeParsingMemberValueState:
|
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
|
||||||
return;
|
|
||||||
case IterativeParsingKeyValueDelimiterState:
|
case IterativeParsingKeyValueDelimiterState:
|
||||||
case IterativeParsingArrayInitialState:
|
case IterativeParsingArrayInitialState:
|
||||||
case IterativeParsingElementDelimiterState:
|
case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
|
default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
|
||||||
return;
|
|
||||||
default:
|
|
||||||
RAPIDJSON_ASSERT(src == IterativeParsingElementState);
|
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,36 +251,14 @@ namespace internal {
|
|||||||
|
|
||||||
bool Null() { return WriteType(kNullType); }
|
bool Null() { return WriteType(kNullType); }
|
||||||
bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
|
bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
|
||||||
bool Int(int i) {
|
bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
|
||||||
Number n;
|
bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
|
||||||
n.u.i = i;
|
bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
|
||||||
n.d = static_cast<double>(i);
|
bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
|
||||||
return WriteNumber(n);
|
|
||||||
}
|
|
||||||
bool Uint(unsigned u) {
|
|
||||||
Number n;
|
|
||||||
n.u.u = u;
|
|
||||||
n.d = static_cast<double>(u);
|
|
||||||
return WriteNumber(n);
|
|
||||||
}
|
|
||||||
bool Int64(int64_t i) {
|
|
||||||
Number n;
|
|
||||||
n.u.i = i;
|
|
||||||
n.d = static_cast<double>(i);
|
|
||||||
return WriteNumber(n);
|
|
||||||
}
|
|
||||||
bool Uint64(uint64_t u) {
|
|
||||||
Number n;
|
|
||||||
n.u.u = u;
|
|
||||||
n.d = static_cast<double>(u);
|
|
||||||
return WriteNumber(n);
|
|
||||||
}
|
|
||||||
bool Double(double d) {
|
bool Double(double d) {
|
||||||
Number n;
|
Number n;
|
||||||
if (d < 0)
|
if (d < 0) n.u.i = static_cast<int64_t>(d);
|
||||||
n.u.i = static_cast<int64_t>(d);
|
else n.u.u = static_cast<uint64_t>(d);
|
||||||
else
|
|
||||||
n.u.u = static_cast<uint64_t>(d);
|
|
||||||
n.d = d;
|
n.d = d;
|
||||||
return WriteNumber(n);
|
return WriteNumber(n);
|
||||||
}
|
}
|
||||||
@ -374,7 +352,8 @@ namespace internal {
|
|||||||
kPatternValidatorWithAdditionalProperty
|
kPatternValidatorWithAdditionalProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s) : factory(f),
|
SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s) :
|
||||||
|
factory(f),
|
||||||
error_handler(eh),
|
error_handler(eh),
|
||||||
schema(s),
|
schema(s),
|
||||||
valueSchema(),
|
valueSchema(),
|
||||||
@ -392,7 +371,8 @@ namespace internal {
|
|||||||
propertyExist(),
|
propertyExist(),
|
||||||
inArray(false),
|
inArray(false),
|
||||||
valueUniqueness(false),
|
valueUniqueness(false),
|
||||||
arrayUniqueness(false) {
|
arrayUniqueness(false)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~SchemaValidationContext() {
|
~SchemaValidationContext() {
|
||||||
@ -454,7 +434,8 @@ namespace internal {
|
|||||||
typedef IValidationErrorHandler<Schema> ErrorHandler;
|
typedef IValidationErrorHandler<Schema> ErrorHandler;
|
||||||
friend class GenericSchemaDocument<ValueType, AllocatorType>;
|
friend class GenericSchemaDocument<ValueType, AllocatorType>;
|
||||||
|
|
||||||
Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : allocator_(allocator),
|
Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
|
||||||
|
allocator_(allocator),
|
||||||
uri_(schemaDocument->GetURI(), *allocator),
|
uri_(schemaDocument->GetURI(), *allocator),
|
||||||
pointer_(p, allocator),
|
pointer_(p, allocator),
|
||||||
typeless_(schemaDocument->GetTypeless()),
|
typeless_(schemaDocument->GetTypeless()),
|
||||||
@ -488,7 +469,8 @@ namespace internal {
|
|||||||
maxLength_(~SizeType(0)),
|
maxLength_(~SizeType(0)),
|
||||||
exclusiveMinimum_(false),
|
exclusiveMinimum_(false),
|
||||||
exclusiveMaximum_(false),
|
exclusiveMaximum_(false),
|
||||||
defaultValueLength_(0) {
|
defaultValueLength_(0)
|
||||||
|
{
|
||||||
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
||||||
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
|
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
|
||||||
|
|
||||||
@ -687,6 +669,7 @@ namespace internal {
|
|||||||
if (const ValueType* v = GetMember(value, GetDefaultValueString()))
|
if (const ValueType* v = GetMember(value, GetDefaultValueString()))
|
||||||
if (v->IsString())
|
if (v->IsString())
|
||||||
defaultValueLength_ = v->GetStringLength();
|
defaultValueLength_ = v->GetStringLength();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Schema() {
|
~Schema() {
|
||||||
@ -818,8 +801,7 @@ namespace internal {
|
|||||||
if (oneValid) {
|
if (oneValid) {
|
||||||
context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count, true);
|
context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count, true);
|
||||||
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOfMatch);
|
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOfMatch);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
oneValid = true;
|
oneValid = true;
|
||||||
}
|
}
|
||||||
if (!oneValid) {
|
if (!oneValid) {
|
||||||
@ -1072,64 +1054,38 @@ namespace internal {
|
|||||||
|
|
||||||
static const ValueType& GetValidateErrorKeyword(ValidateErrorCode validateErrorCode) {
|
static const ValueType& GetValidateErrorKeyword(ValidateErrorCode validateErrorCode) {
|
||||||
switch (validateErrorCode) {
|
switch (validateErrorCode) {
|
||||||
case kValidateErrorMultipleOf:
|
case kValidateErrorMultipleOf: return GetMultipleOfString();
|
||||||
return GetMultipleOfString();
|
case kValidateErrorMaximum: return GetMaximumString();
|
||||||
case kValidateErrorMaximum:
|
case kValidateErrorExclusiveMaximum: return GetMaximumString(); // Same
|
||||||
return GetMaximumString();
|
case kValidateErrorMinimum: return GetMinimumString();
|
||||||
case kValidateErrorExclusiveMaximum:
|
case kValidateErrorExclusiveMinimum: return GetMinimumString(); // Same
|
||||||
return GetMaximumString(); // Same
|
|
||||||
case kValidateErrorMinimum:
|
|
||||||
return GetMinimumString();
|
|
||||||
case kValidateErrorExclusiveMinimum:
|
|
||||||
return GetMinimumString(); // Same
|
|
||||||
|
|
||||||
case kValidateErrorMaxLength:
|
case kValidateErrorMaxLength: return GetMaxLengthString();
|
||||||
return GetMaxLengthString();
|
case kValidateErrorMinLength: return GetMinLengthString();
|
||||||
case kValidateErrorMinLength:
|
case kValidateErrorPattern: return GetPatternString();
|
||||||
return GetMinLengthString();
|
|
||||||
case kValidateErrorPattern:
|
|
||||||
return GetPatternString();
|
|
||||||
|
|
||||||
case kValidateErrorMaxItems:
|
case kValidateErrorMaxItems: return GetMaxItemsString();
|
||||||
return GetMaxItemsString();
|
case kValidateErrorMinItems: return GetMinItemsString();
|
||||||
case kValidateErrorMinItems:
|
case kValidateErrorUniqueItems: return GetUniqueItemsString();
|
||||||
return GetMinItemsString();
|
case kValidateErrorAdditionalItems: return GetAdditionalItemsString();
|
||||||
case kValidateErrorUniqueItems:
|
|
||||||
return GetUniqueItemsString();
|
|
||||||
case kValidateErrorAdditionalItems:
|
|
||||||
return GetAdditionalItemsString();
|
|
||||||
|
|
||||||
case kValidateErrorMaxProperties:
|
case kValidateErrorMaxProperties: return GetMaxPropertiesString();
|
||||||
return GetMaxPropertiesString();
|
case kValidateErrorMinProperties: return GetMinPropertiesString();
|
||||||
case kValidateErrorMinProperties:
|
case kValidateErrorRequired: return GetRequiredString();
|
||||||
return GetMinPropertiesString();
|
case kValidateErrorAdditionalProperties: return GetAdditionalPropertiesString();
|
||||||
case kValidateErrorRequired:
|
case kValidateErrorPatternProperties: return GetPatternPropertiesString();
|
||||||
return GetRequiredString();
|
case kValidateErrorDependencies: return GetDependenciesString();
|
||||||
case kValidateErrorAdditionalProperties:
|
|
||||||
return GetAdditionalPropertiesString();
|
|
||||||
case kValidateErrorPatternProperties:
|
|
||||||
return GetPatternPropertiesString();
|
|
||||||
case kValidateErrorDependencies:
|
|
||||||
return GetDependenciesString();
|
|
||||||
|
|
||||||
case kValidateErrorEnum:
|
case kValidateErrorEnum: return GetEnumString();
|
||||||
return GetEnumString();
|
case kValidateErrorType: return GetTypeString();
|
||||||
case kValidateErrorType:
|
|
||||||
return GetTypeString();
|
|
||||||
|
|
||||||
case kValidateErrorOneOf:
|
case kValidateErrorOneOf: return GetOneOfString();
|
||||||
return GetOneOfString();
|
case kValidateErrorOneOfMatch: return GetOneOfString(); // Same
|
||||||
case kValidateErrorOneOfMatch:
|
case kValidateErrorAllOf: return GetAllOfString();
|
||||||
return GetOneOfString(); // Same
|
case kValidateErrorAnyOf: return GetAnyOfString();
|
||||||
case kValidateErrorAllOf:
|
case kValidateErrorNot: return GetNotString();
|
||||||
return GetAllOfString();
|
|
||||||
case kValidateErrorAnyOf:
|
|
||||||
return GetAnyOfString();
|
|
||||||
case kValidateErrorNot:
|
|
||||||
return GetNotString();
|
|
||||||
|
|
||||||
default:
|
default: return GetNullString();
|
||||||
return GetNullString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,20 +1250,13 @@ namespace internal {
|
|||||||
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
|
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
|
|
||||||
void AddType(const ValueType& type) {
|
void AddType(const ValueType& type) {
|
||||||
if (type == GetNullString())
|
if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
|
||||||
type_ |= 1 << kNullSchemaType;
|
else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
|
||||||
else if (type == GetBooleanString())
|
else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
|
||||||
type_ |= 1 << kBooleanSchemaType;
|
else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
|
||||||
else if (type == GetObjectString())
|
else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
|
||||||
type_ |= 1 << kObjectSchemaType;
|
else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
|
||||||
else if (type == GetArrayString())
|
else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
|
||||||
type_ |= 1 << kArraySchemaType;
|
|
||||||
else if (type == GetStringString())
|
|
||||||
type_ |= 1 << kStringSchemaType;
|
|
||||||
else if (type == GetIntegerString())
|
|
||||||
type_ |= 1 << kIntegerSchemaType;
|
|
||||||
else if (type == GetNumberString())
|
|
||||||
type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreateParallelValidator(Context& context) const {
|
bool CreateParallelValidator(Context& context) const {
|
||||||
@ -1353,7 +1302,8 @@ namespace internal {
|
|||||||
const Ch* str = name.GetString();
|
const Ch* str = name.GetString();
|
||||||
for (SizeType index = 0; index < propertyCount_; index++)
|
for (SizeType index = 0; index < propertyCount_; index++)
|
||||||
if (properties_[index].name.GetStringLength() == len &&
|
if (properties_[index].name.GetStringLength() == len &&
|
||||||
(std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) {
|
(std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))
|
||||||
|
{
|
||||||
*outIndex = index;
|
*outIndex = index;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1388,8 +1338,7 @@ namespace internal {
|
|||||||
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum);
|
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (maximum_.IsUint64()) {
|
else if (maximum_.IsUint64()) { }
|
||||||
}
|
|
||||||
/* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()
|
/* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()
|
||||||
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
|
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
|
||||||
return false;
|
return false;
|
||||||
@ -1494,10 +1443,8 @@ namespace internal {
|
|||||||
if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString());
|
if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString());
|
||||||
if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString());
|
if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString());
|
||||||
|
|
||||||
if (type_ & (1 << kNumberSchemaType))
|
if (type_ & (1 << kNumberSchemaType)) eh.AddExpectedType(GetNumberString());
|
||||||
eh.AddExpectedType(GetNumberString());
|
else if (type_ & (1 << kIntegerSchemaType)) eh.AddExpectedType(GetIntegerString());
|
||||||
else if (type_ & (1 << kIntegerSchemaType))
|
|
||||||
eh.AddExpectedType(GetIntegerString());
|
|
||||||
|
|
||||||
eh.EndDisallowedType(actualType);
|
eh.EndDisallowedType(actualType);
|
||||||
}
|
}
|
||||||
@ -1655,13 +1602,15 @@ public:
|
|||||||
\param allocator An optional allocator instance for allocating memory. Can be null.
|
\param allocator An optional allocator instance for allocating memory. Can be null.
|
||||||
*/
|
*/
|
||||||
explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0,
|
explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0,
|
||||||
IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : remoteProvider_(remoteProvider),
|
IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
|
||||||
|
remoteProvider_(remoteProvider),
|
||||||
allocator_(allocator),
|
allocator_(allocator),
|
||||||
ownAllocator_(),
|
ownAllocator_(),
|
||||||
root_(),
|
root_(),
|
||||||
typeless_(),
|
typeless_(),
|
||||||
schemaMap_(allocator, kInitialSchemaMapSize),
|
schemaMap_(allocator, kInitialSchemaMapSize),
|
||||||
schemaRef_(allocator, kInitialSchemaRefSize) {
|
schemaRef_(allocator, kInitialSchemaRefSize)
|
||||||
|
{
|
||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||||
|
|
||||||
@ -1700,14 +1649,16 @@ public:
|
|||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
//! Move constructor in C++11
|
//! Move constructor in C++11
|
||||||
GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : remoteProvider_(rhs.remoteProvider_),
|
GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :
|
||||||
|
remoteProvider_(rhs.remoteProvider_),
|
||||||
allocator_(rhs.allocator_),
|
allocator_(rhs.allocator_),
|
||||||
ownAllocator_(rhs.ownAllocator_),
|
ownAllocator_(rhs.ownAllocator_),
|
||||||
root_(rhs.root_),
|
root_(rhs.root_),
|
||||||
typeless_(rhs.typeless_),
|
typeless_(rhs.typeless_),
|
||||||
schemaMap_(std::move(rhs.schemaMap_)),
|
schemaMap_(std::move(rhs.schemaMap_)),
|
||||||
schemaRef_(std::move(rhs.schemaRef_)),
|
schemaRef_(std::move(rhs.schemaRef_)),
|
||||||
uri_(std::move(rhs.uri_)) {
|
uri_(std::move(rhs.uri_))
|
||||||
|
{
|
||||||
rhs.remoteProvider_ = 0;
|
rhs.remoteProvider_ = 0;
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
@ -1888,7 +1839,8 @@ template <
|
|||||||
typename SchemaDocumentType,
|
typename SchemaDocumentType,
|
||||||
typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>,
|
typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>,
|
||||||
typename StateAllocator = CrtAllocator>
|
typename StateAllocator = CrtAllocator>
|
||||||
class GenericSchemaValidator : public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
|
class GenericSchemaValidator :
|
||||||
|
public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
|
||||||
public internal::ISchemaValidator,
|
public internal::ISchemaValidator,
|
||||||
public internal::IValidationErrorHandler<typename SchemaDocumentType::SchemaType> {
|
public internal::IValidationErrorHandler<typename SchemaDocumentType::SchemaType> {
|
||||||
public:
|
public:
|
||||||
@ -1912,7 +1864,8 @@ public:
|
|||||||
StateAllocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
||||||
: schemaDocument_(&schemaDocument),
|
:
|
||||||
|
schemaDocument_(&schemaDocument),
|
||||||
root_(schemaDocument.GetRoot()),
|
root_(schemaDocument.GetRoot()),
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
@ -1925,8 +1878,7 @@ public:
|
|||||||
valid_(true),
|
valid_(true),
|
||||||
flags_(kValidateDefaultFlags)
|
flags_(kValidateDefaultFlags)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
,
|
, depth_(0)
|
||||||
depth_(0)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1944,7 +1896,8 @@ public:
|
|||||||
StateAllocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
||||||
: schemaDocument_(&schemaDocument),
|
:
|
||||||
|
schemaDocument_(&schemaDocument),
|
||||||
root_(schemaDocument.GetRoot()),
|
root_(schemaDocument.GetRoot()),
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
@ -1957,8 +1910,7 @@ public:
|
|||||||
valid_(true),
|
valid_(true),
|
||||||
flags_(kValidateDefaultFlags)
|
flags_(kValidateDefaultFlags)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
,
|
, depth_(0)
|
||||||
depth_(0)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -2281,8 +2233,10 @@ public:
|
|||||||
bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); }
|
bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); }
|
||||||
bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }
|
bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }
|
||||||
bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }
|
bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
|
bool RawNumber(const Ch* str, SizeType length, bool copy)
|
||||||
bool String(const Ch* str, SizeType length, bool copy) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
|
{ RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
|
||||||
|
bool String(const Ch* str, SizeType length, bool copy)
|
||||||
|
{ RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
|
||||||
|
|
||||||
bool StartObject() {
|
bool StartObject() {
|
||||||
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
|
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
|
||||||
@ -2377,7 +2331,8 @@ private:
|
|||||||
StateAllocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
||||||
: schemaDocument_(&schemaDocument),
|
:
|
||||||
|
schemaDocument_(&schemaDocument),
|
||||||
root_(root),
|
root_(root),
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
@ -2390,8 +2345,7 @@ private:
|
|||||||
valid_(true),
|
valid_(true),
|
||||||
flags_(kValidateDefaultFlags)
|
flags_(kValidateDefaultFlags)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
,
|
, depth_(depth)
|
||||||
depth_(depth)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (basePath && basePathSize)
|
if (basePath && basePathSize)
|
||||||
@ -2469,8 +2423,7 @@ private:
|
|||||||
// Cleanup before returning if continuing
|
// Cleanup before returning if continuing
|
||||||
if (GetContinueOnErrors()) {
|
if (GetContinueOnErrors()) {
|
||||||
a->PushBack(h, GetStateAllocator());
|
a->PushBack(h, GetStateAllocator());
|
||||||
while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')
|
while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/');
|
||||||
;
|
|
||||||
}
|
}
|
||||||
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorUniqueItems);
|
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorUniqueItems);
|
||||||
}
|
}
|
||||||
@ -2518,8 +2471,7 @@ private:
|
|||||||
PointerType instancePointer = GetInvalidDocumentPointer();
|
PointerType instancePointer = GetInvalidDocumentPointer();
|
||||||
((parent && instancePointer.GetTokenCount() > 0)
|
((parent && instancePointer.GetTokenCount() > 0)
|
||||||
? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1)
|
? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1)
|
||||||
: instancePointer)
|
: instancePointer).StringifyUriFragment(sb);
|
||||||
.StringifyUriFragment(sb);
|
|
||||||
ValueType instanceRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
ValueType instanceRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
||||||
GetStateAllocator());
|
GetStateAllocator());
|
||||||
result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
|
result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
|
||||||
@ -2529,10 +2481,8 @@ private:
|
|||||||
GenericStringBuffer<EncodingType> sb;
|
GenericStringBuffer<EncodingType> sb;
|
||||||
SizeType len = CurrentSchema().GetURI().GetStringLength();
|
SizeType len = CurrentSchema().GetURI().GetStringLength();
|
||||||
if (len) memcpy(sb.Push(len), CurrentSchema().GetURI().GetString(), len * sizeof(Ch));
|
if (len) memcpy(sb.Push(len), CurrentSchema().GetURI().GetString(), len * sizeof(Ch));
|
||||||
if (schema.GetTokenCount())
|
if (schema.GetTokenCount()) schema.StringifyUriFragment(sb);
|
||||||
schema.StringifyUriFragment(sb);
|
else GetInvalidSchemaPointer().StringifyUriFragment(sb);
|
||||||
else
|
|
||||||
GetInvalidSchemaPointer().StringifyUriFragment(sb);
|
|
||||||
ValueType schemaRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
ValueType schemaRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
||||||
GetStateAllocator());
|
GetStateAllocator());
|
||||||
result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
|
result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
|
||||||
|
@ -160,16 +160,10 @@ struct GenericStringStream {
|
|||||||
Ch Take() { return *src_++; }
|
Ch Take() { return *src_++; }
|
||||||
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
||||||
|
|
||||||
Ch* PutBegin() {
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
size_t PutEnd(Ch*) {
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Ch* src_; //!< Current read position.
|
const Ch* src_; //!< Current read position.
|
||||||
const Ch* head_; //!< Original head of the string.
|
const Ch* head_; //!< Original head of the string.
|
||||||
@ -202,20 +196,13 @@ struct GenericInsituStringStream {
|
|||||||
size_t Tell() { return static_cast<size_t>(src_ - head_); }
|
size_t Tell() { return static_cast<size_t>(src_ - head_); }
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
void Put(Ch c) {
|
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
|
||||||
RAPIDJSON_ASSERT(dst_ != 0);
|
|
||||||
*dst_++ = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ch* PutBegin() { return dst_ = src_; }
|
Ch* PutBegin() { return dst_ = src_; }
|
||||||
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
|
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
|
||||||
void Flush() {}
|
void Flush() {}
|
||||||
|
|
||||||
Ch* Push(size_t count) {
|
Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
|
||||||
Ch* begin = dst_;
|
|
||||||
dst_ += count;
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
void Pop(size_t count) { dst_ -= count; }
|
void Pop(size_t count) { dst_ -= count; }
|
||||||
|
|
||||||
Ch* src_;
|
Ch* src_;
|
||||||
|
@ -98,12 +98,17 @@ public:
|
|||||||
\param stackAllocator User supplied allocator. If it is null, it will create a private one.
|
\param stackAllocator User supplied allocator. If it is null, it will create a private one.
|
||||||
\param levelDepth Initial capacity of stack.
|
\param levelDepth Initial capacity of stack.
|
||||||
*/
|
*/
|
||||||
explicit Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
explicit
|
||||||
|
Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||||
|
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
||||||
|
|
||||||
explicit Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
explicit
|
||||||
|
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||||
|
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
Writer(Writer&& rhs) : os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
|
Writer(Writer&& rhs) :
|
||||||
|
os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
|
||||||
rhs.os_ = 0;
|
rhs.os_ = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -174,40 +179,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
bool Null() {
|
bool Null() { Prefix(kNullType); return EndValue(WriteNull()); }
|
||||||
Prefix(kNullType);
|
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }
|
||||||
return EndValue(WriteNull());
|
bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); }
|
||||||
}
|
bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); }
|
||||||
bool Bool(bool b) {
|
bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }
|
||||||
Prefix(b ? kTrueType : kFalseType);
|
bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }
|
||||||
return EndValue(WriteBool(b));
|
|
||||||
}
|
|
||||||
bool Int(int i) {
|
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteInt(i));
|
|
||||||
}
|
|
||||||
bool Uint(unsigned u) {
|
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteUint(u));
|
|
||||||
}
|
|
||||||
bool Int64(int64_t i64) {
|
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteInt64(i64));
|
|
||||||
}
|
|
||||||
bool Uint64(uint64_t u64) {
|
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteUint64(u64));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Writes the given \c double value to the stream
|
//! Writes the given \c double value to the stream
|
||||||
/*!
|
/*!
|
||||||
\param d The value to be written.
|
\param d The value to be written.
|
||||||
\return Whether it is succeed.
|
\return Whether it is succeed.
|
||||||
*/
|
*/
|
||||||
bool Double(double d) {
|
bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); }
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteDouble(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
@ -238,7 +222,8 @@ public:
|
|||||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
bool Key(const std::basic_string<Ch>& str) {
|
bool Key(const std::basic_string<Ch>& str)
|
||||||
|
{
|
||||||
return Key(str.data(), SizeType(str.size()));
|
return Key(str.data(), SizeType(str.size()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -310,28 +295,17 @@ protected:
|
|||||||
|
|
||||||
bool WriteNull() {
|
bool WriteNull() {
|
||||||
PutReserve(*os_, 4);
|
PutReserve(*os_, 4);
|
||||||
PutUnsafe(*os_, 'n');
|
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
|
||||||
PutUnsafe(*os_, 'u');
|
|
||||||
PutUnsafe(*os_, 'l');
|
|
||||||
PutUnsafe(*os_, 'l');
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteBool(bool b) {
|
bool WriteBool(bool b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
PutReserve(*os_, 4);
|
PutReserve(*os_, 4);
|
||||||
PutUnsafe(*os_, 't');
|
PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
|
||||||
PutUnsafe(*os_, 'r');
|
|
||||||
PutUnsafe(*os_, 'u');
|
|
||||||
PutUnsafe(*os_, 'e');
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PutReserve(*os_, 5);
|
PutReserve(*os_, 5);
|
||||||
PutUnsafe(*os_, 'f');
|
PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
|
||||||
PutUnsafe(*os_, 'a');
|
|
||||||
PutUnsafe(*os_, 'l');
|
|
||||||
PutUnsafe(*os_, 's');
|
|
||||||
PutUnsafe(*os_, 'e');
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -378,9 +352,7 @@ protected:
|
|||||||
return false;
|
return false;
|
||||||
if (internal::Double(d).IsNan()) {
|
if (internal::Double(d).IsNan()) {
|
||||||
PutReserve(*os_, 3);
|
PutReserve(*os_, 3);
|
||||||
PutUnsafe(*os_, 'N');
|
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||||
PutUnsafe(*os_, 'a');
|
|
||||||
PutUnsafe(*os_, 'N');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (internal::Double(d).Sign()) {
|
if (internal::Double(d).Sign()) {
|
||||||
@ -389,14 +361,8 @@ protected:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
PutReserve(*os_, 8);
|
PutReserve(*os_, 8);
|
||||||
PutUnsafe(*os_, 'I');
|
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
||||||
PutUnsafe(*os_, 'n');
|
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
||||||
PutUnsafe(*os_, 'f');
|
|
||||||
PutUnsafe(*os_, 'i');
|
|
||||||
PutUnsafe(*os_, 'n');
|
|
||||||
PutUnsafe(*os_, 'i');
|
|
||||||
PutUnsafe(*os_, 't');
|
|
||||||
PutUnsafe(*os_, 'y');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +439,9 @@ protected:
|
|||||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) : Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PutUnsafe(*os_, '\"');
|
PutUnsafe(*os_, '\"');
|
||||||
@ -484,29 +452,19 @@ protected:
|
|||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
return RAPIDJSON_LIKELY(is.Tell() < length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteStartObject() {
|
bool WriteStartObject() { os_->Put('{'); return true; }
|
||||||
os_->Put('{');
|
bool WriteEndObject() { os_->Put('}'); return true; }
|
||||||
return true;
|
bool WriteStartArray() { os_->Put('['); return true; }
|
||||||
}
|
bool WriteEndArray() { os_->Put(']'); return true; }
|
||||||
bool WriteEndObject() {
|
|
||||||
os_->Put('}');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool WriteStartArray() {
|
|
||||||
os_->Put('[');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool WriteEndArray() {
|
|
||||||
os_->Put(']');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteRawValue(const Ch* json, size_t length) {
|
bool WriteRawValue(const Ch* json, size_t length) {
|
||||||
PutReserve(*os_, length);
|
PutReserve(*os_, length);
|
||||||
GenericStringStream<SourceEncoding> is(json);
|
GenericStringStream<SourceEncoding> is(json);
|
||||||
while (RAPIDJSON_LIKELY(is.Tell() < length)) {
|
while (RAPIDJSON_LIKELY(is.Tell() < length)) {
|
||||||
RAPIDJSON_ASSERT(is.Peek() != '\0');
|
RAPIDJSON_ASSERT(is.Peek() != '\0');
|
||||||
if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) : Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -592,9 +550,7 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
|||||||
return false;
|
return false;
|
||||||
if (internal::Double(d).IsNan()) {
|
if (internal::Double(d).IsNan()) {
|
||||||
PutReserve(*os_, 3);
|
PutReserve(*os_, 3);
|
||||||
PutUnsafe(*os_, 'N');
|
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||||
PutUnsafe(*os_, 'a');
|
|
||||||
PutUnsafe(*os_, 'N');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (internal::Double(d).Sign()) {
|
if (internal::Double(d).Sign()) {
|
||||||
@ -603,14 +559,8 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
PutReserve(*os_, 8);
|
PutReserve(*os_, 8);
|
||||||
PutUnsafe(*os_, 'I');
|
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
||||||
PutUnsafe(*os_, 'n');
|
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
||||||
PutUnsafe(*os_, 'f');
|
|
||||||
PutUnsafe(*os_, 'i');
|
|
||||||
PutUnsafe(*os_, 'n');
|
|
||||||
PutUnsafe(*os_, 'i');
|
|
||||||
PutUnsafe(*os_, 't');
|
|
||||||
PutUnsafe(*os_, 'y');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,8 +680,7 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
|
|||||||
len = 8 + (lz >> 3);
|
len = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
len = lz >> 3;
|
len = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
|
@ -16,15 +16,22 @@ struct Backoff {
|
|||||||
double rand01() { return randDistribution(randGenerator); }
|
double rand01() { return randDistribution(randGenerator); }
|
||||||
|
|
||||||
Backoff(int64_t min, int64_t max)
|
Backoff(int64_t min, int64_t max)
|
||||||
: minAmount(min), maxAmount(max), current(min), fails(0), randGenerator((uint64_t)time(0)) {
|
: minAmount(min)
|
||||||
|
, maxAmount(max)
|
||||||
|
, current(min)
|
||||||
|
, fails(0)
|
||||||
|
, randGenerator((uint64_t)time(0))
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset()
|
||||||
|
{
|
||||||
fails = 0;
|
fails = 0;
|
||||||
current = minAmount;
|
current = minAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t nextDelay() {
|
int64_t nextDelay()
|
||||||
|
{
|
||||||
++fails;
|
++fails;
|
||||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
||||||
current = std::min(current + delay, maxAmount);
|
current = std::min(current + delay, maxAmount);
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int GetProcessId() {
|
int GetProcessId()
|
||||||
|
{
|
||||||
return ::getpid();
|
return ::getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +26,8 @@ static int MsgFlags = MSG_NOSIGNAL;
|
|||||||
static int MsgFlags = 0;
|
static int MsgFlags = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char* GetTempPath() {
|
static const char* GetTempPath()
|
||||||
|
{
|
||||||
const char* temp = getenv("XDG_RUNTIME_DIR");
|
const char* temp = getenv("XDG_RUNTIME_DIR");
|
||||||
temp = temp ? temp : getenv("TMPDIR");
|
temp = temp ? temp : getenv("TMPDIR");
|
||||||
temp = temp ? temp : getenv("TMP");
|
temp = temp ? temp : getenv("TMP");
|
||||||
@ -34,18 +36,21 @@ static const char* GetTempPath() {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ BaseConnection* BaseConnection::Create() {
|
/*static*/ BaseConnection* BaseConnection::Create()
|
||||||
|
{
|
||||||
PipeAddr.sun_family = AF_UNIX;
|
PipeAddr.sun_family = AF_UNIX;
|
||||||
return &Connection;
|
return &Connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void BaseConnection::Destroy(BaseConnection*& c) {
|
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionUnix*>(c);
|
auto self = reinterpret_cast<BaseConnectionUnix*>(c);
|
||||||
self->Close();
|
self->Close();
|
||||||
c = nullptr;
|
c = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Open() {
|
bool BaseConnection::Open()
|
||||||
|
{
|
||||||
const char* tempPath = GetTempPath();
|
const char* tempPath = GetTempPath();
|
||||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||||
self->sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
self->sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
@ -71,7 +76,8 @@ bool BaseConnection::Open() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Close() {
|
bool BaseConnection::Close()
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||||
if (self->sock == -1) {
|
if (self->sock == -1) {
|
||||||
return false;
|
return false;
|
||||||
@ -82,7 +88,8 @@ bool BaseConnection::Close() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Write(const void* data, size_t length) {
|
bool BaseConnection::Write(const void* data, size_t length)
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||||
|
|
||||||
if (self->sock == -1) {
|
if (self->sock == -1) {
|
||||||
@ -96,7 +103,8 @@ bool BaseConnection::Write(const void* data, size_t length) {
|
|||||||
return sentBytes == (ssize_t)length;
|
return sentBytes == (ssize_t)length;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Read(void* data, size_t length) {
|
bool BaseConnection::Read(void* data, size_t length)
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||||
|
|
||||||
if (self->sock == -1) {
|
if (self->sock == -1) {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int GetProcessId() {
|
int GetProcessId()
|
||||||
|
{
|
||||||
return (int)::GetCurrentProcessId();
|
return (int)::GetCurrentProcessId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,17 +18,20 @@ struct BaseConnectionWin : public BaseConnection {
|
|||||||
|
|
||||||
static BaseConnectionWin Connection;
|
static BaseConnectionWin Connection;
|
||||||
|
|
||||||
/*static*/ BaseConnection* BaseConnection::Create() {
|
/*static*/ BaseConnection* BaseConnection::Create()
|
||||||
|
{
|
||||||
return &Connection;
|
return &Connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void BaseConnection::Destroy(BaseConnection*& c) {
|
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionWin*>(c);
|
auto self = reinterpret_cast<BaseConnectionWin*>(c);
|
||||||
self->Close();
|
self->Close();
|
||||||
c = nullptr;
|
c = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Open() {
|
bool BaseConnection::Open()
|
||||||
|
{
|
||||||
wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"};
|
wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"};
|
||||||
const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2;
|
const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2;
|
||||||
pipeName[pipeDigit] = L'0';
|
pipeName[pipeDigit] = L'0';
|
||||||
@ -57,7 +61,8 @@ bool BaseConnection::Open() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Close() {
|
bool BaseConnection::Close()
|
||||||
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||||
::CloseHandle(self->pipe);
|
::CloseHandle(self->pipe);
|
||||||
self->pipe = INVALID_HANDLE_VALUE;
|
self->pipe = INVALID_HANDLE_VALUE;
|
||||||
@ -65,7 +70,8 @@ bool BaseConnection::Close() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Write(const void* data, size_t length) {
|
bool BaseConnection::Write(const void* data, size_t length)
|
||||||
|
{
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -87,7 +93,8 @@ bool BaseConnection::Write(const void* data, size_t length) {
|
|||||||
bytesWritten == bytesLength;
|
bytesWritten == bytesLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseConnection::Read(void* data, size_t length) {
|
bool BaseConnection::Read(void* data, size_t length)
|
||||||
|
{
|
||||||
assert(data);
|
assert(data);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static bool Mkdir(const char* path) {
|
static bool Mkdir(const char* path)
|
||||||
|
{
|
||||||
int result = mkdir(path, 0755);
|
int result = mkdir(path, 0755);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return true;
|
return true;
|
||||||
@ -21,7 +22,8 @@ static bool Mkdir(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we want to register games so we can run them from Discord client as discord-<appid>://
|
// we want to register games so we can run them from Discord client as discord-<appid>://
|
||||||
extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) {
|
extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command)
|
||||||
|
{
|
||||||
// Add a desktop file and update some mime handlers so that xdg-open does the right thing.
|
// Add a desktop file and update some mime handlers so that xdg-open does the right thing.
|
||||||
|
|
||||||
const char* home = getenv("HOME");
|
const char* home = getenv("HOME");
|
||||||
@ -92,7 +94,8 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId,
|
extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId,
|
||||||
const char* steamId) {
|
const char* steamId)
|
||||||
|
{
|
||||||
char command[256];
|
char command[256];
|
||||||
sprintf(command, "xdg-open steam://rungameid/%s", steamId);
|
sprintf(command, "xdg-open steam://rungameid/%s", steamId);
|
||||||
Discord_Register(applicationId, command);
|
Discord_Register(applicationId, command);
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
/// strsafe.h fixes
|
/// strsafe.h fixes
|
||||||
static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) {
|
static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...)
|
||||||
|
{
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, pszFormat);
|
va_start(va, pszFormat);
|
||||||
@ -50,7 +51,8 @@ static LSTATUS regset(HKEY hkey,
|
|||||||
LPCWSTR name,
|
LPCWSTR name,
|
||||||
DWORD type,
|
DWORD type,
|
||||||
const void* data,
|
const void* data,
|
||||||
DWORD len) {
|
DWORD len)
|
||||||
|
{
|
||||||
HKEY htkey = hkey, hsubkey = nullptr;
|
HKEY htkey = hkey, hsubkey = nullptr;
|
||||||
LSTATUS ret;
|
LSTATUS ret;
|
||||||
if (subkey && subkey[0]) {
|
if (subkey && subkey[0]) {
|
||||||
@ -65,7 +67,8 @@ static LSTATUS regset(HKEY hkey,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* command) {
|
static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* command)
|
||||||
|
{
|
||||||
// https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
|
||||||
// we want to register games so we can run them as discord-<appid>://
|
// we want to register games so we can run them as discord-<appid>://
|
||||||
// Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions.
|
// Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions.
|
||||||
@ -128,7 +131,8 @@ static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* comma
|
|||||||
RegCloseKey(key);
|
RegCloseKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) {
|
extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command)
|
||||||
|
{
|
||||||
wchar_t appId[32];
|
wchar_t appId[32];
|
||||||
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
||||||
|
|
||||||
@ -144,7 +148,8 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId,
|
extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId,
|
||||||
const char* steamId) {
|
const char* steamId)
|
||||||
|
{
|
||||||
wchar_t appId[32];
|
wchar_t appId[32];
|
||||||
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@ struct QueuedMessage {
|
|||||||
size_t length;
|
size_t length;
|
||||||
char buffer[MaxMessageSize];
|
char buffer[MaxMessageSize];
|
||||||
|
|
||||||
void Copy(const QueuedMessage& other) {
|
void Copy(const QueuedMessage& other)
|
||||||
|
{
|
||||||
length = other.length;
|
length = other.length;
|
||||||
if (length) {
|
if (length) {
|
||||||
memcpy(buffer, other.buffer, length);
|
memcpy(buffer, other.buffer, length);
|
||||||
@ -84,7 +85,8 @@ private:
|
|||||||
std::thread ioThread;
|
std::thread ioThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Start() {
|
void Start()
|
||||||
|
{
|
||||||
keepRunning.store(true);
|
keepRunning.store(true);
|
||||||
ioThread = std::thread([&]() {
|
ioThread = std::thread([&]() {
|
||||||
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
||||||
@ -99,7 +101,8 @@ public:
|
|||||||
|
|
||||||
void Notify() { waitForIOActivity.notify_all(); }
|
void Notify() { waitForIOActivity.notify_all(); }
|
||||||
|
|
||||||
void Stop() {
|
void Stop()
|
||||||
|
{
|
||||||
keepRunning.exchange(false);
|
keepRunning.exchange(false);
|
||||||
Notify();
|
Notify();
|
||||||
if (ioThread.joinable()) {
|
if (ioThread.joinable()) {
|
||||||
@ -119,7 +122,8 @@ public:
|
|||||||
#endif // DISCORD_DISABLE_IO_THREAD
|
#endif // DISCORD_DISABLE_IO_THREAD
|
||||||
static IoThreadHolder* IoThread{nullptr};
|
static IoThreadHolder* IoThread{nullptr};
|
||||||
|
|
||||||
static void UpdateReconnectTime() {
|
static void UpdateReconnectTime()
|
||||||
|
{
|
||||||
NextConnect = std::chrono::system_clock::now() +
|
NextConnect = std::chrono::system_clock::now() +
|
||||||
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
||||||
}
|
}
|
||||||
@ -233,13 +237,15 @@ static void Discord_UpdateConnection(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SignalIOActivity() {
|
static void SignalIOActivity()
|
||||||
|
{
|
||||||
if (IoThread != nullptr) {
|
if (IoThread != nullptr) {
|
||||||
IoThread->Notify();
|
IoThread->Notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RegisterForEvent(const char* evtName) {
|
static bool RegisterForEvent(const char* evtName)
|
||||||
|
{
|
||||||
auto qmessage = SendQueue.GetNextAddMessage();
|
auto qmessage = SendQueue.GetNextAddMessage();
|
||||||
if (qmessage) {
|
if (qmessage) {
|
||||||
qmessage->length =
|
qmessage->length =
|
||||||
@ -251,7 +257,8 @@ static bool RegisterForEvent(const char* evtName) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DeregisterForEvent(const char* evtName) {
|
static bool DeregisterForEvent(const char* evtName)
|
||||||
|
{
|
||||||
auto qmessage = SendQueue.GetNextAddMessage();
|
auto qmessage = SendQueue.GetNextAddMessage();
|
||||||
if (qmessage) {
|
if (qmessage) {
|
||||||
qmessage->length =
|
qmessage->length =
|
||||||
@ -266,7 +273,8 @@ static bool DeregisterForEvent(const char* evtName) {
|
|||||||
extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
DiscordEventHandlers* handlers,
|
DiscordEventHandlers* handlers,
|
||||||
int autoRegister,
|
int autoRegister,
|
||||||
const char* optionalSteamId) {
|
const char* optionalSteamId)
|
||||||
|
{
|
||||||
IoThread = new (std::nothrow) IoThreadHolder();
|
IoThread = new (std::nothrow) IoThreadHolder();
|
||||||
if (IoThread == nullptr) {
|
if (IoThread == nullptr) {
|
||||||
return;
|
return;
|
||||||
@ -339,7 +347,8 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
|||||||
IoThread->Start();
|
IoThread->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_Shutdown(void) {
|
extern "C" DISCORD_EXPORT void Discord_Shutdown(void)
|
||||||
|
{
|
||||||
if (!Connection) {
|
if (!Connection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -357,7 +366,8 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void) {
|
|||||||
RpcConnection::Destroy(Connection);
|
RpcConnection::Destroy(Connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence) {
|
extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
QueuedPresence.length = JsonWriteRichPresenceObj(
|
QueuedPresence.length = JsonWriteRichPresenceObj(
|
||||||
@ -367,11 +377,13 @@ extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence*
|
|||||||
SignalIOActivity();
|
SignalIOActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_ClearPresence(void) {
|
extern "C" DISCORD_EXPORT void Discord_ClearPresence(void)
|
||||||
|
{
|
||||||
Discord_UpdatePresence(nullptr);
|
Discord_UpdatePresence(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply) {
|
extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply)
|
||||||
|
{
|
||||||
// if we are not connected, let's not batch up stale messages for later
|
// if we are not connected, let's not batch up stale messages for later
|
||||||
if (!Connection || !Connection->IsOpen()) {
|
if (!Connection || !Connection->IsOpen()) {
|
||||||
return;
|
return;
|
||||||
@ -385,7 +397,8 @@ extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_RE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void) {
|
extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
|
||||||
|
{
|
||||||
// Note on some weirdness: internally we might connect, get other signals, disconnect any number
|
// Note on some weirdness: internally we might connect, get other signals, disconnect any number
|
||||||
// of times inbetween calls here. Externally, we want the sequence to seem sane, so any other
|
// of times inbetween calls here. Externally, we want the sequence to seem sane, so any other
|
||||||
// signals are book-ended by calls to ready and disconnect.
|
// signals are book-ended by calls to ready and disconnect.
|
||||||
@ -463,7 +476,8 @@ extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers) {
|
extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers)
|
||||||
|
{
|
||||||
if (newHandlers) {
|
if (newHandlers) {
|
||||||
#define HANDLE_EVENT_REGISTRATION(handler_name, event) \
|
#define HANDLE_EVENT_REGISTRATION(handler_name, event) \
|
||||||
if (!Handlers.handler_name && newHandlers->handler_name) { \
|
if (!Handlers.handler_name && newHandlers->handler_name) { \
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
// outsmart GCC's missing-declarations warning
|
// outsmart GCC's missing-declarations warning
|
||||||
BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID);
|
BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID);
|
||||||
BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID) {
|
BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID)
|
||||||
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ class MsgQueue {
|
|||||||
public:
|
public:
|
||||||
MsgQueue() {}
|
MsgQueue() {}
|
||||||
|
|
||||||
ElementType* GetNextAddMessage() {
|
ElementType* GetNextAddMessage()
|
||||||
|
{
|
||||||
// if we are falling behind, bail
|
// if we are falling behind, bail
|
||||||
if (pendingSends_.load() >= QueueSize) {
|
if (pendingSends_.load() >= QueueSize) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -26,7 +27,8 @@ public:
|
|||||||
void CommitAdd() { ++pendingSends_; }
|
void CommitAdd() { ++pendingSends_; }
|
||||||
|
|
||||||
bool HavePendingSends() const { return pendingSends_.load() != 0; }
|
bool HavePendingSends() const { return pendingSends_.load() != 0; }
|
||||||
ElementType* GetNextSendMessage() {
|
ElementType* GetNextSendMessage()
|
||||||
|
{
|
||||||
auto index = (nextSend_++) % QueueSize;
|
auto index = (nextSend_++) % QueueSize;
|
||||||
return &queue_[index];
|
return &queue_[index];
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,22 @@
|
|||||||
static const int RpcVersion = 1;
|
static const int RpcVersion = 1;
|
||||||
static RpcConnection Instance;
|
static RpcConnection Instance;
|
||||||
|
|
||||||
/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) {
|
/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId)
|
||||||
|
{
|
||||||
Instance.connection = BaseConnection::Create();
|
Instance.connection = BaseConnection::Create();
|
||||||
StringCopy(Instance.appId, applicationId);
|
StringCopy(Instance.appId, applicationId);
|
||||||
return &Instance;
|
return &Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void RpcConnection::Destroy(RpcConnection*& c) {
|
/*static*/ void RpcConnection::Destroy(RpcConnection*& c)
|
||||||
|
{
|
||||||
c->Close();
|
c->Close();
|
||||||
BaseConnection::Destroy(c->connection);
|
BaseConnection::Destroy(c->connection);
|
||||||
c = nullptr;
|
c = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RpcConnection::Open() {
|
void RpcConnection::Open()
|
||||||
|
{
|
||||||
if (state == State::Connected) {
|
if (state == State::Connected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -54,7 +57,8 @@ void RpcConnection::Open() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RpcConnection::Close() {
|
void RpcConnection::Close()
|
||||||
|
{
|
||||||
if (onDisconnect && (state == State::Connected || state == State::SentHandshake)) {
|
if (onDisconnect && (state == State::Connected || state == State::SentHandshake)) {
|
||||||
onDisconnect(lastErrorCode, lastErrorMessage);
|
onDisconnect(lastErrorCode, lastErrorMessage);
|
||||||
}
|
}
|
||||||
@ -62,7 +66,8 @@ void RpcConnection::Close() {
|
|||||||
state = State::Disconnected;
|
state = State::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RpcConnection::Write(const void* data, size_t length) {
|
bool RpcConnection::Write(const void* data, size_t length)
|
||||||
|
{
|
||||||
sendFrame.opcode = Opcode::Frame;
|
sendFrame.opcode = Opcode::Frame;
|
||||||
memcpy(sendFrame.message, data, length);
|
memcpy(sendFrame.message, data, length);
|
||||||
sendFrame.length = (uint32_t)length;
|
sendFrame.length = (uint32_t)length;
|
||||||
@ -73,7 +78,8 @@ bool RpcConnection::Write(const void* data, size_t length) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RpcConnection::Read(JsonDocument& message) {
|
bool RpcConnection::Read(JsonDocument& message)
|
||||||
|
{
|
||||||
if (state != State::Connected && state != State::SentHandshake) {
|
if (state != State::Connected && state != State::SentHandshake) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
#include "discord_rpc.h"
|
#include "discord_rpc.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void NumberToString(char* dest, T number) {
|
void NumberToString(char* dest, T number)
|
||||||
|
{
|
||||||
if (!number) {
|
if (!number) {
|
||||||
*dest++ = '0';
|
*dest++ = '0';
|
||||||
*dest++ = 0;
|
*dest++ = 0;
|
||||||
@ -28,19 +29,22 @@ void NumberToString(char* dest, T number) {
|
|||||||
|
|
||||||
// it's ever so slightly faster to not have to strlen the key
|
// it's ever so slightly faster to not have to strlen the key
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void WriteKey(JsonWriter& w, T& k) {
|
void WriteKey(JsonWriter& w, T& k)
|
||||||
|
{
|
||||||
w.Key(k, sizeof(T) - 1);
|
w.Key(k, sizeof(T) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WriteObject {
|
struct WriteObject {
|
||||||
JsonWriter& writer;
|
JsonWriter& writer;
|
||||||
WriteObject(JsonWriter& w)
|
WriteObject(JsonWriter& w)
|
||||||
: writer(w) {
|
: writer(w)
|
||||||
|
{
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
WriteObject(JsonWriter& w, T& name)
|
WriteObject(JsonWriter& w, T& name)
|
||||||
: writer(w) {
|
: writer(w)
|
||||||
|
{
|
||||||
WriteKey(writer, name);
|
WriteKey(writer, name);
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
}
|
}
|
||||||
@ -51,7 +55,8 @@ struct WriteArray {
|
|||||||
JsonWriter& writer;
|
JsonWriter& writer;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
WriteArray(JsonWriter& w, T& name)
|
WriteArray(JsonWriter& w, T& name)
|
||||||
: writer(w) {
|
: writer(w)
|
||||||
|
{
|
||||||
WriteKey(writer, name);
|
WriteKey(writer, name);
|
||||||
writer.StartArray();
|
writer.StartArray();
|
||||||
}
|
}
|
||||||
@ -59,14 +64,16 @@ struct WriteArray {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void WriteOptionalString(JsonWriter& w, T& k, const char* value) {
|
void WriteOptionalString(JsonWriter& w, T& k, const char* value)
|
||||||
|
{
|
||||||
if (value && value[0]) {
|
if (value && value[0]) {
|
||||||
w.Key(k, sizeof(T) - 1);
|
w.Key(k, sizeof(T) - 1);
|
||||||
w.String(value);
|
w.String(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JsonWriteNonce(JsonWriter& writer, int nonce) {
|
static void JsonWriteNonce(JsonWriter& writer, int nonce)
|
||||||
|
{
|
||||||
WriteKey(writer, "nonce");
|
WriteKey(writer, "nonce");
|
||||||
char nonceBuffer[32];
|
char nonceBuffer[32];
|
||||||
NumberToString(nonceBuffer, nonce);
|
NumberToString(nonceBuffer, nonce);
|
||||||
@ -77,7 +84,8 @@ size_t JsonWriteRichPresenceObj(char* dest,
|
|||||||
size_t maxLen,
|
size_t maxLen,
|
||||||
int nonce,
|
int nonce,
|
||||||
int pid,
|
int pid,
|
||||||
const DiscordRichPresence* presence) {
|
const DiscordRichPresence* presence)
|
||||||
|
{
|
||||||
JsonWriter writer(dest, maxLen);
|
JsonWriter writer(dest, maxLen);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -159,7 +167,8 @@ size_t JsonWriteRichPresenceObj(char* dest,
|
|||||||
return writer.Size();
|
return writer.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId) {
|
size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId)
|
||||||
|
{
|
||||||
JsonWriter writer(dest, maxLen);
|
JsonWriter writer(dest, maxLen);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -173,7 +182,8 @@ size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char*
|
|||||||
return writer.Size();
|
return writer.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) {
|
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName)
|
||||||
|
{
|
||||||
JsonWriter writer(dest, maxLen);
|
JsonWriter writer(dest, maxLen);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -191,7 +201,8 @@ size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const cha
|
|||||||
return writer.Size();
|
return writer.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) {
|
size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName)
|
||||||
|
{
|
||||||
JsonWriter writer(dest, maxLen);
|
JsonWriter writer(dest, maxLen);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -209,7 +220,8 @@ size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const c
|
|||||||
return writer.Size();
|
return writer.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce) {
|
size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce)
|
||||||
|
{
|
||||||
JsonWriter writer(dest, maxLen);
|
JsonWriter writer(dest, maxLen);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
// if only there was a standard library function for this
|
// if only there was a standard library function for this
|
||||||
template <size_t Len>
|
template <size_t Len>
|
||||||
inline size_t StringCopy(char (&dest)[Len], const char* src) {
|
inline size_t StringCopy(char (&dest)[Len], const char* src)
|
||||||
|
{
|
||||||
if (!src || !Len) {
|
if (!src || !Len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -57,14 +58,18 @@ class LinearAllocator {
|
|||||||
public:
|
public:
|
||||||
char* buffer_;
|
char* buffer_;
|
||||||
char* end_;
|
char* end_;
|
||||||
LinearAllocator() {
|
LinearAllocator()
|
||||||
|
{
|
||||||
assert(0); // needed for some default case in rapidjson, should not use
|
assert(0); // needed for some default case in rapidjson, should not use
|
||||||
}
|
}
|
||||||
LinearAllocator(char* buffer, size_t size)
|
LinearAllocator(char* buffer, size_t size)
|
||||||
: buffer_(buffer), end_(buffer + size) {
|
: buffer_(buffer)
|
||||||
|
, end_(buffer + size)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static const bool kNeedFree = false;
|
static const bool kNeedFree = false;
|
||||||
void* Malloc(size_t size) {
|
void* Malloc(size_t size)
|
||||||
|
{
|
||||||
char* res = buffer_;
|
char* res = buffer_;
|
||||||
buffer_ += size;
|
buffer_ += size;
|
||||||
if (buffer_ > end_) {
|
if (buffer_ > end_) {
|
||||||
@ -73,7 +78,8 @@ public:
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
|
||||||
|
{
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -84,7 +90,8 @@ public:
|
|||||||
(void)(originalSize);
|
(void)(originalSize);
|
||||||
return Malloc(newSize);
|
return Malloc(newSize);
|
||||||
}
|
}
|
||||||
static void Free(void* ptr) {
|
static void Free(void* ptr)
|
||||||
|
{
|
||||||
/* shrug */
|
/* shrug */
|
||||||
(void)ptr;
|
(void)ptr;
|
||||||
}
|
}
|
||||||
@ -95,7 +102,8 @@ class FixedLinearAllocator : public LinearAllocator {
|
|||||||
public:
|
public:
|
||||||
char fixedBuffer_[Size];
|
char fixedBuffer_[Size];
|
||||||
FixedLinearAllocator()
|
FixedLinearAllocator()
|
||||||
: LinearAllocator(fixedBuffer_, Size) {
|
: LinearAllocator(fixedBuffer_, Size)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static const bool kNeedFree = false;
|
static const bool kNeedFree = false;
|
||||||
};
|
};
|
||||||
@ -109,10 +117,14 @@ public:
|
|||||||
char* current_;
|
char* current_;
|
||||||
|
|
||||||
DirectStringBuffer(char* buffer, size_t maxLen)
|
DirectStringBuffer(char* buffer, size_t maxLen)
|
||||||
: buffer_(buffer), end_(buffer + maxLen), current_(buffer) {
|
: buffer_(buffer)
|
||||||
|
, end_(buffer + maxLen)
|
||||||
|
, current_(buffer)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Put(char c) {
|
void Put(char c)
|
||||||
|
{
|
||||||
if (current_ < end_) {
|
if (current_ < end_) {
|
||||||
*current_++ = c;
|
*current_++ = c;
|
||||||
}
|
}
|
||||||
@ -135,7 +147,10 @@ public:
|
|||||||
StackAllocator stackAlloc_;
|
StackAllocator stackAlloc_;
|
||||||
|
|
||||||
JsonWriter(char* dest, size_t maxLen)
|
JsonWriter(char* dest, size_t maxLen)
|
||||||
: JsonWriterBase(stringBuffer_, &stackAlloc_, WriterNestingLevels), stringBuffer_(dest, maxLen), stackAlloc_() {
|
: JsonWriterBase(stringBuffer_, &stackAlloc_, WriterNestingLevels)
|
||||||
|
, stringBuffer_(dest, maxLen)
|
||||||
|
, stackAlloc_()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Size() const { return stringBuffer_.GetSize(); }
|
size_t Size() const { return stringBuffer_.GetSize(); }
|
||||||
@ -155,14 +170,17 @@ public:
|
|||||||
: JsonDocumentBase(rapidjson::kObjectType,
|
: JsonDocumentBase(rapidjson::kObjectType,
|
||||||
&poolAllocator_,
|
&poolAllocator_,
|
||||||
sizeof(stackAllocator_.fixedBuffer_),
|
sizeof(stackAllocator_.fixedBuffer_),
|
||||||
&stackAllocator_),
|
&stackAllocator_)
|
||||||
poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_), stackAllocator_() {
|
, poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_)
|
||||||
|
, stackAllocator_()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using JsonValue = rapidjson::GenericValue<UTF8, PoolAllocator>;
|
using JsonValue = rapidjson::GenericValue<UTF8, PoolAllocator>;
|
||||||
|
|
||||||
inline JsonValue* GetObjMember(JsonValue* obj, const char* name) {
|
inline JsonValue* GetObjMember(JsonValue* obj, const char* name)
|
||||||
|
{
|
||||||
if (obj) {
|
if (obj) {
|
||||||
auto member = obj->FindMember(name);
|
auto member = obj->FindMember(name);
|
||||||
if (member != obj->MemberEnd() && member->value.IsObject()) {
|
if (member != obj->MemberEnd() && member->value.IsObject()) {
|
||||||
@ -172,7 +190,8 @@ inline JsonValue* GetObjMember(JsonValue* obj, const char* name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0) {
|
inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0)
|
||||||
|
{
|
||||||
if (obj) {
|
if (obj) {
|
||||||
auto member = obj->FindMember(name);
|
auto member = obj->FindMember(name);
|
||||||
if (member != obj->MemberEnd() && member->value.IsInt()) {
|
if (member != obj->MemberEnd() && member->value.IsInt()) {
|
||||||
@ -184,7 +203,8 @@ inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault =
|
|||||||
|
|
||||||
inline const char* GetStrMember(JsonValue* obj,
|
inline const char* GetStrMember(JsonValue* obj,
|
||||||
const char* name,
|
const char* name,
|
||||||
const char* notFoundDefault = nullptr) {
|
const char* notFoundDefault = nullptr)
|
||||||
|
{
|
||||||
if (obj) {
|
if (obj) {
|
||||||
auto member = obj->FindMember(name);
|
auto member = obj->FindMember(name);
|
||||||
if (member != obj->MemberEnd() && member->value.IsString()) {
|
if (member != obj->MemberEnd() && member->value.IsString()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user