Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterative Parsing (for issue #35) #76

Merged
merged 23 commits into from
Jul 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3006fa7
Try to resolve issue #35: implement iterative parsing.
thebusytypist Jul 6, 2014
7acb0c1
Rename flags/state names/functions/test cases from 'NonRecursive' to …
thebusytypist Jul 7, 2014
7d33b01
Bugfix: add missing transition from finish state.
thebusytypist Jul 7, 2014
ebb9a25
It is sufficient to check finish state in iterative parsing.
thebusytypist Jul 7, 2014
6b0df21
WIP: refactor iterative parsing.
thebusytypist Jul 7, 2014
91aaa34
Finish the new implementation of state machine. But not been unittested.
thebusytypist Jul 8, 2014
f6235b2
Add basic error handling.
thebusytypist Jul 9, 2014
692904b
Handle all unspecific parsing errors.
thebusytypist Jul 10, 2014
e3c4b33
Add unittests for state transition.
thebusytypist Jul 10, 2014
55e97ea
Add two basic performance tests.
thebusytypist Jul 10, 2014
70d01cc
Complete unittests for state transition.
thebusytypist Jul 11, 2014
36434b6
Merge remote-tracking branch 'upstream/master' into TransitionTable
thebusytypist Jul 11, 2014
3038a78
Revise unittests: reset the handler before the transition which we ar…
thebusytypist Jul 11, 2014
face724
Revise unittests of compound value(array or object)'s initial state t…
thebusytypist Jul 11, 2014
d4da07c
Merge upstream/master.
thebusytypist Jul 14, 2014
46e89da
Add unittests for kParserErrorTermination; Fix bugs in last merge.
thebusytypist Jul 14, 2014
1f53c6c
Implement stack size limitation for iterative parsing.
thebusytypist Jul 15, 2014
b22a89b
Reduce times of stack size check; reduce transition table size.
thebusytypist Jul 16, 2014
c3d7d8b
Revise unittests: should not expose implementation details.
thebusytypist Jul 16, 2014
fa25f93
Merge remote-tracking branch 'upstream/master' into TransitionTable
thebusytypist Jul 16, 2014
4a15264
Fix compilation error for gcc/clang.
thebusytypist Jul 17, 2014
afa5945
Fix compilation error(unused variable, signed/unsigned comparison).
thebusytypist Jul 17, 2014
140dc06
Fix compilation error(signed/unsigned comparison).
thebusytypist Jul 17, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions include/rapidjson/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -1221,12 +1221,13 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
\tparam SourceEncoding Encoding of input stream
\tparam InputStream Type of input stream, implementing Stream concept
\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.
*/
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
GenericDocument& ParseStream(InputStream& is) {
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
ValueType::SetNull(); // Remove existing root if exist
GenericReader<SourceEncoding, Encoding, Allocator> reader(&GetAllocator());
GenericReader<SourceEncoding, Encoding, Allocator> reader(limit, &GetAllocator());
ClearStackOnExit scope(*this);
parseResult_ = reader.template Parse<parseFlags>(is, *this);
if (parseResult_) {
Expand All @@ -1240,21 +1241,23 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
/*! \tparam parseFlags Combination of \ref ParseFlag.
\tparam InputStream Type of input stream, implementing Stream concept
\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.
*/
template <unsigned parseFlags, typename InputStream>
GenericDocument& ParseStream(InputStream& is) {
return ParseStream<parseFlags,Encoding,InputStream>(is);
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
return ParseStream<parseFlags,Encoding,InputStream>(is, limit);
}

//! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
/*! \tparam InputStream Type of input stream, implementing Stream concept
\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.
*/
template <typename InputStream>
GenericDocument& ParseStream(InputStream& is) {
return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
GenericDocument& ParseStream(InputStream& is, size_t limit = 0) {
return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is, limit);
}
//!@}

Expand All @@ -1265,30 +1268,33 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
/*! \tparam parseFlags Combination of \ref ParseFlag.
\tparam SourceEncoding Transcoding from input Encoding
\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.
*/
template <unsigned parseFlags, typename SourceEncoding>
GenericDocument& ParseInsitu(Ch* str) {
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
GenericInsituStringStream<Encoding> s(str);
return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s);
return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s, limit);
}

//! Parse JSON text from a mutable string
/*! \tparam parseFlags Combination of \ref ParseFlag.
\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.
*/
template <unsigned parseFlags>
GenericDocument& ParseInsitu(Ch* str) {
return ParseInsitu<parseFlags, Encoding>(str);
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
return ParseInsitu<parseFlags, Encoding>(str, limit);
}

//! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
/*! \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.
*/
GenericDocument& ParseInsitu(Ch* str) {
return ParseInsitu<kParseDefaultFlags, Encoding>(str);
GenericDocument& ParseInsitu(Ch* str, size_t limit = 0) {
return ParseInsitu<kParseDefaultFlags, Encoding>(str, limit);
}
//!@}

Expand All @@ -1299,28 +1305,31 @@ class GenericDocument : public GenericValue<Encoding, Allocator> {
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
\tparam SourceEncoding Transcoding from input Encoding
\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>
GenericDocument& Parse(const Ch* str) {
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
GenericStringStream<SourceEncoding> s(str);
return ParseStream<parseFlags, SourceEncoding>(s);
return ParseStream<parseFlags, SourceEncoding>(s, limit);
}

//! Parse JSON text from a read-only string
/*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
\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>
GenericDocument& Parse(const Ch* str) {
return Parse<parseFlags, Encoding>(str);
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
return Parse<parseFlags, Encoding>(str, limit);
}

//! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
/*! \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) {
return Parse<kParseDefaultFlags>(str);
GenericDocument& Parse(const Ch* str, size_t limit = 0) {
return Parse<kParseDefaultFlags>(str, limit);
}
//!@}

Expand Down
2 changes: 2 additions & 0 deletions include/rapidjson/error/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");

case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
case kParseErrorStackSizeLimitExceeded: return RAPIDJSON_ERROR_STRING("Parsing stack size limit is exceeded.");

default:
return RAPIDJSON_ERROR_STRING("Unknown error.");
Expand Down
4 changes: 3 additions & 1 deletion include/rapidjson/error/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ enum ParseErrorCode {
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
kParseErrorNumberMissExponent, //!< Miss exponent in number.

kParseErrorTermination //!< Parsing was terminated.
kParseErrorTermination, //!< Parsing was terminated.
kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error.
kParseErrorStackSizeLimitExceeded //!< Parsing stack size limit is exceeded.
};

//! Result of parsing (wraps ParseErrorCode)
Expand Down
Loading