Commit 3693d61f authored by Milo Yip's avatar Milo Yip

Add parse error codes and API for converting error code to text.

Parse errors is represented as enum type `ParseErrorCode`.
Error texts are optional for user.
Added  `GetParseError_En()` in `error/en.h`, user can localize this file
into other files. User may dynamically change the locale in runtime.
parent 813eaf4e
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "rapidjson/writer.h" #include "rapidjson/writer.h"
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/error/en.h"
using namespace rapidjson; using namespace rapidjson;
...@@ -23,7 +24,7 @@ int main(int, char*[]) { ...@@ -23,7 +24,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<0>(is, writer)) { if (!reader.Parse<0>(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), reader.GetParseError()); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/error/en.h"
using namespace rapidjson; using namespace rapidjson;
...@@ -21,7 +22,7 @@ int main(int, char*[]) { ...@@ -21,7 +22,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), reader.GetParseError()); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/encodedstream.h" // NEW #include "rapidjson/encodedstream.h" // NEW
#include "rapidjson/error/en.h"
#ifdef _WIN32 #ifdef _WIN32
#include <fcntl.h> #include <fcntl.h>
#include <io.h> #include <io.h>
...@@ -47,7 +48,7 @@ int main(int, char*[]) { ...@@ -47,7 +48,7 @@ int main(int, char*[]) {
// JSON reader parse from the input stream and let writer generate the output. // JSON reader parse from the input stream and let writer generate the output.
//if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) { //if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), reader.GetParseError()); fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
return 1; return 1;
} }
......
...@@ -788,7 +788,7 @@ public: ...@@ -788,7 +788,7 @@ public:
/*! \param allocator Optional allocator for allocating stack memory. /*! \param allocator Optional allocator for allocating stack memory.
\param stackCapacity Initial capacity of stack in bytes. \param stackCapacity Initial capacity of stack in bytes.
*/ */
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {}
//! Parse JSON text from an input stream. //! Parse JSON text from an input stream.
/*! \tparam parseFlags Combination of ParseFlag. /*! \tparam parseFlags Combination of ParseFlag.
...@@ -802,11 +802,11 @@ public: ...@@ -802,11 +802,11 @@ public:
if (reader.template Parse<parseFlags>(is, *this)) { if (reader.template Parse<parseFlags>(is, *this)) {
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13. this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13.
parseError_ = 0; parseErrorCode_ = kParseErrorNone;
errorOffset_ = 0; errorOffset_ = 0;
} }
else { else {
parseError_ = reader.GetParseError(); parseErrorCode_ = reader.GetParseErrorCode();
errorOffset_ = reader.GetErrorOffset(); errorOffset_ = reader.GetErrorOffset();
ClearStack(); ClearStack();
} }
...@@ -851,10 +851,10 @@ public: ...@@ -851,10 +851,10 @@ public:
} }
//! Whether a parse error was occured in the last parsing. //! Whether a parse error was occured in the last parsing.
bool HasParseError() const { return parseError_ != 0; } bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; }
//! Get the message of parsing error. //! Get the message of parsing error.
const char* GetParseError() const { return parseError_; } ParseErrorCode GetParseError() const { return parseErrorCode_; }
//! Get the offset in character of the parsing error. //! Get the offset in character of the parsing error.
size_t GetErrorOffset() const { return errorOffset_; } size_t GetErrorOffset() const { return errorOffset_; }
...@@ -914,7 +914,7 @@ private: ...@@ -914,7 +914,7 @@ private:
static const size_t kDefaultStackCapacity = 1024; static const size_t kDefaultStackCapacity = 1024;
internal::Stack<Allocator> stack_; internal::Stack<Allocator> stack_;
const char* parseError_; ParseErrorCode parseErrorCode_;
size_t errorOffset_; size_t errorOffset_;
}; };
......
#ifndef RAPIDJSON_ERROR_EN_H__
#define RAPIDJSON_ERROR_EN_H__
#include "error.h"
namespace rapidjson {
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
switch (parseErrorCode) {
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
case kParseErrorDocumentRootNotObjectOrArray: return RAPIDJSON_ERROR_STRING("The document root must be either object or array.");
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Must be a comma or ']' after an array element.");
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoidng in string.");
case kParesErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to store in double.");
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
default:
return RAPIDJSON_ERROR_STRING("Unknown error.");
}
}
} // namespace rapidjson
#endif // RAPIDJSON_ERROR_EN_H__
#ifndef RAPIDJSON_ERROR_ERROR_H__
#define RAPIDJSON_ERROR_ERROR_H__
// For example, on Windows, user can define this macro as TCHAR
#ifndef RAPIDJSON_ERROR_CHARTYPE
#define RAPIDJSON_ERROR_CHARTYPE char
#endif
// For example, on Windows, user can define this macro as _T(x)
#ifndef RAPIDJSON_ERROR_STRING
#define RAPIDJSON_ERROR_STRING(x) x
#endif
namespace rapidjson {
// User can dynamically change locale in runtime, e.g.:
// GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
// const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
} // namespace rapidjson
#endif // RAPIDJSON_ERROR_ERROR_H__
\ No newline at end of file
...@@ -21,19 +21,19 @@ ...@@ -21,19 +21,19 @@
#endif #endif
#ifndef RAPIDJSON_PARSE_ERROR_NORETURN #ifndef RAPIDJSON_PARSE_ERROR_NORETURN
#define RAPIDJSON_PARSE_ERROR_NORETURN(msg, offset) \ #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \ RAPIDJSON_MULTILINEMACRO_BEGIN \
if (!HasParseError()) {\ if (!HasParseError()) {\
parseError_ = msg; \ parseErrorCode_ = parseErrorCode; \
errorOffset_ = offset; \ errorOffset_ = offset; \
}\ }\
RAPIDJSON_MULTILINEMACRO_END RAPIDJSON_MULTILINEMACRO_END
#endif #endif
#ifndef RAPIDJSON_PARSE_ERROR #ifndef RAPIDJSON_PARSE_ERROR
#define RAPIDJSON_PARSE_ERROR(msg, offset) \ #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \ RAPIDJSON_MULTILINEMACRO_BEGIN \
RAPIDJSON_PARSE_ERROR_NORETURN(msg, offset); \ RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
return; \ return; \
RAPIDJSON_MULTILINEMACRO_END RAPIDJSON_MULTILINEMACRO_END
#endif #endif
...@@ -50,6 +50,33 @@ enum ParseFlag { ...@@ -50,6 +50,33 @@ enum ParseFlag {
kParseValidateEncodingFlag = 2 //!< Validate encoding of JSON strings. kParseValidateEncodingFlag = 2 //!< Validate encoding of JSON strings.
}; };
//! Error code of parsing.
enum ParseErrorCode {
kParseErrorNone = 0, //!< No error.
kParseErrorDocumentEmpty, //!< The document is empty.
kParseErrorDocumentRootNotObjectOrArray, //!< The document root must be either object or array.
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
kParseErrorValueInvalid, //!< Invalid value.
kParseErrorObjectMissName, //!< Missing a name for object member.
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
kParseErrorArrayMissCommaOrSquareBracket, //!< Must be a comma or ']' after an array element.
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
kParseErrorStringInvalidEncoding, //!< Invalid encoidng in string.
kParesErrorNumberTooBig, //!< Number too big to store in double.
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
kParseErrorNumberMissExponent //!< Miss exponent in number.
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Handler // Handler
...@@ -218,7 +245,7 @@ public: ...@@ -218,7 +245,7 @@ public:
/*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) /*! \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) \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), parseError_(0), errorOffset_(0) {} GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {}
//! Parse JSON text. //! Parse JSON text.
/*! \tparam parseFlags Combination of ParseFlag. /*! \tparam parseFlags Combination of ParseFlag.
...@@ -230,31 +257,31 @@ public: ...@@ -230,31 +257,31 @@ public:
*/ */
template <unsigned parseFlags, typename InputStream, typename Handler> template <unsigned parseFlags, typename InputStream, typename Handler>
bool Parse(InputStream& is, Handler& handler) { bool Parse(InputStream& is, Handler& handler) {
parseError_ = 0; parseErrorCode_ = kParseErrorNone;
errorOffset_ = 0; errorOffset_ = 0;
SkipWhitespace(is); SkipWhitespace(is);
if (is.Peek() == '\0') if (is.Peek() == '\0')
RAPIDJSON_PARSE_ERROR_NORETURN("Text only contains white space(s)", is.Tell()); RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
else { else {
switch (is.Peek()) { switch (is.Peek()) {
case '{': ParseObject<parseFlags>(is, handler); break; case '{': ParseObject<parseFlags>(is, handler); break;
case '[': ParseArray<parseFlags>(is, handler); break; case '[': ParseArray<parseFlags>(is, handler); break;
default: RAPIDJSON_PARSE_ERROR_NORETURN("Expect either an object or array at root", is.Tell()); default: RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotObjectOrArray, is.Tell());
} }
SkipWhitespace(is); SkipWhitespace(is);
if (is.Peek() != '\0') if (is.Peek() != '\0')
RAPIDJSON_PARSE_ERROR_NORETURN("Nothing should follow the root object or array.", is.Tell()); RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
} }
stack_.Clear(); stack_.Clear();
return !HasParseError(); return !HasParseError();
} }
bool HasParseError() const { return parseError_ != 0; } bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; }
const char* GetParseError() const { return parseError_; } ParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
size_t GetErrorOffset() const { return errorOffset_; } size_t GetErrorOffset() const { return errorOffset_; }
private: private:
...@@ -274,7 +301,7 @@ private: ...@@ -274,7 +301,7 @@ private:
for (SizeType memberCount = 0;;) { for (SizeType memberCount = 0;;) {
if (is.Peek() != '"') if (is.Peek() != '"')
RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
ParseString<parseFlags>(is, handler); ParseString<parseFlags>(is, handler);
if (HasParseError()) if (HasParseError())
...@@ -283,7 +310,7 @@ private: ...@@ -283,7 +310,7 @@ private:
SkipWhitespace(is); SkipWhitespace(is);
if (is.Take() != ':') if (is.Take() != ':')
RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
SkipWhitespace(is); SkipWhitespace(is);
...@@ -298,7 +325,7 @@ private: ...@@ -298,7 +325,7 @@ private:
switch(is.Take()) { switch(is.Take()) {
case ',': SkipWhitespace(is); break; case ',': SkipWhitespace(is); break;
case '}': handler.EndObject(memberCount); return; case '}': handler.EndObject(memberCount); return;
default: RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", is.Tell()); default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
} }
} }
} }
...@@ -328,7 +355,7 @@ private: ...@@ -328,7 +355,7 @@ private:
switch (is.Take()) { switch (is.Take()) {
case ',': SkipWhitespace(is); break; case ',': SkipWhitespace(is); break;
case ']': handler.EndArray(elementCount); return; case ']': handler.EndArray(elementCount); return;
default: RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", is.Tell()); default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
} }
} }
} }
...@@ -341,7 +368,7 @@ private: ...@@ -341,7 +368,7 @@ private:
if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l')
handler.Null(); handler.Null();
else else
RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
} }
template<unsigned parseFlags, typename InputStream, typename Handler> template<unsigned parseFlags, typename InputStream, typename Handler>
...@@ -352,7 +379,7 @@ private: ...@@ -352,7 +379,7 @@ private:
if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e')
handler.Bool(true); handler.Bool(true);
else else
RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
} }
template<unsigned parseFlags, typename InputStream, typename Handler> template<unsigned parseFlags, typename InputStream, typename Handler>
...@@ -363,7 +390,7 @@ private: ...@@ -363,7 +390,7 @@ private:
if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e')
handler.Bool(false); handler.Bool(false);
else else
RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
} }
// Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
...@@ -382,7 +409,7 @@ private: ...@@ -382,7 +409,7 @@ private:
else if (c >= 'a' && c <= 'f') else if (c >= 'a' && c <= 'f')
codepoint -= 'a' - 10; codepoint -= 'a' - 10;
else { else {
RAPIDJSON_PARSE_ERROR_NORETURN("Incorrect hex digit after \\u escape", s.Tell() - 1); RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, s.Tell() - 1);
return 0; return 0;
} }
} }
...@@ -455,16 +482,16 @@ private: ...@@ -455,16 +482,16 @@ private:
if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
// Handle UTF-16 surrogate pair // Handle UTF-16 surrogate pair
if (is.Take() != '\\' || is.Take() != 'u') if (is.Take() != '\\' || is.Take() != 'u')
RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", is.Tell() - 2); RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
unsigned codepoint2 = ParseHex4(is); unsigned codepoint2 = ParseHex4(is);
if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", is.Tell() - 2); RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
} }
TEncoding::Encode(os, codepoint); TEncoding::Encode(os, codepoint);
} }
else else
RAPIDJSON_PARSE_ERROR("Unknown escape character", is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
} }
else if (c == '"') { // Closing double quote else if (c == '"') { // Closing double quote
is.Take(); is.Take();
...@@ -472,14 +499,14 @@ private: ...@@ -472,14 +499,14 @@ private:
return; return;
} }
else if (c == '\0') else if (c == '\0')
RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", is.Tell() - 1); RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
else { else {
if (parseFlags & kParseValidateEncodingFlag ? if (parseFlags & kParseValidateEncodingFlag ?
!Transcoder<SEncoding, TEncoding>::Validate(is, os) : !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
!Transcoder<SEncoding, TEncoding>::Transcode(is, os)) !Transcoder<SEncoding, TEncoding>::Transcode(is, os))
RAPIDJSON_PARSE_ERROR("Invalid encoding", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
} }
} }
} }
...@@ -526,7 +553,7 @@ private: ...@@ -526,7 +553,7 @@ private:
} }
} }
else else
RAPIDJSON_PARSE_ERROR("Expect a value here.", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
// Parse 64bit int // Parse 64bit int
uint64_t i64 = 0; uint64_t i64 = 0;
...@@ -559,7 +586,7 @@ private: ...@@ -559,7 +586,7 @@ private:
d = (double)i64; d = (double)i64;
while (s.Peek() >= '0' && s.Peek() <= '9') { while (s.Peek() >= '0' && s.Peek() <= '9') {
if (d >= 1E307) if (d >= 1E307)
RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); RAPIDJSON_PARSE_ERROR(kParesErrorNumberTooBig, is.Tell());
d = d * 10 + (s.Take() - '0'); d = d * 10 + (s.Take() - '0');
} }
} }
...@@ -578,7 +605,7 @@ private: ...@@ -578,7 +605,7 @@ private:
--expFrac; --expFrac;
} }
else else
RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, is.Tell());
while (s.Peek() >= '0' && s.Peek() <= '9') { while (s.Peek() >= '0' && s.Peek() <= '9') {
if (expFrac > -16) { if (expFrac > -16) {
...@@ -611,11 +638,11 @@ private: ...@@ -611,11 +638,11 @@ private:
while (s.Peek() >= '0' && s.Peek() <= '9') { while (s.Peek() >= '0' && s.Peek() <= '9') {
exp = exp * 10 + (s.Take() - '0'); exp = exp * 10 + (s.Take() - '0');
if (exp > 308) if (exp > 308)
RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); RAPIDJSON_PARSE_ERROR(kParesErrorNumberTooBig, is.Tell());
} }
} }
else else
RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
if (expMinus) if (expMinus)
exp = -exp; exp = -exp;
...@@ -660,7 +687,7 @@ private: ...@@ -660,7 +687,7 @@ private:
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<Allocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. internal::Stack<Allocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
const char* parseError_; ParseErrorCode parseErrorCode_;
size_t errorOffset_; size_t errorOffset_;
}; // class GenericReader }; // class GenericReader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment