mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-12 17:31:19 +01:00
Merge remote-tracking branch 'origin/master' into issue75stopwhendone
This commit is contained in:
commit
e09b9d5c05
@ -1221,13 +1221,12 @@ public:
|
|||||||
\tparam SourceEncoding Encoding of input stream
|
\tparam SourceEncoding Encoding of input stream
|
||||||
\tparam InputStream Type of input stream, implementing Stream concept
|
\tparam InputStream Type of input stream, implementing Stream concept
|
||||||
\param is Input stream to be parsed.
|
\param is Input stream to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
|
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
|
||||||
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
|
GenericDocument& ParseStream(InputStream& is) {
|
||||||
ValueType::SetNull(); // Remove existing root if exist
|
ValueType::SetNull(); // Remove existing root if exist
|
||||||
GenericReader<SourceEncoding, Encoding, Allocator> reader(limit, &GetAllocator());
|
GenericReader<SourceEncoding, Encoding, Allocator> reader(&GetAllocator());
|
||||||
ClearStackOnExit scope(*this);
|
ClearStackOnExit scope(*this);
|
||||||
parseResult_ = reader.template Parse<parseFlags>(is, *this);
|
parseResult_ = reader.template Parse<parseFlags>(is, *this);
|
||||||
if (parseResult_) {
|
if (parseResult_) {
|
||||||
@ -1241,23 +1240,21 @@ public:
|
|||||||
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
||||||
\tparam InputStream Type of input stream, implementing Stream concept
|
\tparam InputStream Type of input stream, implementing Stream concept
|
||||||
\param is Input stream to be parsed.
|
\param is Input stream to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags, typename InputStream>
|
template <unsigned parseFlags, typename InputStream>
|
||||||
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
|
GenericDocument& ParseStream(InputStream& is) {
|
||||||
return ParseStream<parseFlags,Encoding,InputStream>(is, limit);
|
return ParseStream<parseFlags,Encoding,InputStream>(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
|
//! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
|
||||||
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
||||||
\param is Input stream to be parsed.
|
\param is Input stream to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
template <typename InputStream>
|
template <typename InputStream>
|
||||||
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
|
GenericDocument& ParseStream(InputStream& is) {
|
||||||
return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is, limit);
|
return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
|
||||||
}
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
@ -1268,33 +1265,30 @@ public:
|
|||||||
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
||||||
\tparam SourceEncoding Transcoding from input Encoding
|
\tparam SourceEncoding Transcoding from input Encoding
|
||||||
\param str Mutable zero-terminated string to be parsed.
|
\param str Mutable zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags, typename SourceEncoding>
|
template <unsigned parseFlags, typename SourceEncoding>
|
||||||
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
|
GenericDocument& ParseInsitu(Ch* str) {
|
||||||
GenericInsituStringStream<Encoding> s(str);
|
GenericInsituStringStream<Encoding> s(str);
|
||||||
return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s, limit);
|
return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse JSON text from a mutable string
|
//! Parse JSON text from a mutable string
|
||||||
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
/*! \tparam parseFlags Combination of \ref ParseFlag.
|
||||||
\param str Mutable zero-terminated string to be parsed.
|
\param str Mutable zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags>
|
template <unsigned parseFlags>
|
||||||
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
|
GenericDocument& ParseInsitu(Ch* str) {
|
||||||
return ParseInsitu<parseFlags, Encoding>(str, limit);
|
return ParseInsitu<parseFlags, Encoding>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
|
//! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
|
||||||
/*! \param str Mutable zero-terminated string to be parsed.
|
/*! \param str Mutable zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
\return The document itself for fluent API.
|
\return The document itself for fluent API.
|
||||||
*/
|
*/
|
||||||
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
|
GenericDocument& ParseInsitu(Ch* str) {
|
||||||
return ParseInsitu<kParseDefaultFlags, Encoding>(str, limit);
|
return ParseInsitu<kParseDefaultFlags, Encoding>(str);
|
||||||
}
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
@ -1305,31 +1299,28 @@ public:
|
|||||||
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
|
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
|
||||||
\tparam SourceEncoding Transcoding from input Encoding
|
\tparam SourceEncoding Transcoding from input Encoding
|
||||||
\param str Read-only zero-terminated string to be parsed.
|
\param str Read-only zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags, typename SourceEncoding>
|
template <unsigned parseFlags, typename SourceEncoding>
|
||||||
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
|
GenericDocument& Parse(const Ch* str) {
|
||||||
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
|
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
|
||||||
GenericStringStream<SourceEncoding> s(str);
|
GenericStringStream<SourceEncoding> s(str);
|
||||||
return ParseStream<parseFlags, SourceEncoding>(s, limit);
|
return ParseStream<parseFlags, SourceEncoding>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse JSON text from a read-only string
|
//! Parse JSON text from a read-only string
|
||||||
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
|
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
|
||||||
\param str Read-only zero-terminated string to be parsed.
|
\param str Read-only zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
*/
|
*/
|
||||||
template <unsigned parseFlags>
|
template <unsigned parseFlags>
|
||||||
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
|
GenericDocument& Parse(const Ch* str) {
|
||||||
return Parse<parseFlags, Encoding>(str, limit);
|
return Parse<parseFlags, Encoding>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
|
//! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
|
||||||
/*! \param str Read-only zero-terminated string to be parsed.
|
/*! \param str Read-only zero-terminated string to be parsed.
|
||||||
\param limit Parsing stack size limit(in bytes). Pass 0 means no limit.
|
|
||||||
*/
|
*/
|
||||||
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
|
GenericDocument& Parse(const Ch* str) {
|
||||||
return Parse<kParseDefaultFlags>(str, limit);
|
return Parse<kParseDefaultFlags>(str);
|
||||||
}
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
|||||||
|
|
||||||
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
||||||
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
||||||
case kParseErrorStackSizeLimitExceeded: return RAPIDJSON_ERROR_STRING("Parsing stack size limit is exceeded.");
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
|
@ -60,7 +60,6 @@ enum ParseErrorCode {
|
|||||||
|
|
||||||
kParseErrorTermination, //!< Parsing was terminated.
|
kParseErrorTermination, //!< Parsing was terminated.
|
||||||
kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error.
|
kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error.
|
||||||
kParseErrorStackSizeLimitExceeded //!< Parsing stack size limit is exceeded.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Result of parsing (wraps ParseErrorCode)
|
//! Result of parsing (wraps ParseErrorCode)
|
||||||
|
@ -28,20 +28,14 @@ public:
|
|||||||
|
|
||||||
void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
|
void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
|
||||||
|
|
||||||
|
// Optimization note: try to minimize the size of this function for force inline.
|
||||||
|
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* Push(size_t count = 1) {
|
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
||||||
// Expand the stack if needed
|
// Expand the stack if needed
|
||||||
if (stack_top_ + sizeof(T) * count >= stack_end_) {
|
if (stack_top_ + sizeof(T) * count >= stack_end_)
|
||||||
size_t new_capacity = stack_capacity_ * 2;
|
Expand<T>(count);
|
||||||
size_t size = GetSize();
|
|
||||||
size_t new_size = GetSize() + sizeof(T) * count;
|
|
||||||
if (new_capacity < new_size)
|
|
||||||
new_capacity = new_size;
|
|
||||||
stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
|
|
||||||
stack_capacity_ = new_capacity;
|
|
||||||
stack_top_ = stack_ + size;
|
|
||||||
stack_end_ = stack_ + stack_capacity_;
|
|
||||||
}
|
|
||||||
T* ret = reinterpret_cast<T*>(stack_top_);
|
T* ret = reinterpret_cast<T*>(stack_top_);
|
||||||
stack_top_ += sizeof(T) * count;
|
stack_top_ += sizeof(T) * count;
|
||||||
return ret;
|
return ret;
|
||||||
@ -69,6 +63,19 @@ public:
|
|||||||
size_t GetCapacity() const { return stack_capacity_; }
|
size_t GetCapacity() const { return stack_capacity_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename T>
|
||||||
|
void Expand(size_t count) {
|
||||||
|
size_t new_capacity = stack_capacity_ * 2;
|
||||||
|
size_t size = GetSize();
|
||||||
|
size_t new_size = GetSize() + sizeof(T) * count;
|
||||||
|
if (new_capacity < new_size)
|
||||||
|
new_capacity = new_size;
|
||||||
|
stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
|
||||||
|
stack_capacity_ = new_capacity;
|
||||||
|
stack_top_ = stack_ + size;
|
||||||
|
stack_end_ = stack_ + stack_capacity_;
|
||||||
|
}
|
||||||
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
// Prohibit copy constructor & assignment operator.
|
||||||
Stack(const Stack&);
|
Stack(const Stack&);
|
||||||
Stack& operator=(const Stack&);
|
Stack& operator=(const Stack&);
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#ifndef RAPIDJSON_FORCEINLINE
|
#ifndef RAPIDJSON_FORCEINLINE
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define RAPIDJSON_FORCEINLINE __forceinline
|
#define RAPIDJSON_FORCEINLINE __forceinline
|
||||||
|
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_FORCEINLINE
|
#define RAPIDJSON_FORCEINLINE
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,48 +104,37 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator)) {
|
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator)) {
|
||||||
//const size_t userBufferSize = 128 * 1024;
|
|
||||||
//char* userBuffer = (char*)malloc(userBufferSize);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < kTrialCount; i++) {
|
for (size_t i = 0; i < kTrialCount; i++) {
|
||||||
memcpy(temp_, json_, length_ + 1);
|
memcpy(temp_, json_, length_ + 1);
|
||||||
//MemoryPoolAllocator<> allocator(userBuffer, userBufferSize);
|
|
||||||
//Document doc(&allocator);
|
|
||||||
Document doc;
|
Document doc;
|
||||||
doc.ParseInsitu(temp_);
|
doc.ParseInsitu(temp_);
|
||||||
ASSERT_TRUE(doc.IsObject());
|
ASSERT_TRUE(doc.IsObject());
|
||||||
//if (i == 0) {
|
|
||||||
// size_t size = doc.GetAllocator().Size();
|
|
||||||
// size_t capacity = doc.GetAllocator().Capacity();
|
|
||||||
// size_t stack_capacity = doc.GetStackCapacity();
|
|
||||||
// size_t actual = size - stack_capacity;
|
|
||||||
// std::cout << "Size:" << size << " Capacity:" << capacity << " Stack:" << stack_capacity << " Actual:" << actual << std::endl;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//free(userBuffer);
|
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterativeInsitu_MemoryPoolAllocator)) {
|
||||||
|
for (size_t i = 0; i < kTrialCount; i++) {
|
||||||
|
memcpy(temp_, json_, length_ + 1);
|
||||||
|
Document doc;
|
||||||
|
doc.ParseInsitu<kParseIterativeFlag>(temp_);
|
||||||
|
ASSERT_TRUE(doc.IsObject());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator)) {
|
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator)) {
|
||||||
//const size_t userBufferSize = 128 * 1024;
|
|
||||||
//char* userBuffer = (char*)malloc(userBufferSize);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < kTrialCount; i++) {
|
for (size_t i = 0; i < kTrialCount; i++) {
|
||||||
//MemoryPoolAllocator<> allocator(userBuffer, userBufferSize);
|
|
||||||
//Document doc(&allocator);
|
|
||||||
Document doc;
|
Document doc;
|
||||||
doc.Parse(json_);
|
doc.Parse(json_);
|
||||||
ASSERT_TRUE(doc.IsObject());
|
ASSERT_TRUE(doc.IsObject());
|
||||||
//if (i == 0) {
|
|
||||||
// size_t size = doc.GetAllocator().Size();
|
|
||||||
// size_t capacity = doc.GetAllocator().Capacity();
|
|
||||||
// size_t stack_capacity = doc.GetStackCapacity();
|
|
||||||
// size_t actual = size - stack_capacity;
|
|
||||||
// std::cout << "Size:" << size << " Capacity:" << capacity << " Stack:" << stack_capacity << " Actual:" << actual << std::endl;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//free(userBuffer);
|
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterative_MemoryPoolAllocator)) {
|
||||||
|
for (size_t i = 0; i < kTrialCount; i++) {
|
||||||
|
Document doc;
|
||||||
|
doc.Parse<kParseIterativeFlag>(json_);
|
||||||
|
ASSERT_TRUE(doc.IsObject());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_CrtAllocator)) {
|
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_CrtAllocator)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user