Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaitoHH <hh.kaito@gmail.com>2017-09-26 10:39:06 +0300
committerKaitoHH <hh.kaito@gmail.com>2017-09-29 10:24:27 +0300
commitb16ff281f854564e2669b2c3f4871793ddc51fc3 (patch)
treee4a5c1ce3ba5a7220ffb781b9dff9deea3147199
parent2a0bc6062b38ed40586bd8e1945835698b95a9c1 (diff)
Add feature of locating line and column number of error
-rw-r--r--include/rapidjson/document.h11
-rw-r--r--include/rapidjson/error/error.h8
-rw-r--r--include/rapidjson/stream.h42
3 files changed, 60 insertions, 1 deletions
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index 93b091f6..de657409 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -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
diff --git a/include/rapidjson/error/error.h b/include/rapidjson/error/error.h
index 9311d2f0..be805791 100644
--- a/include/rapidjson/error/error.h
+++ b/include/rapidjson/error/error.h
@@ -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().
diff --git a/include/rapidjson/stream.h b/include/rapidjson/stream.h
index fef82c25..4e4ba80a 100644
--- a/include/rapidjson/stream.h
+++ b/include/rapidjson/stream.h
@@ -101,6 +101,48 @@ inline void PutN(Stream& stream, Ch c, size_t n) {
}
///////////////////////////////////////////////////////////////////////////////
+// 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
//! Read-only string stream.