diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index e397a48..b8d136d 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1210,7 +1210,7 @@ public: /*! \param allocator Optional allocator for allocating stack memory. \param stackCapacity Initial capacity of stack in bytes. */ - GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {} + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseResult_() {} //!@name Parse from stream //!@{ @@ -1227,12 +1227,11 @@ public: ValueType::SetNull(); // Remove existing root if exist GenericReader reader(&GetAllocator()); ClearStackOnExit scope(*this); - if (reader.template Parse(is, *this)) { + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object this->RawAssign(*stack_.template Pop(1)); // Add this-> to prevent issue 13. } - parseErrorCode_ = reader.GetParseErrorCode(); - errorOffset_ = reader.GetErrorOffset(); return *this; } @@ -1328,13 +1327,13 @@ public: //!@{ //! Whether a parse error was occured in the last parsing. - bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; } + bool HasParseError() const { return parseResult_.IsError(); } //! Get the message of parsing error. - ParseErrorCode GetParseError() const { return parseErrorCode_; } + ParseErrorCode GetParseError() const { return parseResult_.Code(); } //! Get the offset in character of the parsing error. - size_t GetErrorOffset() const { return errorOffset_; } + size_t GetErrorOffset() const { return parseResult_.Offset(); } //!@} @@ -1401,8 +1400,7 @@ private: static const size_t kDefaultStackCapacity = 1024; internal::Stack stack_; - ParseErrorCode parseErrorCode_; - size_t errorOffset_; + ParseResult parseResult_; }; //! GenericDocument with UTF8 encoding diff --git a/include/rapidjson/error/error.h b/include/rapidjson/error/error.h index af597d2..765f1c1 100644 --- a/include/rapidjson/error/error.h +++ b/include/rapidjson/error/error.h @@ -59,6 +59,28 @@ enum ParseErrorCode { kParseErrorNumberMissExponent //!< Miss exponent in number. }; +struct ParseResult { + + ParseResult() : code_(kParseErrorNone), offset_(0) {} + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + ParseErrorCode Code() const { return code_; } + size_t Offset() const { return offset_; } + + operator bool() const { return !IsError(); } + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + void Clear() { Set(kParseErrorNone); } + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; //! Function pointer type of GetParseError(). /*! This is the prototype for GetParseError_X(), where X is a locale. diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 00ee43e..72ebad9 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -38,8 +38,7 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ RAPIDJSON_MULTILINEMACRO_BEGIN \ RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ - parseErrorCode_ = parseErrorCode; \ - errorOffset_ = offset; \ + parseResult_.Set(parseErrorCode,offset); \ RAPIDJSON_MULTILINEMACRO_END #endif @@ -51,7 +50,7 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_MULTILINEMACRO_END #endif -#include "error/error.h" // ParseErrorCode +#include "error/error.h" // ParseErrorCode, ParseResult namespace rapidjson { @@ -273,7 +272,7 @@ public: /*! \param allocator 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) */ - GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {} + GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseResult_() {} //! Parse JSON text. /*! \tparam parseFlags Combination of \ref ParseFlag. @@ -284,16 +283,15 @@ public: \return Whether the parsing is successful. */ template - bool Parse(InputStream& is, Handler& handler) { - parseErrorCode_ = kParseErrorNone; - errorOffset_ = 0; + ParseResult Parse(InputStream& is, Handler& handler) { + parseResult_.Clear(); ClearStackOnExit scope(*this); SkipWhitespace(is); if (is.Peek() == '\0') { RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(false); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); } else { switch (is.Peek()) { @@ -301,17 +299,17 @@ public: case '[': ParseArray(is, handler); break; default: RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotObjectOrArray, is.Tell()); } - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(false); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); SkipWhitespace(is); if (is.Peek() != '\0') { RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(false); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); } } - return true; + return parseResult_; } //! Parse JSON text (with \ref kParseDefaultFlags) @@ -322,15 +320,15 @@ public: \return Whether the parsing is successful. */ template - bool Parse(InputStream& is, Handler& handler) { + ParseResult Parse(InputStream& is, Handler& handler) { return Parse(is, handler); } - bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; } + bool HasParseError() const { return parseResult_.IsError(); } - ParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } - size_t GetErrorOffset() const { return errorOffset_; } + size_t GetErrorOffset() const { return parseResult_.Offset(); } private: // Prohibit copy constructor & assignment operator. @@ -755,8 +753,7 @@ private: static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. - ParseErrorCode parseErrorCode_; - size_t errorOffset_; + ParseResult parseResult_; }; // class GenericReader //! Reader with UTF8 encoding and default allocator.