mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-17 19:09:56 +00:00
rlottie/json: updated to latest rapidjson
This commit is contained in:
parent
ebfe68ba55
commit
1d4716e03d
@ -52,6 +52,19 @@ concept Allocator {
|
|||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User-defined kDefaultChunkCapacity definition.
|
||||||
|
|
||||||
|
User can define this as any \c size that is a power of 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
|
||||||
|
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// CrtAllocator
|
// CrtAllocator
|
||||||
|
|
||||||
@ -248,7 +261,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
|
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
|
||||||
|
|
||||||
//! Chunk header for perpending to each chunk.
|
//! Chunk header for perpending to each chunk.
|
||||||
/*! Chunks are stored as a singly linked list.
|
/*! Chunks are stored as a singly linked list.
|
||||||
|
@ -26,26 +26,21 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
|
||||||
RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||||
|
RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#if __GNUC__ >= 6
|
|
||||||
RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
|
|
||||||
#endif
|
|
||||||
#endif // __GNUC__
|
#endif // __GNUC__
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||||
#include <iterator> // std::iterator, std::random_access_iterator_tag
|
#include <iterator> // std::random_access_iterator_tag
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
@ -71,6 +66,12 @@ template <typename Encoding, typename Allocator>
|
|||||||
struct GenericMember {
|
struct GenericMember {
|
||||||
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
||||||
GenericValue<Encoding, Allocator> value; //!< value of member.
|
GenericValue<Encoding, Allocator> value; //!< value of member.
|
||||||
|
|
||||||
|
// swap() for std::sort() and other potential use in STL.
|
||||||
|
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
||||||
|
a.name.Swap(b.name);
|
||||||
|
a.value.Swap(b.value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -98,16 +99,13 @@ struct GenericMember {
|
|||||||
\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
|
\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
|
||||||
*/
|
*/
|
||||||
template <bool Const, typename Encoding, typename Allocator>
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
class GenericMemberIterator
|
class GenericMemberIterator {
|
||||||
: public std::iterator<std::random_access_iterator_tag
|
|
||||||
, typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
|
|
||||||
|
|
||||||
friend class GenericValue<Encoding,Allocator>;
|
friend class GenericValue<Encoding,Allocator>;
|
||||||
template <bool, typename, typename> friend class GenericMemberIterator;
|
template <bool, typename, typename> 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;
|
||||||
typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Iterator type itself
|
//! Iterator type itself
|
||||||
@ -117,12 +115,21 @@ public:
|
|||||||
//! Non-constant iterator type
|
//! Non-constant iterator type
|
||||||
typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
|
typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
|
||||||
|
|
||||||
|
/** \name std::iterator_traits support */
|
||||||
|
//@{
|
||||||
|
typedef ValueType value_type;
|
||||||
|
typedef ValueType * pointer;
|
||||||
|
typedef ValueType & reference;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
//@}
|
||||||
|
|
||||||
//! Pointer to (const) GenericMember
|
//! Pointer to (const) GenericMember
|
||||||
typedef typename BaseType::pointer Pointer;
|
typedef pointer Pointer;
|
||||||
//! Reference to (const) GenericMember
|
//! Reference to (const) GenericMember
|
||||||
typedef typename BaseType::reference Reference;
|
typedef reference Reference;
|
||||||
//! Signed integer type (e.g. \c ptrdiff_t)
|
//! Signed integer type (e.g. \c ptrdiff_t)
|
||||||
typedef typename BaseType::difference_type DifferenceType;
|
typedef difference_type DifferenceType;
|
||||||
|
|
||||||
//! Default constructor (singular value)
|
//! Default constructor (singular value)
|
||||||
/*! Creates an iterator pointing to no element.
|
/*! Creates an iterator pointing to no element.
|
||||||
@ -445,6 +452,26 @@ struct TypeHelper<ValueType, unsigned> {
|
|||||||
static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
|
static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
|
||||||
|
template<typename ValueType>
|
||||||
|
struct TypeHelper<ValueType, long> {
|
||||||
|
static bool Is(const ValueType& v) { return v.IsInt(); }
|
||||||
|
static long Get(const ValueType& v) { return v.GetInt(); }
|
||||||
|
static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
|
||||||
|
static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
|
||||||
|
};
|
||||||
|
|
||||||
|
RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
|
||||||
|
template<typename ValueType>
|
||||||
|
struct TypeHelper<ValueType, unsigned long> {
|
||||||
|
static bool Is(const ValueType& v) { return v.IsUint(); }
|
||||||
|
static unsigned long Get(const ValueType& v) { return v.GetUint(); }
|
||||||
|
static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
|
||||||
|
static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
struct TypeHelper<ValueType, int64_t> {
|
struct TypeHelper<ValueType, int64_t> {
|
||||||
static bool Is(const ValueType& v) { return v.IsInt64(); }
|
static bool Is(const ValueType& v) { return v.IsInt64(); }
|
||||||
@ -601,11 +628,11 @@ public:
|
|||||||
\note Default content for number is zero.
|
\note Default content for number is zero.
|
||||||
*/
|
*/
|
||||||
explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
|
explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
|
||||||
static const uint16_t defaultFlags[7] = {
|
static const uint16_t defaultFlags[] = {
|
||||||
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
|
kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
|
||||||
kNumberAnyFlag
|
kNumberAnyFlag
|
||||||
};
|
};
|
||||||
RAPIDJSON_ASSERT(type >= kNullType && type <= kNumberType);
|
RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
|
||||||
data_.f.flags = defaultFlags[type];
|
data_.f.flags = defaultFlags[type];
|
||||||
|
|
||||||
// Use ShortString to store empty string.
|
// Use ShortString to store empty string.
|
||||||
@ -807,9 +834,10 @@ public:
|
|||||||
/*! \param rhs Source of the assignment. It will become a null value after assignment.
|
/*! \param rhs Source of the assignment. It will become a null value after assignment.
|
||||||
*/
|
*/
|
||||||
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
RAPIDJSON_ASSERT(this != &rhs);
|
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||||
this->~GenericValue();
|
this->~GenericValue();
|
||||||
RawAssign(rhs);
|
RawAssign(rhs);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,7 +929,7 @@ public:
|
|||||||
//! Equal-to operator
|
//! Equal-to operator
|
||||||
/*!
|
/*!
|
||||||
\note If an object contains duplicated named member, comparing equality with any object is always \c false.
|
\note If an object contains duplicated named member, comparing equality with any object is always \c false.
|
||||||
\note Linear time complexity (number of all values in the subtree and total lengths of all strings).
|
\note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings).
|
||||||
*/
|
*/
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator>
|
||||||
bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
|
bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
|
||||||
@ -1090,25 +1118,6 @@ public:
|
|||||||
GenericValue n(StringRef(name));
|
GenericValue n(StringRef(name));
|
||||||
return (*this)[n];
|
return (*this)[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
float optFloat(T* name, float fallback = 0.0) {
|
|
||||||
GenericValue n(StringRef(name));
|
|
||||||
return optFloat(n, fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
double optDouble(T* name, double fallback = 0.0) {
|
|
||||||
GenericValue n(StringRef(name));
|
|
||||||
return optDouble(n, fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
int optInt(T* name, int fallback=0) {
|
|
||||||
GenericValue n(StringRef(name));
|
|
||||||
return optInt(n, fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
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]; }
|
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]; }
|
||||||
|
|
||||||
@ -1138,31 +1147,6 @@ public:
|
|||||||
return *new (buffer) GenericValue();
|
return *new (buffer) GenericValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SourceAllocator>
|
|
||||||
float optFloat(const GenericValue<Encoding, SourceAllocator>& name, float fallback) {
|
|
||||||
MemberIterator member = FindMember(name);
|
|
||||||
if (member != MemberEnd())
|
|
||||||
return member->value.GetFloat();
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename SourceAllocator>
|
|
||||||
double optDouble(const GenericValue<Encoding, SourceAllocator>& name, double fallback) {
|
|
||||||
MemberIterator member = FindMember(name);
|
|
||||||
if (member != MemberEnd())
|
|
||||||
return member->value.GetDouble();
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename SourceAllocator>
|
|
||||||
int optInt(const GenericValue<Encoding, SourceAllocator>& name, int fallback) {
|
|
||||||
MemberIterator member = FindMember(name);
|
|
||||||
if (member != MemberEnd() && member->value.IsInt())
|
|
||||||
return member->value.GetInt();
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator>
|
||||||
const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
|
const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
|
||||||
|
|
||||||
@ -1533,7 +1517,7 @@ public:
|
|||||||
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
||||||
for (MemberIterator itr = pos; itr != last; ++itr)
|
for (MemberIterator itr = pos; itr != last; ++itr)
|
||||||
itr->~Member();
|
itr->~Member();
|
||||||
std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
||||||
data_.o.size -= static_cast<SizeType>(last - first);
|
data_.o.size -= static_cast<SizeType>(last - first);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
@ -1736,8 +1720,8 @@ public:
|
|||||||
RAPIDJSON_ASSERT(last <= End());
|
RAPIDJSON_ASSERT(last <= End());
|
||||||
ValueIterator pos = Begin() + (first - Begin());
|
ValueIterator pos = Begin() + (first - Begin());
|
||||||
for (ValueIterator itr = pos; itr != last; ++itr)
|
for (ValueIterator itr = pos; itr != last; ++itr)
|
||||||
itr->~GenericValue();
|
itr->~GenericValue();
|
||||||
std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
|
std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
|
||||||
data_.a.size -= static_cast<SizeType>(last - first);
|
data_.a.size -= static_cast<SizeType>(last - first);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
@ -2052,7 +2036,7 @@ private:
|
|||||||
if (count) {
|
if (count) {
|
||||||
GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
|
GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
|
||||||
SetElementsPointer(e);
|
SetElementsPointer(e);
|
||||||
std::memcpy(e, values, count * sizeof(GenericValue));
|
std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetElementsPointer(0);
|
SetElementsPointer(0);
|
||||||
@ -2065,7 +2049,7 @@ private:
|
|||||||
if (count) {
|
if (count) {
|
||||||
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
||||||
SetMembersPointer(m);
|
SetMembersPointer(m);
|
||||||
std::memcpy(m, members, count * sizeof(Member));
|
std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetMembersPointer(0);
|
SetMembersPointer(0);
|
||||||
@ -2125,8 +2109,6 @@ private:
|
|||||||
//! GenericValue with UTF8 encoding
|
//! GenericValue with UTF8 encoding
|
||||||
typedef GenericValue<UTF8<> > Value;
|
typedef GenericValue<UTF8<> > Value;
|
||||||
|
|
||||||
typedef GenericValue<UTF8<> > JsonObj;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// GenericDocument
|
// GenericDocument
|
||||||
|
|
||||||
@ -2402,7 +2384,7 @@ public:
|
|||||||
//!@name Handling parse errors
|
//!@name Handling parse errors
|
||||||
//!@{
|
//!@{
|
||||||
|
|
||||||
//! Whether a parse error has occured in the last parsing.
|
//! Whether a parse error has occurred in the last parsing.
|
||||||
bool HasParseError() const { return parseResult_.IsError(); }
|
bool HasParseError() const { return parseResult_.IsError(); }
|
||||||
|
|
||||||
//! Get the \ref ParseErrorCode of last parsing.
|
//! Get the \ref ParseErrorCode of last parsing.
|
||||||
@ -2522,8 +2504,6 @@ private:
|
|||||||
|
|
||||||
//! GenericDocument with UTF8 encoding
|
//! GenericDocument with UTF8 encoding
|
||||||
typedef GenericDocument<UTF8<> > Document;
|
typedef GenericDocument<UTF8<> > Document;
|
||||||
typedef GenericDocument<UTF8<> > JsonDoc;
|
|
||||||
|
|
||||||
|
|
||||||
//! Helper class for accessing Value of array type.
|
//! Helper class for accessing Value of array type.
|
||||||
/*!
|
/*!
|
||||||
@ -2547,7 +2527,7 @@ public:
|
|||||||
|
|
||||||
GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
|
GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
|
||||||
GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
|
GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
|
||||||
~GenericArray() = default;
|
~GenericArray() {}
|
||||||
|
|
||||||
SizeType Size() const { return value_.Size(); }
|
SizeType Size() const { return value_.Size(); }
|
||||||
SizeType Capacity() const { return value_.Capacity(); }
|
SizeType Capacity() const { return value_.Capacity(); }
|
||||||
@ -2602,7 +2582,7 @@ public:
|
|||||||
|
|
||||||
GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
|
GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
|
||||||
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
|
||||||
~GenericObject() = default;
|
~GenericObject() {}
|
||||||
|
|
||||||
SizeType MemberCount() const { return value_.MemberCount(); }
|
SizeType MemberCount() const { return value_.MemberCount(); }
|
||||||
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
SizeType MemberCapacity() const { return value_.MemberCapacity(); }
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "rapidjson.h"
|
#include "rapidjson.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
|
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
|
||||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
||||||
@ -144,9 +144,9 @@ struct UTF8 {
|
|||||||
|
|
||||||
template <typename InputStream>
|
template <typename InputStream>
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||||
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
||||||
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
||||||
#define TAIL() COPY(); TRANS(0x70)
|
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
||||||
typename InputStream::Ch c = is.Take();
|
typename InputStream::Ch c = is.Take();
|
||||||
if (!(c & 0x80)) {
|
if (!(c & 0x80)) {
|
||||||
*codepoint = static_cast<unsigned char>(c);
|
*codepoint = static_cast<unsigned char>(c);
|
||||||
@ -161,44 +161,44 @@ struct UTF8 {
|
|||||||
}
|
}
|
||||||
bool result = true;
|
bool result = true;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 2: TAIL(); return result;
|
case 2: RAPIDJSON_TAIL(); return result;
|
||||||
case 3: TAIL(); TAIL(); return result;
|
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 4: COPY(); TRANS(0x50); TAIL(); return result;
|
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
||||||
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
|
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 6: TAIL(); TAIL(); TAIL(); return result;
|
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 10: COPY(); TRANS(0x20); TAIL(); return result;
|
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
||||||
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
|
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
#undef COPY
|
#undef RAPIDJSON_COPY
|
||||||
#undef TRANS
|
#undef RAPIDJSON_TRANS
|
||||||
#undef TAIL
|
#undef RAPIDJSON_TAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
template <typename InputStream, typename OutputStream>
|
||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
static bool Validate(InputStream& is, OutputStream& os) {
|
||||||
#define COPY() os.Put(c = is.Take())
|
#define RAPIDJSON_COPY() os.Put(c = is.Take())
|
||||||
#define 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 TAIL() COPY(); TRANS(0x70)
|
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
||||||
Ch c;
|
Ch c;
|
||||||
COPY();
|
RAPIDJSON_COPY();
|
||||||
if (!(c & 0x80))
|
if (!(c & 0x80))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
switch (GetRange(static_cast<unsigned char>(c))) {
|
switch (GetRange(static_cast<unsigned char>(c))) {
|
||||||
case 2: TAIL(); return result;
|
case 2: RAPIDJSON_TAIL(); return result;
|
||||||
case 3: TAIL(); TAIL(); return result;
|
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 4: COPY(); TRANS(0x50); TAIL(); return result;
|
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
||||||
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
|
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 6: TAIL(); TAIL(); TAIL(); return result;
|
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
case 10: COPY(); TRANS(0x20); TAIL(); return result;
|
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
||||||
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
|
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
#undef COPY
|
#undef RAPIDJSON_COPY
|
||||||
#undef TRANS
|
#undef RAPIDJSON_TRANS
|
||||||
#undef TAIL
|
#undef RAPIDJSON_TAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char GetRange(unsigned char c) {
|
static unsigned char GetRange(unsigned char c) {
|
||||||
@ -709,7 +709,7 @@ struct Transcoder<Encoding, Encoding> {
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
return (current_ + 4 <= bufferLast_) ? current_ : 0;
|
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -25,7 +25,7 @@ RAPIDJSON_DIAG_OFF(unreachable-code)
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
//! Wrapper of C file stream for input using fread().
|
//! Wrapper of C file stream for output using fwrite().
|
||||||
/*!
|
/*!
|
||||||
\note implements Stream concept
|
\note implements Stream concept
|
||||||
*/
|
*/
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
#if defined(_MSC_VER) && !__INTEL_COMPILER && defined(_M_AMD64)
|
||||||
#include <intrin.h> // for _umul128
|
#include <intrin.h> // for _umul128
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
#endif
|
#endif
|
||||||
@ -133,7 +133,7 @@ public:
|
|||||||
RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
|
RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
|
||||||
|
|
||||||
if (interShift == 0) {
|
if (interShift == 0) {
|
||||||
std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
|
std::memmove(digits_ + offset, digits_, count_ * sizeof(Type));
|
||||||
count_ += offset;
|
count_ += offset;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
@ -7,9 +7,9 @@
|
|||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
|
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#define RAPIDJSON_DIYFP_H_
|
#define RAPIDJSON_DIYFP_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
@ -56,7 +57,7 @@ struct DiyFp {
|
|||||||
if (biased_e != 0) {
|
if (biased_e != 0) {
|
||||||
f = significand + kDpHiddenBit;
|
f = significand + kDpHiddenBit;
|
||||||
e = biased_e - kDpExponentBias;
|
e = biased_e - kDpExponentBias;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
f = significand;
|
f = significand;
|
||||||
e = kDpMinExponent + 1;
|
e = kDpMinExponent + 1;
|
||||||
@ -99,6 +100,7 @@ struct DiyFp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DiyFp Normalize() const {
|
DiyFp Normalize() const {
|
||||||
|
RAPIDJSON_ASSERT(f != 0); // https://stackoverflow.com/a/26809183/291737
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
_BitScanReverse64(&index, f);
|
_BitScanReverse64(&index, f);
|
||||||
@ -141,7 +143,16 @@ struct DiyFp {
|
|||||||
double d;
|
double d;
|
||||||
uint64_t u64;
|
uint64_t u64;
|
||||||
}u;
|
}u;
|
||||||
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
|
RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask);
|
||||||
|
if (e < kDpDenormalExponent) {
|
||||||
|
// Underflow.
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (e >= kDpMaxExponent) {
|
||||||
|
// Overflow.
|
||||||
|
return std::numeric_limits<double>::infinity();
|
||||||
|
}
|
||||||
|
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
|
||||||
static_cast<uint64_t>(e + kDpExponentBias);
|
static_cast<uint64_t>(e + kDpExponentBias);
|
||||||
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
||||||
return u.d;
|
return u.d;
|
||||||
@ -220,9 +231,10 @@ inline DiyFp GetCachedPowerByIndex(size_t index) {
|
|||||||
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
|
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
|
||||||
907, 933, 960, 986, 1013, 1039, 1066
|
907, 933, 960, 986, 1013, 1039, 1066
|
||||||
};
|
};
|
||||||
|
RAPIDJSON_ASSERT(index < 87);
|
||||||
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DiyFp GetCachedPower(int e, int* K) {
|
inline DiyFp GetCachedPower(int e, int* K) {
|
||||||
|
|
||||||
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
|
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
|
||||||
@ -238,10 +250,11 @@ inline DiyFp GetCachedPower(int e, int* K) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline DiyFp GetCachedPower10(int exp, int *outExp) {
|
inline DiyFp GetCachedPower10(int exp, int *outExp) {
|
||||||
unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
|
RAPIDJSON_ASSERT(exp >= -348);
|
||||||
*outExp = -348 + static_cast<int>(index) * 8;
|
unsigned index = static_cast<unsigned>(exp + 348) / 8u;
|
||||||
return GetCachedPowerByIndex(index);
|
*outExp = -348 + static_cast<int>(index) * 8;
|
||||||
}
|
return GetCachedPowerByIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
|
@ -22,7 +22,7 @@ namespace internal {
|
|||||||
|
|
||||||
class Double {
|
class Double {
|
||||||
public:
|
public:
|
||||||
Double() = default;
|
Double() {}
|
||||||
Double(double d) : d_(d) {}
|
Double(double d) : d_(d) {}
|
||||||
Double(uint64_t u) : u_(u) {}
|
Double(uint64_t u) : u_(u) {}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
@ -7,9 +7,9 @@
|
|||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ITOA_
|
#ifndef RAPIDJSON_ITOA_
|
||||||
@ -37,12 +37,14 @@ inline const char* GetDigitsLut() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline char* u32toa(uint32_t value, char* buffer) {
|
inline char* u32toa(uint32_t value, char* buffer) {
|
||||||
|
RAPIDJSON_ASSERT(buffer != 0);
|
||||||
|
|
||||||
const char* cDigitsLut = GetDigitsLut();
|
const char* cDigitsLut = GetDigitsLut();
|
||||||
|
|
||||||
if (value < 10000) {
|
if (value < 10000) {
|
||||||
const uint32_t d1 = (value / 100) << 1;
|
const uint32_t d1 = (value / 100) << 1;
|
||||||
const uint32_t d2 = (value % 100) << 1;
|
const uint32_t d2 = (value % 100) << 1;
|
||||||
|
|
||||||
if (value >= 1000)
|
if (value >= 1000)
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
if (value >= 100)
|
if (value >= 100)
|
||||||
@ -55,13 +57,13 @@ inline char* u32toa(uint32_t value, char* buffer) {
|
|||||||
// value = bbbbcccc
|
// value = bbbbcccc
|
||||||
const uint32_t b = value / 10000;
|
const uint32_t b = value / 10000;
|
||||||
const uint32_t c = value % 10000;
|
const uint32_t c = value % 10000;
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
const uint32_t d1 = (b / 100) << 1;
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
const uint32_t d2 = (b % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
const uint32_t d3 = (c / 100) << 1;
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
const uint32_t d4 = (c % 100) << 1;
|
||||||
|
|
||||||
if (value >= 10000000)
|
if (value >= 10000000)
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
if (value >= 1000000)
|
if (value >= 1000000)
|
||||||
@ -69,7 +71,7 @@ inline char* u32toa(uint32_t value, char* buffer) {
|
|||||||
if (value >= 100000)
|
if (value >= 100000)
|
||||||
*buffer++ = cDigitsLut[d2];
|
*buffer++ = cDigitsLut[d2];
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
*buffer++ = cDigitsLut[d2 + 1];
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
*buffer++ = cDigitsLut[d3];
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
*buffer++ = cDigitsLut[d3 + 1];
|
||||||
*buffer++ = cDigitsLut[d4];
|
*buffer++ = cDigitsLut[d4];
|
||||||
@ -77,10 +79,10 @@ inline char* u32toa(uint32_t value, char* buffer) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// value = aabbbbcccc in decimal
|
// value = aabbbbcccc in decimal
|
||||||
|
|
||||||
const uint32_t a = value / 100000000; // 1 to 42
|
const uint32_t a = value / 100000000; // 1 to 42
|
||||||
value %= 100000000;
|
value %= 100000000;
|
||||||
|
|
||||||
if (a >= 10) {
|
if (a >= 10) {
|
||||||
const unsigned i = a << 1;
|
const unsigned i = a << 1;
|
||||||
*buffer++ = cDigitsLut[i];
|
*buffer++ = cDigitsLut[i];
|
||||||
@ -91,13 +93,13 @@ inline char* u32toa(uint32_t value, char* buffer) {
|
|||||||
|
|
||||||
const uint32_t b = value / 10000; // 0 to 9999
|
const uint32_t b = value / 10000; // 0 to 9999
|
||||||
const uint32_t c = value % 10000; // 0 to 9999
|
const uint32_t c = value % 10000; // 0 to 9999
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
const uint32_t d1 = (b / 100) << 1;
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
const uint32_t d2 = (b % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
const uint32_t d3 = (c / 100) << 1;
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
const uint32_t d4 = (c % 100) << 1;
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
*buffer++ = cDigitsLut[d1 + 1];
|
||||||
*buffer++ = cDigitsLut[d2];
|
*buffer++ = cDigitsLut[d2];
|
||||||
@ -111,6 +113,7 @@ inline char* u32toa(uint32_t value, char* buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline char* i32toa(int32_t value, char* buffer) {
|
inline char* i32toa(int32_t value, char* buffer) {
|
||||||
|
RAPIDJSON_ASSERT(buffer != 0);
|
||||||
uint32_t u = static_cast<uint32_t>(value);
|
uint32_t u = static_cast<uint32_t>(value);
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
*buffer++ = '-';
|
*buffer++ = '-';
|
||||||
@ -121,6 +124,7 @@ inline char* i32toa(int32_t value, char* buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline char* u64toa(uint64_t value, char* buffer) {
|
inline char* u64toa(uint64_t value, char* buffer) {
|
||||||
|
RAPIDJSON_ASSERT(buffer != 0);
|
||||||
const char* cDigitsLut = GetDigitsLut();
|
const char* cDigitsLut = GetDigitsLut();
|
||||||
const uint64_t kTen8 = 100000000;
|
const uint64_t kTen8 = 100000000;
|
||||||
const uint64_t kTen9 = kTen8 * 10;
|
const uint64_t kTen9 = kTen8 * 10;
|
||||||
@ -131,13 +135,13 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
const uint64_t kTen14 = kTen8 * 1000000;
|
const uint64_t kTen14 = kTen8 * 1000000;
|
||||||
const uint64_t kTen15 = kTen8 * 10000000;
|
const uint64_t kTen15 = kTen8 * 10000000;
|
||||||
const uint64_t kTen16 = kTen8 * kTen8;
|
const uint64_t kTen16 = kTen8 * kTen8;
|
||||||
|
|
||||||
if (value < kTen8) {
|
if (value < kTen8) {
|
||||||
uint32_t v = static_cast<uint32_t>(value);
|
uint32_t v = static_cast<uint32_t>(value);
|
||||||
if (v < 10000) {
|
if (v < 10000) {
|
||||||
const uint32_t d1 = (v / 100) << 1;
|
const uint32_t d1 = (v / 100) << 1;
|
||||||
const uint32_t d2 = (v % 100) << 1;
|
const uint32_t d2 = (v % 100) << 1;
|
||||||
|
|
||||||
if (v >= 1000)
|
if (v >= 1000)
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
if (v >= 100)
|
if (v >= 100)
|
||||||
@ -150,13 +154,13 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
// value = bbbbcccc
|
// value = bbbbcccc
|
||||||
const uint32_t b = v / 10000;
|
const uint32_t b = v / 10000;
|
||||||
const uint32_t c = v % 10000;
|
const uint32_t c = v % 10000;
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
const uint32_t d1 = (b / 100) << 1;
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
const uint32_t d2 = (b % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
const uint32_t d3 = (c / 100) << 1;
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
const uint32_t d4 = (c % 100) << 1;
|
||||||
|
|
||||||
if (value >= 10000000)
|
if (value >= 10000000)
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
if (value >= 1000000)
|
if (value >= 1000000)
|
||||||
@ -164,7 +168,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
if (value >= 100000)
|
if (value >= 100000)
|
||||||
*buffer++ = cDigitsLut[d2];
|
*buffer++ = cDigitsLut[d2];
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
*buffer++ = cDigitsLut[d2 + 1];
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
*buffer++ = cDigitsLut[d3];
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
*buffer++ = cDigitsLut[d3 + 1];
|
||||||
*buffer++ = cDigitsLut[d4];
|
*buffer++ = cDigitsLut[d4];
|
||||||
@ -174,22 +178,22 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
else if (value < kTen16) {
|
else if (value < kTen16) {
|
||||||
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
||||||
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
||||||
|
|
||||||
const uint32_t b0 = v0 / 10000;
|
const uint32_t b0 = v0 / 10000;
|
||||||
const uint32_t c0 = v0 % 10000;
|
const uint32_t c0 = v0 % 10000;
|
||||||
|
|
||||||
const uint32_t d1 = (b0 / 100) << 1;
|
const uint32_t d1 = (b0 / 100) << 1;
|
||||||
const uint32_t d2 = (b0 % 100) << 1;
|
const uint32_t d2 = (b0 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d3 = (c0 / 100) << 1;
|
const uint32_t d3 = (c0 / 100) << 1;
|
||||||
const uint32_t d4 = (c0 % 100) << 1;
|
const uint32_t d4 = (c0 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t b1 = v1 / 10000;
|
const uint32_t b1 = v1 / 10000;
|
||||||
const uint32_t c1 = v1 % 10000;
|
const uint32_t c1 = v1 % 10000;
|
||||||
|
|
||||||
const uint32_t d5 = (b1 / 100) << 1;
|
const uint32_t d5 = (b1 / 100) << 1;
|
||||||
const uint32_t d6 = (b1 % 100) << 1;
|
const uint32_t d6 = (b1 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d7 = (c1 / 100) << 1;
|
const uint32_t d7 = (c1 / 100) << 1;
|
||||||
const uint32_t d8 = (c1 % 100) << 1;
|
const uint32_t d8 = (c1 % 100) << 1;
|
||||||
|
|
||||||
@ -207,9 +211,8 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
*buffer++ = cDigitsLut[d3 + 1];
|
*buffer++ = cDigitsLut[d3 + 1];
|
||||||
if (value >= kTen9)
|
if (value >= kTen9)
|
||||||
*buffer++ = cDigitsLut[d4];
|
*buffer++ = cDigitsLut[d4];
|
||||||
if (value >= kTen8)
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
*buffer++ = cDigitsLut[d4 + 1];
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d5];
|
*buffer++ = cDigitsLut[d5];
|
||||||
*buffer++ = cDigitsLut[d5 + 1];
|
*buffer++ = cDigitsLut[d5 + 1];
|
||||||
*buffer++ = cDigitsLut[d6];
|
*buffer++ = cDigitsLut[d6];
|
||||||
@ -222,7 +225,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
else {
|
else {
|
||||||
const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
|
const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
|
||||||
value %= kTen16;
|
value %= kTen16;
|
||||||
|
|
||||||
if (a < 10)
|
if (a < 10)
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
|
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
|
||||||
else if (a < 100) {
|
else if (a < 100) {
|
||||||
@ -232,7 +235,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
}
|
}
|
||||||
else if (a < 1000) {
|
else if (a < 1000) {
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
|
*buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
|
||||||
|
|
||||||
const uint32_t i = (a % 100) << 1;
|
const uint32_t i = (a % 100) << 1;
|
||||||
*buffer++ = cDigitsLut[i];
|
*buffer++ = cDigitsLut[i];
|
||||||
*buffer++ = cDigitsLut[i + 1];
|
*buffer++ = cDigitsLut[i + 1];
|
||||||
@ -245,28 +248,28 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
*buffer++ = cDigitsLut[j];
|
*buffer++ = cDigitsLut[j];
|
||||||
*buffer++ = cDigitsLut[j + 1];
|
*buffer++ = cDigitsLut[j + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
||||||
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
||||||
|
|
||||||
const uint32_t b0 = v0 / 10000;
|
const uint32_t b0 = v0 / 10000;
|
||||||
const uint32_t c0 = v0 % 10000;
|
const uint32_t c0 = v0 % 10000;
|
||||||
|
|
||||||
const uint32_t d1 = (b0 / 100) << 1;
|
const uint32_t d1 = (b0 / 100) << 1;
|
||||||
const uint32_t d2 = (b0 % 100) << 1;
|
const uint32_t d2 = (b0 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d3 = (c0 / 100) << 1;
|
const uint32_t d3 = (c0 / 100) << 1;
|
||||||
const uint32_t d4 = (c0 % 100) << 1;
|
const uint32_t d4 = (c0 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t b1 = v1 / 10000;
|
const uint32_t b1 = v1 / 10000;
|
||||||
const uint32_t c1 = v1 % 10000;
|
const uint32_t c1 = v1 % 10000;
|
||||||
|
|
||||||
const uint32_t d5 = (b1 / 100) << 1;
|
const uint32_t d5 = (b1 / 100) << 1;
|
||||||
const uint32_t d6 = (b1 % 100) << 1;
|
const uint32_t d6 = (b1 % 100) << 1;
|
||||||
|
|
||||||
const uint32_t d7 = (c1 / 100) << 1;
|
const uint32_t d7 = (c1 / 100) << 1;
|
||||||
const uint32_t d8 = (c1 % 100) << 1;
|
const uint32_t d8 = (c1 % 100) << 1;
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
*buffer++ = cDigitsLut[d1];
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
*buffer++ = cDigitsLut[d1 + 1];
|
||||||
*buffer++ = cDigitsLut[d2];
|
*buffer++ = cDigitsLut[d2];
|
||||||
@ -284,11 +287,12 @@ inline char* u64toa(uint64_t value, char* buffer) {
|
|||||||
*buffer++ = cDigitsLut[d8];
|
*buffer++ = cDigitsLut[d8];
|
||||||
*buffer++ = cDigitsLut[d8 + 1];
|
*buffer++ = cDigitsLut[d8 + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* i64toa(int64_t value, char* buffer) {
|
inline char* i64toa(int64_t value, char* buffer) {
|
||||||
|
RAPIDJSON_ASSERT(buffer != 0);
|
||||||
uint64_t u = static_cast<uint64_t>(value);
|
uint64_t u = static_cast<uint64_t>(value);
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
*buffer++ = '-';
|
*buffer++ = '-';
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#endif
|
#endif
|
||||||
#if defined(_MSC_VER)
|
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(6334)
|
RAPIDJSON_DIAG_OFF(6334)
|
||||||
#endif
|
#endif
|
||||||
@ -174,7 +175,11 @@ template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type;
|
|||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
//@endcond
|
//@endcond
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ RAPIDJSON_DIAG_PUSH
|
|||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -34,11 +37,6 @@ RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||||
#define RAPIDJSON_REGEX_VERBOSE 0
|
#define RAPIDJSON_REGEX_VERBOSE 0
|
||||||
#endif
|
#endif
|
||||||
@ -120,7 +118,8 @@ public:
|
|||||||
template <typename, typename> friend class GenericRegexSearch;
|
template <typename, typename> friend class GenericRegexSearch;
|
||||||
|
|
||||||
GenericRegex(const Ch* source, Allocator* allocator = 0) :
|
GenericRegex(const Ch* source, Allocator* allocator = 0) :
|
||||||
states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_),
|
||||||
|
states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
||||||
anchorBegin_(), anchorEnd_()
|
anchorBegin_(), anchorEnd_()
|
||||||
{
|
{
|
||||||
GenericStringStream<Encoding> ss(source);
|
GenericStringStream<Encoding> ss(source);
|
||||||
@ -128,7 +127,10 @@ public:
|
|||||||
Parse(ds);
|
Parse(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GenericRegex() {}
|
~GenericRegex()
|
||||||
|
{
|
||||||
|
RAPIDJSON_DELETE(ownAllocator_);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValid() const {
|
bool IsValid() const {
|
||||||
return root_ != kRegexInvalidState;
|
return root_ != kRegexInvalidState;
|
||||||
@ -190,10 +192,9 @@ private:
|
|||||||
|
|
||||||
template <typename InputStream>
|
template <typename InputStream>
|
||||||
void Parse(DecodedStream<InputStream, Encoding>& ds) {
|
void Parse(DecodedStream<InputStream, Encoding>& ds) {
|
||||||
Allocator allocator;
|
Stack<Allocator> operandStack(allocator_, 256); // Frag
|
||||||
Stack<Allocator> operandStack(&allocator, 256); // Frag
|
Stack<Allocator> operatorStack(allocator_, 256); // Operator
|
||||||
Stack<Allocator> operatorStack(&allocator, 256); // Operator
|
Stack<Allocator> atomCountStack(allocator_, 256); // unsigned (Atom per parenthesis)
|
||||||
Stack<Allocator> atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis)
|
|
||||||
|
|
||||||
*atomCountStack.template Push<unsigned>() = 0;
|
*atomCountStack.template Push<unsigned>() = 0;
|
||||||
|
|
||||||
@ -394,8 +395,7 @@ private:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
case kOneOrMore:
|
||||||
RAPIDJSON_ASSERT(op == kOneOrMore);
|
|
||||||
if (operandStack.GetSize() >= sizeof(Frag)) {
|
if (operandStack.GetSize() >= sizeof(Frag)) {
|
||||||
Frag e = *operandStack.template Pop<Frag>(1);
|
Frag e = *operandStack.template Pop<Frag>(1);
|
||||||
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
||||||
@ -404,6 +404,10 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// syntax error (e.g. unclosed kLeftParenthesis)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,6 +588,8 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Allocator* ownAllocator_;
|
||||||
|
Allocator* allocator_;
|
||||||
Stack<Allocator> states_;
|
Stack<Allocator> states_;
|
||||||
Stack<Allocator> ranges_;
|
Stack<Allocator> ranges_;
|
||||||
SizeType root_;
|
SizeType root_;
|
||||||
@ -723,11 +729,11 @@ typedef GenericRegexSearch<Regex> RegexSearch;
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(__clang__) || defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../allocators.h"
|
#include "../allocators.h"
|
||||||
#include "swap.h"
|
#include "swap.h"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
@ -100,7 +101,7 @@ public:
|
|||||||
void ShrinkToFit() {
|
void ShrinkToFit() {
|
||||||
if (Empty()) {
|
if (Empty()) {
|
||||||
// If the stack is empty, completely deallocate the memory.
|
// If the stack is empty, completely deallocate the memory.
|
||||||
Allocator::Free(stack_);
|
Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
|
||||||
stack_ = 0;
|
stack_ = 0;
|
||||||
stackTop_ = 0;
|
stackTop_ = 0;
|
||||||
stackEnd_ = 0;
|
stackEnd_ = 0;
|
||||||
@ -114,7 +115,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
||||||
// Expand the stack if needed
|
// Expand the stack if needed
|
||||||
if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
|
if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
|
||||||
Expand<T>(count);
|
Expand<T>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
||||||
RAPIDJSON_ASSERT(stackTop_);
|
RAPIDJSON_ASSERT(stackTop_);
|
||||||
RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
|
RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
|
||||||
T* ret = reinterpret_cast<T*>(stackTop_);
|
T* ret = reinterpret_cast<T*>(stackTop_);
|
||||||
stackTop_ += sizeof(T) * count;
|
stackTop_ += sizeof(T) * count;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include "biginteger.h"
|
#include "biginteger.h"
|
||||||
#include "diyfp.h"
|
#include "diyfp.h"
|
||||||
#include "pow10.h"
|
#include "pow10.h"
|
||||||
|
#include <climits>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -126,20 +128,20 @@ inline bool StrtodFast(double d, int p, double* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute an approximation and see if it is within 1/2 ULP
|
// Compute an approximation and see if it is within 1/2 ULP
|
||||||
inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
|
inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result) {
|
||||||
uint64_t significand = 0;
|
uint64_t significand = 0;
|
||||||
size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
||||||
for (; i < length; i++) {
|
for (; i < dLen; i++) {
|
||||||
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
|
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
|
||||||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
|
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
|
||||||
break;
|
break;
|
||||||
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
|
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < length && decimals[i] >= '5') // Rounding
|
if (i < dLen && decimals[i] >= '5') // Rounding
|
||||||
significand++;
|
significand++;
|
||||||
|
|
||||||
size_t remaining = length - i;
|
int remaining = dLen - i;
|
||||||
const int kUlpShift = 3;
|
const int kUlpShift = 3;
|
||||||
const int kUlp = 1 << kUlpShift;
|
const int kUlp = 1 << kUlpShift;
|
||||||
int64_t error = (remaining == 0) ? 0 : kUlp / 2;
|
int64_t error = (remaining == 0) ? 0 : kUlp / 2;
|
||||||
@ -148,24 +150,24 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||||||
v = v.Normalize();
|
v = v.Normalize();
|
||||||
error <<= -v.e;
|
error <<= -v.e;
|
||||||
|
|
||||||
const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
|
dExp += remaining;
|
||||||
|
|
||||||
int actualExp;
|
int actualExp;
|
||||||
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
|
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
|
||||||
if (actualExp != dExp) {
|
if (actualExp != dExp) {
|
||||||
static const DiyFp kPow10[] = {
|
static const DiyFp kPow10[] = {
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1
|
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2
|
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3
|
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4
|
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5
|
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
|
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
|
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7
|
||||||
};
|
};
|
||||||
int adjustment = dExp - actualExp - 1;
|
int adjustment = dExp - actualExp;
|
||||||
RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
|
RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8);
|
||||||
v = v * kPow10[adjustment];
|
v = v * kPow10[adjustment - 1];
|
||||||
if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
|
if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit
|
||||||
error += kUlp / 2;
|
error += kUlp / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,9 +205,9 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||||||
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
|
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) {
|
||||||
const BigInteger dInt(decimals, length);
|
RAPIDJSON_ASSERT(dLen >= 0);
|
||||||
const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
|
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
||||||
Double a(approx);
|
Double a(approx);
|
||||||
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
|
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
@ -225,42 +227,61 @@ inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t
|
|||||||
RAPIDJSON_ASSERT(d >= 0.0);
|
RAPIDJSON_ASSERT(d >= 0.0);
|
||||||
RAPIDJSON_ASSERT(length >= 1);
|
RAPIDJSON_ASSERT(length >= 1);
|
||||||
|
|
||||||
double result;
|
double result = 0.0;
|
||||||
if (StrtodFast(d, p, &result))
|
if (StrtodFast(d, p, &result))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
RAPIDJSON_ASSERT(length <= INT_MAX);
|
||||||
|
int dLen = static_cast<int>(length);
|
||||||
|
|
||||||
|
RAPIDJSON_ASSERT(length >= decimalPosition);
|
||||||
|
RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX);
|
||||||
|
int dExpAdjust = static_cast<int>(length - decimalPosition);
|
||||||
|
|
||||||
|
RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust);
|
||||||
|
int dExp = exp - dExpAdjust;
|
||||||
|
|
||||||
|
// Make sure length+dExp does not overflow
|
||||||
|
RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen);
|
||||||
|
|
||||||
// Trim leading zeros
|
// Trim leading zeros
|
||||||
while (*decimals == '0' && length > 1) {
|
while (dLen > 0 && *decimals == '0') {
|
||||||
length--;
|
dLen--;
|
||||||
decimals++;
|
decimals++;
|
||||||
decimalPosition--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim trailing zeros
|
// Trim trailing zeros
|
||||||
while (decimals[length - 1] == '0' && length > 1) {
|
while (dLen > 0 && decimals[dLen - 1] == '0') {
|
||||||
length--;
|
dLen--;
|
||||||
decimalPosition--;
|
dExp++;
|
||||||
exp++;
|
}
|
||||||
|
|
||||||
|
if (dLen == 0) { // Buffer only contains zeros.
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim right-most digits
|
// Trim right-most digits
|
||||||
const int kMaxDecimalDigit = 780;
|
const int kMaxDecimalDigit = 767 + 1;
|
||||||
if (static_cast<int>(length) > kMaxDecimalDigit) {
|
if (dLen > kMaxDecimalDigit) {
|
||||||
int delta = (static_cast<int>(length) - kMaxDecimalDigit);
|
dExp += dLen - kMaxDecimalDigit;
|
||||||
exp += delta;
|
dLen = kMaxDecimalDigit;
|
||||||
decimalPosition -= static_cast<unsigned>(delta);
|
|
||||||
length = kMaxDecimalDigit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If too small, underflow to zero
|
// If too small, underflow to zero.
|
||||||
if (int(length) + exp < -324)
|
// Any x <= 10^-324 is interpreted as zero.
|
||||||
|
if (dLen + dExp <= -324)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
|
// If too large, overflow to infinity.
|
||||||
|
// Any x >= 10^309 is interpreted as +infinity.
|
||||||
|
if (dLen + dExp > 309)
|
||||||
|
return std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
if (StrtodDiyFp(decimals, dLen, dExp, &result))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
|
// Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
|
||||||
return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
|
return StrtodBigInteger(result, decimals, dLen, dExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -17,13 +17,12 @@
|
|||||||
|
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <ios>
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
#endif
|
#elif defined(_MSC_VER)
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
|
RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
|
||||||
#endif
|
#endif
|
||||||
@ -50,57 +49,71 @@ template <typename StreamType>
|
|||||||
class BasicIStreamWrapper {
|
class BasicIStreamWrapper {
|
||||||
public:
|
public:
|
||||||
typedef typename StreamType::char_type Ch;
|
typedef typename StreamType::char_type Ch;
|
||||||
BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}
|
|
||||||
|
|
||||||
Ch Peek() const {
|
//! Constructor.
|
||||||
typename StreamType::int_type c = stream_.peek();
|
/*!
|
||||||
return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\0');
|
\param stream stream opened for read.
|
||||||
|
*/
|
||||||
|
BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
||||||
|
Read();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ch Take() {
|
//! Constructor.
|
||||||
typename StreamType::int_type c = stream_.get();
|
/*!
|
||||||
if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {
|
\param stream stream opened for read.
|
||||||
count_++;
|
\param buffer user-supplied buffer.
|
||||||
return static_cast<Ch>(c);
|
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
||||||
}
|
*/
|
||||||
else
|
BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
||||||
return '\0';
|
RAPIDJSON_ASSERT(bufferSize >= 4);
|
||||||
|
Read();
|
||||||
}
|
}
|
||||||
|
|
||||||
// tellg() may return -1 when failed. So we count by ourself.
|
Ch Peek() const { return *current_; }
|
||||||
size_t Tell() const { return count_; }
|
Ch Take() { Ch c = *current_; Read(); return c; }
|
||||||
|
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
||||||
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.
|
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
|
||||||
int i;
|
|
||||||
bool hasError = false;
|
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
typename StreamType::int_type c = stream_.get();
|
|
||||||
if (c == StreamType::traits_type::eof()) {
|
|
||||||
hasError = true;
|
|
||||||
stream_.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
peekBuffer_[i] = static_cast<Ch>(c);
|
|
||||||
}
|
|
||||||
for (--i; i >= 0; --i)
|
|
||||||
stream_.putback(peekBuffer_[i]);
|
|
||||||
return !hasError ? peekBuffer_ : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BasicIStreamWrapper();
|
||||||
BasicIStreamWrapper(const BasicIStreamWrapper&);
|
BasicIStreamWrapper(const BasicIStreamWrapper&);
|
||||||
BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
|
BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
|
||||||
|
|
||||||
StreamType& stream_;
|
void Read() {
|
||||||
size_t count_; //!< Number of characters read. Note:
|
if (current_ < bufferLast_)
|
||||||
mutable Ch peekBuffer_[4];
|
++current_;
|
||||||
|
else if (!eof_) {
|
||||||
|
count_ += readCount_;
|
||||||
|
readCount_ = bufferSize_;
|
||||||
|
bufferLast_ = buffer_ + readCount_ - 1;
|
||||||
|
current_ = buffer_;
|
||||||
|
|
||||||
|
if (!stream_.read(buffer_, static_cast<std::streamsize>(bufferSize_))) {
|
||||||
|
readCount_ = static_cast<size_t>(stream_.gcount());
|
||||||
|
*(bufferLast_ = buffer_ + readCount_) = '\0';
|
||||||
|
eof_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamType &stream_;
|
||||||
|
Ch peekBuffer_[4], *buffer_;
|
||||||
|
size_t bufferSize_;
|
||||||
|
Ch *bufferLast_;
|
||||||
|
Ch *current_;
|
||||||
|
size_t readCount_;
|
||||||
|
size_t count_; //!< Number of characters read
|
||||||
|
bool eof_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
|
typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
ssg_sources_lottie_rapidjson = []
|
|
||||||
|
|
||||||
ssg_lottie_rapidjson_file = ['jsontest.cpp'
|
|
||||||
]
|
|
||||||
|
|
||||||
foreach file: ssg_lottie_rapidjson_file
|
|
||||||
ssg_sources_lottie_rapidjson += join_paths('rapidjson', file)
|
|
||||||
endforeach
|
|
@ -21,9 +21,7 @@
|
|||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
#endif
|
#elif defined(_MSC_VER)
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
#endif
|
#endif
|
||||||
@ -165,7 +163,12 @@ public:
|
|||||||
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
||||||
|
|
||||||
//! Copy constructor.
|
//! Copy constructor.
|
||||||
GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Copy constructor.
|
||||||
|
GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||||
*this = rhs;
|
*this = rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +200,36 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Swap the content of this pointer with an other.
|
||||||
|
/*!
|
||||||
|
\param other The pointer to swap with.
|
||||||
|
\note Constant complexity.
|
||||||
|
*/
|
||||||
|
GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
|
||||||
|
internal::Swap(allocator_, other.allocator_);
|
||||||
|
internal::Swap(ownAllocator_, other.ownAllocator_);
|
||||||
|
internal::Swap(nameBuffer_, other.nameBuffer_);
|
||||||
|
internal::Swap(tokens_, other.tokens_);
|
||||||
|
internal::Swap(tokenCount_, other.tokenCount_);
|
||||||
|
internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
|
||||||
|
internal::Swap(parseErrorCode_, other.parseErrorCode_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! free-standing swap function helper
|
||||||
|
/*!
|
||||||
|
Helper function to enable support for common swap implementation pattern based on \c std::swap:
|
||||||
|
\code
|
||||||
|
void swap(MyClass& a, MyClass& b) {
|
||||||
|
using std::swap;
|
||||||
|
swap(a.pointer, b.pointer);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\see Swap()
|
||||||
|
*/
|
||||||
|
friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//!@name Append token
|
//!@name Append token
|
||||||
@ -353,6 +386,33 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
|
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
|
//! Less than operator.
|
||||||
|
/*!
|
||||||
|
\note Invalid pointers are always greater than valid ones.
|
||||||
|
*/
|
||||||
|
bool operator<(const GenericPointer& rhs) const {
|
||||||
|
if (!IsValid())
|
||||||
|
return false;
|
||||||
|
if (!rhs.IsValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (tokenCount_ != rhs.tokenCount_)
|
||||||
|
return tokenCount_ < rhs.tokenCount_;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tokenCount_; i++) {
|
||||||
|
if (tokens_[i].index != rhs.tokens_[i].index)
|
||||||
|
return tokens_[i].index < rhs.tokens_[i].index;
|
||||||
|
|
||||||
|
if (tokens_[i].length != rhs.tokens_[i].length)
|
||||||
|
return tokens_[i].length < rhs.tokens_[i].length;
|
||||||
|
|
||||||
|
if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
|
||||||
|
return cmp < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//!@name Stringify
|
//!@name Stringify
|
||||||
@ -532,14 +592,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
|
ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
|
||||||
bool alreadyExist;
|
bool alreadyExist;
|
||||||
Value& v = Create(root, allocator, &alreadyExist);
|
ValueType& v = Create(root, allocator, &alreadyExist);
|
||||||
return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
|
return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Query a value in a subtree with default null-terminated string.
|
//! Query a value in a subtree with default null-terminated string.
|
||||||
ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
|
ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
|
||||||
bool alreadyExist;
|
bool alreadyExist;
|
||||||
Value& v = Create(root, allocator, &alreadyExist);
|
ValueType& v = Create(root, allocator, &alreadyExist);
|
||||||
return alreadyExist ? v : v.SetString(defaultValue, allocator);
|
return alreadyExist ? v : v.SetString(defaultValue, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,7 +607,7 @@ public:
|
|||||||
//! Query a value in a subtree with default std::basic_string.
|
//! Query a value in a subtree with default std::basic_string.
|
||||||
ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
|
ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
|
||||||
bool alreadyExist;
|
bool alreadyExist;
|
||||||
Value& v = Create(root, allocator, &alreadyExist);
|
ValueType& v = Create(root, allocator, &alreadyExist);
|
||||||
return alreadyExist ? v : v.SetString(defaultValue, allocator);
|
return alreadyExist ? v : v.SetString(defaultValue, allocator);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1347,11 +1407,7 @@ bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ enum PrettyFormatOptions {
|
|||||||
|
|
||||||
//! Writer with indentation and spacing.
|
//! Writer with indentation and spacing.
|
||||||
/*!
|
/*!
|
||||||
\tparam OutputStream Type of ouptut os.
|
\tparam OutputStream Type of output os.
|
||||||
\tparam SourceEncoding Encoding of source string.
|
\tparam SourceEncoding Encoding of source string.
|
||||||
\tparam TargetEncoding Encoding of output stream.
|
\tparam TargetEncoding Encoding of output stream.
|
||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
||||||
@ -92,26 +92,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
|
bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
|
||||||
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
|
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
|
||||||
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
|
bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
|
||||||
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
|
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
|
||||||
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
|
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
|
||||||
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
|
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
|
||||||
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
|
bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
(void)copy;
|
(void)copy;
|
||||||
PrettyPrefix(kNumberType);
|
PrettyPrefix(kNumberType);
|
||||||
return Base::WriteString(str, length);
|
return Base::EndValue(Base::WriteString(str, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
(void)copy;
|
(void)copy;
|
||||||
PrettyPrefix(kStringType);
|
PrettyPrefix(kStringType);
|
||||||
return Base::WriteString(str, length);
|
return Base::EndValue(Base::WriteString(str, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
@ -146,7 +146,7 @@ public:
|
|||||||
Base::os_->Put('\n');
|
Base::os_->Put('\n');
|
||||||
WriteIndent();
|
WriteIndent();
|
||||||
}
|
}
|
||||||
bool ret = Base::WriteEndObject();
|
bool ret = Base::EndValue(Base::WriteEndObject());
|
||||||
(void)ret;
|
(void)ret;
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
RAPIDJSON_ASSERT(ret == true);
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
if (Base::level_stack_.Empty()) // end of json text
|
||||||
@ -170,7 +170,7 @@ public:
|
|||||||
Base::os_->Put('\n');
|
Base::os_->Put('\n');
|
||||||
WriteIndent();
|
WriteIndent();
|
||||||
}
|
}
|
||||||
bool ret = Base::WriteEndArray();
|
bool ret = Base::EndValue(Base::WriteEndArray());
|
||||||
(void)ret;
|
(void)ret;
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
RAPIDJSON_ASSERT(ret == true);
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
if (Base::level_stack_.Empty()) // end of json text
|
||||||
@ -201,7 +201,7 @@ public:
|
|||||||
bool RawValue(const Ch* json, size_t length, Type type) {
|
bool RawValue(const Ch* json, size_t length, Type type) {
|
||||||
RAPIDJSON_ASSERT(json != 0);
|
RAPIDJSON_ASSERT(json != 0);
|
||||||
PrettyPrefix(type);
|
PrettyPrefix(type);
|
||||||
return Base::WriteRawValue(json, length);
|
return Base::EndValue(Base::WriteRawValue(json, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
Some RapidJSON features are configurable to adapt the library to a wide
|
Some RapidJSON features are configurable to adapt the library to a wide
|
||||||
variety of platforms, environments and usage scenarios. Most of the
|
variety of platforms, environments and usage scenarios. Most of the
|
||||||
features can be configured in terms of overriden or predefined
|
features can be configured in terms of overridden or predefined
|
||||||
preprocessor macros at compile-time.
|
preprocessor macros at compile-time.
|
||||||
|
|
||||||
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
|
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
|
||||||
@ -219,7 +219,7 @@
|
|||||||
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||||
# else
|
# else
|
||||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||||
# endif // __BYTE_ORDER__
|
# endif // __BYTE_ORDER__
|
||||||
// Detect with GLIBC's endian.h
|
// Detect with GLIBC's endian.h
|
||||||
# elif defined(__GLIBC__)
|
# elif defined(__GLIBC__)
|
||||||
@ -229,7 +229,7 @@
|
|||||||
# elif (__BYTE_ORDER == __BIG_ENDIAN)
|
# elif (__BYTE_ORDER == __BIG_ENDIAN)
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||||
# else
|
# else
|
||||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||||
# endif // __GLIBC__
|
# endif // __GLIBC__
|
||||||
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
|
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
|
||||||
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
||||||
@ -246,7 +246,7 @@
|
|||||||
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
||||||
# define RAPIDJSON_ENDIAN
|
# define RAPIDJSON_ENDIAN
|
||||||
# else
|
# else
|
||||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||||
# endif
|
# endif
|
||||||
#endif // RAPIDJSON_ENDIAN
|
#endif // RAPIDJSON_ENDIAN
|
||||||
|
|
||||||
@ -269,16 +269,11 @@
|
|||||||
/*! \ingroup RAPIDJSON_CONFIG
|
/*! \ingroup RAPIDJSON_CONFIG
|
||||||
\param x pointer to align
|
\param x pointer to align
|
||||||
|
|
||||||
Some machines require strict data alignment. Currently the default uses 4 bytes
|
Some machines require strict data alignment. The default is 8 bytes.
|
||||||
alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.
|
|
||||||
User can customize by defining the RAPIDJSON_ALIGN function macro.
|
User can customize by defining the RAPIDJSON_ALIGN function macro.
|
||||||
*/
|
*/
|
||||||
#ifndef RAPIDJSON_ALIGN
|
#ifndef RAPIDJSON_ALIGN
|
||||||
#if RAPIDJSON_64BIT == 1
|
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
|
||||||
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -433,7 +428,7 @@ template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
|||||||
template <size_t x> struct StaticAssertTest {};
|
template <size_t x> struct StaticAssertTest {};
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
|
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||||
@ -539,19 +534,18 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// C++11 features
|
// C++11 features
|
||||||
//enable c++11 feature
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#if __has_feature(cxx_rvalue_references) && \
|
#if __has_feature(cxx_rvalue_references) && \
|
||||||
(defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
|
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
|
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
|
||||||
#endif
|
#endif
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1600)
|
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
|
||||||
|
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||||
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
||||||
#else
|
#else
|
||||||
@ -562,8 +556,9 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
|
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
|
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
||||||
// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
|
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
||||||
|
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
|
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
|
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
|
||||||
@ -577,14 +572,19 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
|
|
||||||
// no automatic detection, yet
|
// no automatic detection, yet
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
|
#if (defined(_MSC_VER) && _MSC_VER >= 1700)
|
||||||
|
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1
|
||||||
|
#else
|
||||||
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
|
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
|
#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
|
#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1700)
|
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
|
||||||
|
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
|
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
|
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
|
||||||
@ -593,6 +593,32 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
|
|
||||||
//!@endcond
|
//!@endcond
|
||||||
|
|
||||||
|
//! Assertion (in non-throwing contexts).
|
||||||
|
/*! \ingroup RAPIDJSON_CONFIG
|
||||||
|
Some functions provide a \c noexcept guarantee, if the compiler supports it.
|
||||||
|
In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to
|
||||||
|
throw an exception. This macro adds a separate customization point for
|
||||||
|
such cases.
|
||||||
|
|
||||||
|
Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is
|
||||||
|
supported, and to \ref RAPIDJSON_ASSERT otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
|
#ifdef RAPIDJSON_ASSERT_THROWS
|
||||||
|
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||||
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
||||||
|
#else
|
||||||
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||||
|
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||||
|
#else
|
||||||
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||||
|
#endif // RAPIDJSON_ASSERT_THROWS
|
||||||
|
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// new/delete
|
// new/delete
|
||||||
|
|
||||||
|
@ -37,17 +37,15 @@
|
|||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
|
||||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(old-style-cast)
|
RAPIDJSON_DIAG_OFF(old-style-cast)
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||||
|
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -544,7 +542,8 @@ public:
|
|||||||
/*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
|
/*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
|
||||||
\param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
|
\param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
|
||||||
*/
|
*/
|
||||||
GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
|
GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
|
||||||
|
stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
|
||||||
|
|
||||||
//! Parse JSON text.
|
//! Parse JSON text.
|
||||||
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
||||||
@ -607,7 +606,7 @@ public:
|
|||||||
parseResult_.Clear();
|
parseResult_.Clear();
|
||||||
state_ = IterativeParsingStartState;
|
state_ = IterativeParsingStartState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse one token from JSON text
|
//! Parse one token from JSON text
|
||||||
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
||||||
\tparam Handler Type of handler, implementing Handler concept.
|
\tparam Handler Type of handler, implementing Handler concept.
|
||||||
@ -619,11 +618,11 @@ public:
|
|||||||
bool IterativeParseNext(InputStream& is, Handler& handler) {
|
bool IterativeParseNext(InputStream& is, Handler& handler) {
|
||||||
while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
|
while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
|
||||||
Token t = Tokenize(is.Peek());
|
Token t = Tokenize(is.Peek());
|
||||||
IterativeParsingState n = Predict(state_, t);
|
IterativeParsingState n = Predict(state_, t);
|
||||||
IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
|
IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
|
||||||
|
|
||||||
// If we've finished or hit an error...
|
// If we've finished or hit an error...
|
||||||
if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
|
if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
|
||||||
// Report errors.
|
// Report errors.
|
||||||
@ -631,11 +630,11 @@ public:
|
|||||||
HandleError(state_, is);
|
HandleError(state_, is);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition to the finish state.
|
// Transition to the finish state.
|
||||||
RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
|
RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
|
||||||
state_ = d;
|
state_ = d;
|
||||||
|
|
||||||
// If StopWhenDone is not set...
|
// If StopWhenDone is not set...
|
||||||
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
||||||
// ... and extra non-whitespace data is found...
|
// ... and extra non-whitespace data is found...
|
||||||
@ -646,11 +645,11 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success! We are done!
|
// Success! We are done!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition to the new state.
|
// Transition to the new state.
|
||||||
state_ = d;
|
state_ = d;
|
||||||
|
|
||||||
@ -658,7 +657,7 @@ public:
|
|||||||
if (!IsIterativeParsingDelimiterState(n))
|
if (!IsIterativeParsingDelimiterState(n))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We reached the end of file.
|
// We reached the end of file.
|
||||||
stack_.Clear();
|
stack_.Clear();
|
||||||
|
|
||||||
@ -666,18 +665,18 @@ public:
|
|||||||
HandleError(state_, is);
|
HandleError(state_, is);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Check if token-by-token parsing JSON text is complete
|
//! Check if token-by-token parsing JSON text is complete
|
||||||
/*! \return Whether the JSON has been fully decoded.
|
/*! \return Whether the JSON has been fully decoded.
|
||||||
*/
|
*/
|
||||||
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() {
|
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const {
|
||||||
return IsIterativeParsingCompleteState(state_);
|
return IsIterativeParsingCompleteState(state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Whether a parse error has occured in the last parsing.
|
//! Whether a parse error has occurred in the last parsing.
|
||||||
bool HasParseError() const { return parseResult_.IsError(); }
|
bool HasParseError() const { return parseResult_.IsError(); }
|
||||||
|
|
||||||
//! Get the \ref ParseErrorCode of last parsing.
|
//! Get the \ref ParseErrorCode of last parsing.
|
||||||
@ -900,7 +899,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
|
// Helper function to parse four hexadecimal digits in \uXXXX in ParseString().
|
||||||
template<typename InputStream>
|
template<typename InputStream>
|
||||||
unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
|
unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
|
||||||
unsigned codepoint = 0;
|
unsigned codepoint = 0;
|
||||||
@ -1007,7 +1006,7 @@ private:
|
|||||||
|
|
||||||
Ch c = is.Peek();
|
Ch c = is.Peek();
|
||||||
if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
|
if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
|
||||||
size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
|
size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset
|
||||||
is.Take();
|
is.Take();
|
||||||
Ch e = is.Peek();
|
Ch e = is.Peek();
|
||||||
if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
|
if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
|
||||||
@ -1524,7 +1523,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
|
if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
||||||
}
|
}
|
||||||
@ -1562,8 +1561,6 @@ private:
|
|||||||
// Force double for big integer
|
// Force double for big integer
|
||||||
if (useDouble) {
|
if (useDouble) {
|
||||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||||
if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
|
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
|
|
||||||
d = d * 10 + (s.TakePush() - '0');
|
d = d * 10 + (s.TakePush() - '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1633,9 +1630,18 @@ private:
|
|||||||
if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||||
exp = static_cast<int>(s.Take() - '0');
|
exp = static_cast<int>(s.Take() - '0');
|
||||||
if (expMinus) {
|
if (expMinus) {
|
||||||
|
// (exp + expFrac) must not underflow int => we're detecting when -exp gets
|
||||||
|
// dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
|
||||||
|
// underflow territory):
|
||||||
|
//
|
||||||
|
// -(exp * 10 + 9) + expFrac >= INT_MIN
|
||||||
|
// <=> exp <= (expFrac - INT_MIN - 9) / 10
|
||||||
|
RAPIDJSON_ASSERT(expFrac <= 0);
|
||||||
|
int maxExp = (expFrac + 2147483639) / 10;
|
||||||
|
|
||||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||||
exp = exp * 10 + static_cast<int>(s.Take() - '0');
|
exp = exp * 10 + static_cast<int>(s.Take() - '0');
|
||||||
if (exp >= 214748364) { // Issue #313: prevent overflow exponent
|
if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
|
||||||
while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
|
while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
|
||||||
s.Take();
|
s.Take();
|
||||||
}
|
}
|
||||||
@ -1694,6 +1700,13 @@ private:
|
|||||||
else
|
else
|
||||||
d = internal::StrtodNormalPrecision(d, p);
|
d = internal::StrtodNormalPrecision(d, p);
|
||||||
|
|
||||||
|
// Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
|
||||||
|
if (d > (std::numeric_limits<double>::max)()) {
|
||||||
|
// Overflow
|
||||||
|
// TODO: internal::StrtodX should report overflow (or underflow)
|
||||||
|
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
|
||||||
|
}
|
||||||
|
|
||||||
cont = handler.Double(minus ? -d : d);
|
cont = handler.Double(minus ? -d : d);
|
||||||
}
|
}
|
||||||
else if (useNanOrInf) {
|
else if (useNanOrInf) {
|
||||||
@ -1756,12 +1769,12 @@ private:
|
|||||||
|
|
||||||
// Single value state
|
// Single value state
|
||||||
IterativeParsingValueState,
|
IterativeParsingValueState,
|
||||||
|
|
||||||
// Delimiter states (at bottom)
|
// Delimiter states (at bottom)
|
||||||
IterativeParsingElementDelimiterState,
|
IterativeParsingElementDelimiterState,
|
||||||
IterativeParsingMemberDelimiterState,
|
IterativeParsingMemberDelimiterState,
|
||||||
IterativeParsingKeyValueDelimiterState,
|
IterativeParsingKeyValueDelimiterState,
|
||||||
|
|
||||||
cIterativeParsingStateCount
|
cIterativeParsingStateCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1785,7 +1798,7 @@ private:
|
|||||||
kTokenCount
|
kTokenCount
|
||||||
};
|
};
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
|
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const {
|
||||||
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||||
#define N NumberToken
|
#define N NumberToken
|
||||||
@ -1812,7 +1825,7 @@ private:
|
|||||||
return NumberToken;
|
return NumberToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
|
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const {
|
||||||
// current state x one lookahead token -> new state
|
// current state x one lookahead token -> new state
|
||||||
static const char G[cIterativeParsingStateCount][kTokenCount] = {
|
static const char G[cIterativeParsingStateCount][kTokenCount] = {
|
||||||
// Finish(sink state)
|
// Finish(sink state)
|
||||||
@ -2151,53 +2164,53 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) {
|
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
|
||||||
return s >= IterativeParsingElementDelimiterState;
|
return s >= IterativeParsingElementDelimiterState;
|
||||||
}
|
}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) {
|
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
|
||||||
return s <= IterativeParsingErrorState;
|
return s <= IterativeParsingErrorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned parseFlags, typename InputStream, typename Handler>
|
template <unsigned parseFlags, typename InputStream, typename Handler>
|
||||||
ParseResult IterativeParse(InputStream& is, Handler& handler) {
|
ParseResult IterativeParse(InputStream& is, Handler& handler) {
|
||||||
parseResult_.Clear();
|
parseResult_.Clear();
|
||||||
ClearStackOnExit scope(*this);
|
ClearStackOnExit scope(*this);
|
||||||
IterativeParsingState state = IterativeParsingStartState;
|
IterativeParsingState state = IterativeParsingStartState;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
while (is.Peek() != '\0') {
|
while (is.Peek() != '\0') {
|
||||||
Token t = Tokenize(is.Peek());
|
Token t = Tokenize(is.Peek());
|
||||||
IterativeParsingState n = Predict(state, t);
|
IterativeParsingState n = Predict(state, t);
|
||||||
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
|
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
|
||||||
|
|
||||||
if (d == IterativeParsingErrorState) {
|
if (d == IterativeParsingErrorState) {
|
||||||
HandleError(state, is);
|
HandleError(state, is);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = d;
|
state = d;
|
||||||
|
|
||||||
// Do not further consume streams if a root JSON has been parsed.
|
// Do not further consume streams if a root JSON has been parsed.
|
||||||
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the end of file.
|
// Handle the end of file.
|
||||||
if (state != IterativeParsingFinishState)
|
if (state != IterativeParsingFinishState)
|
||||||
HandleError(state, is);
|
HandleError(state, is);
|
||||||
|
|
||||||
return parseResult_;
|
return parseResult_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
|
static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
|
||||||
internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
|
internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
|
||||||
ParseResult parseResult_;
|
ParseResult parseResult_;
|
||||||
IterativeParsingState state_{IterativeParsingStartState};
|
IterativeParsingState state_;
|
||||||
}; // class GenericReader
|
}; // class GenericReader
|
||||||
|
|
||||||
//! Reader with UTF8 encoding and default allocator.
|
//! Reader with UTF8 encoding and default allocator.
|
||||||
@ -2205,7 +2218,7 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2214,8 +2227,4 @@ RAPIDJSON_DIAG_POP
|
|||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_READER_H_
|
#endif // RAPIDJSON_READER_H_
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -36,16 +36,14 @@
|
|||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
@ -460,9 +458,13 @@ protected:
|
|||||||
|
|
||||||
bool WriteRawValue(const Ch* json, size_t length) {
|
bool WriteRawValue(const Ch* json, size_t length) {
|
||||||
PutReserve(*os_, length);
|
PutReserve(*os_, length);
|
||||||
for (size_t i = 0; i < length; i++) {
|
GenericStringStream<SourceEncoding> is(json);
|
||||||
RAPIDJSON_ASSERT(json[i] != '\0');
|
while (RAPIDJSON_LIKELY(is.Tell() < length)) {
|
||||||
PutUnsafe(*os_, json[i]);
|
RAPIDJSON_ASSERT(is.Peek() != '\0');
|
||||||
|
if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
||||||
|
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -700,11 +702,7 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) || defined(__clang__)
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user