Add feature of locating line and column number of error

This commit is contained in:
KaitoHH 2017-09-26 15:39:06 +08:00
parent 2a0bc6062b
commit b16ff281f8
3 changed files with 60 additions and 1 deletions

View File

@ -2219,14 +2219,17 @@ public:
\return The document itself for fluent API.
*/
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
GenericDocument& ParseStream(InputStream& is) {
GenericDocument& ParseStream(InputStream& is_) {
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
ClearStackOnExit scope(*this);
GenericStreamWrapper<InputStream, SourceEncoding> is(is_);
parseResult_ = reader.template Parse<parseFlags>(is, *this);
if (parseResult_) {
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
} else {
parseResult_.SetPos(is.line_, is.col_);
}
return *this;
}
@ -2355,6 +2358,12 @@ public:
//! Get the position of last parsing error in input, 0 otherwise.
size_t GetErrorOffset() const { return parseResult_.Offset(); }
//! Get the position of last parsing error in input, 0 otherwise.
size_t GetErrorLine() const { return parseResult_.Line(); }
//! Get the position of last parsing error in input, 0 otherwise.
size_t GetErrorColumn() const { return parseResult_.Col(); }
//! Implicit conversion to get the last parse result
#ifndef __clang // -Wdocumentation

View File

@ -116,6 +116,10 @@ public:
ParseErrorCode Code() const { return code_; }
//! Get the error offset, if \ref IsError(), 0 otherwise.
size_t Offset() const { return offset_; }
//! Get the position of line number if error exists.
size_t Line() const { return line_; }
//! Get the position of column number if error exists.
size_t Col() const { return col_; }
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
@ -134,10 +138,14 @@ public:
void Clear() { Set(kParseErrorNone); }
//! Update error code and offset.
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
//! Update line number and column number of the error position
void SetPos(size_t line, size_t col) { line_ = line; col_ = col; }
private:
ParseErrorCode code_;
size_t offset_;
size_t line_;
size_t col_;
};
//! Function pointer type of GetParseError().

View File

@ -100,6 +100,48 @@ inline void PutN(Stream& stream, Ch c, size_t n) {
PutUnsafe(stream, c);
}
///////////////////////////////////////////////////////////////////////////////
// GenericStreamWrapper
//! A Stream Wrapper
/*! \tThis string stream is designed for counting line and column number
\tof the error (if exists) position, while just forwarding any received
\tmessage to the origin stream.
\note implements Stream concept
*/
template <typename InputStream, typename Encoding>
class GenericStreamWrapper {
public:
typedef typename Encoding::Ch Ch;
size_t line_;
size_t col_;
GenericStreamWrapper(InputStream& is): is_(is), line_(1), col_(0) {}
Ch Peek() const { return is_.Peek(); }
// counting line and column number
Ch Take() {
Ch ch = is_.Take();
if(ch == '\n') {
line_ ++;
col_ = 0;
} else {
col_ ++;
}
return ch;
}
size_t Tell() { return is_.Tell(); }
Ch* PutBegin() { return is_.PutBegin(); }
void Put(Ch ch) { return is_.Put(ch); }
void Flush() { return is_.Flush(); }
size_t PutEnd(Ch* ch) { is_.PutEnd(ch); }
const Ch* Peek4() const { is_.Peek4(); }
private:
InputStream& is_;
};
///////////////////////////////////////////////////////////////////////////////
// StringStream