diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/utils/CharReader.cpp | 72 | ||||
-rw-r--r-- | src/core/utils/CharReader.hpp | 22 |
2 files changed, 72 insertions, 22 deletions
diff --git a/src/core/utils/CharReader.cpp b/src/core/utils/CharReader.cpp index 61bbd64..12d0043 100644 --- a/src/core/utils/CharReader.cpp +++ b/src/core/utils/CharReader.cpp @@ -41,7 +41,7 @@ namespace utils { */ static size_t istreamReadCallback(char *buf, size_t size, void *userData) { - return (static_cast<std::istream*>(userData))->read(buf, size).gcount(); + return (static_cast<std::istream *>(userData))->read(buf, size).gcount(); } /* Class Buffer */ @@ -371,24 +371,22 @@ void CharReader::Cursor::assign(std::shared_ptr<Buffer> buffer, /* CharReader class */ -CharReader::CharReader(std::shared_ptr<Buffer> buffer) +CharReader::CharReader(std::shared_ptr<Buffer> buffer, size_t line, + size_t column) : buffer(buffer), - readCursor(buffer->createCursor()), - peekCursor(buffer->createCursor()) + readCursor(buffer->createCursor(), line, column), + peekCursor(buffer->createCursor(), line, column), + coherent(true) { } CharReader::CharReader(const std::string &str, size_t line, size_t column) - : buffer(new Buffer{str}), - readCursor(buffer->createCursor(), line, column), - peekCursor(buffer->createCursor(), line, column) + : CharReader(std::shared_ptr<Buffer>{new Buffer{str}}, line, column) { } CharReader::CharReader(std::istream &istream, size_t line, size_t column) - : buffer(new Buffer{istream}), - readCursor(buffer->createCursor(), line, column), - peekCursor(buffer->createCursor(), line, column) + : CharReader(std::shared_ptr<Buffer>{new Buffer{istream}}, line, column) { } @@ -467,13 +465,51 @@ bool CharReader::readAtCursor(Cursor &cursor, char &c) } } -bool CharReader::peek(char &c) { return readAtCursor(peekCursor, c); } +bool CharReader::peek(char &c) +{ + // If the reader was coherent, update the peek cursor state + if (coherent) { + peekCursor.assign(buffer, readCursor); + coherent = false; + } -bool CharReader::read(char &c) { return readAtCursor(readCursor, c); } + // Read a character from the peek cursor + return readAtCursor(peekCursor, c); +} -void CharReader::resetPeek() { peekCursor.assign(buffer, readCursor); } +bool CharReader::read(char &c) +{ + // Read a character from the buffer at the current read cursor + bool res = readAtCursor(readCursor, c); + + // Set the peek position to the current read position, if reading was not + // coherent + if (!coherent) { + peekCursor.assign(buffer, readCursor); + coherent = true; + } else { + buffer->copyCursor(readCursor.cursor, peekCursor.cursor); + } -void CharReader::consumePeek() { readCursor.assign(buffer, peekCursor); } + // Return the result of the read function + return res; +} + +void CharReader::resetPeek() +{ + if (!coherent) { + peekCursor.assign(buffer, readCursor); + coherent = true; + } +} + +void CharReader::consumePeek() +{ + if (!coherent) { + readCursor.assign(buffer, peekCursor); + coherent = true; + } +} bool CharReader::consumeWhitespace() { @@ -490,20 +526,22 @@ bool CharReader::consumeWhitespace() CharReaderFork CharReader::fork() { - return CharReaderFork(buffer, readCursor, peekCursor); + return CharReaderFork(buffer, readCursor, peekCursor, coherent); } /* Class CharReaderFork */ CharReaderFork::CharReaderFork(std::shared_ptr<Buffer> buffer, CharReader::Cursor &parentReadCursor, - CharReader::Cursor &parentPeekCursor) - : CharReader(buffer), + CharReader::Cursor &parentPeekCursor, + bool coherent) + : CharReader(buffer, 1, 1), parentReadCursor(parentReadCursor), parentPeekCursor(parentPeekCursor) { readCursor.assign(buffer, parentReadCursor); peekCursor.assign(buffer, parentPeekCursor); + this->coherent = coherent; } void CharReaderFork::commit() diff --git a/src/core/utils/CharReader.hpp b/src/core/utils/CharReader.hpp index a48f5ad..3d4c894 100644 --- a/src/core/utils/CharReader.hpp +++ b/src/core/utils/CharReader.hpp @@ -377,7 +377,7 @@ protected: * * @param cursor is the underlying cursor in the Buffer instance. */ - Cursor(Buffer::CursorId cursor, size_t line = 1, size_t column = 1) + Cursor(Buffer::CursorId cursor, size_t line, size_t column) : cursor(cursor), line(line), column(column), @@ -433,13 +433,19 @@ protected: Cursor peekCursor; /** + * Set to true as long the underlying Buffer cursor is at the same position + * for the read and the peek cursor. + */ + bool coherent; + + /** * Protected constructor of the CharReader base class. Creates new read * and peek cursors for the given buffer. * * @param buffer is a reference to the underlying Buffer class responsible * for allowing to read from a single input stream from multiple locations. */ - CharReader(std::shared_ptr<Buffer> buffer); + CharReader(std::shared_ptr<Buffer> buffer, size_t line, size_t column); public: /** @@ -538,14 +544,14 @@ public: * * @return the current line number. */ - int getLine() const { return readCursor.line; } + size_t getLine() const { return readCursor.line; } /** * Returns the current column (starting with one). * * @return the current column number. */ - int getColumn() const { return readCursor.column; } + size_t getColumn() const { return readCursor.column; } }; /** @@ -570,10 +576,16 @@ private: /** * Constructor of the CharReaderFork class. + * + * @param buffer is a reference at the parent Buffer instance. + * @param parentPeekCursor is a reference at the parent read cursor. + * @param parentPeekCursor is a reference at the parent peek cursor. + * @param coherent specifies whether the char reader cursors are initialized + * coherently. */ CharReaderFork(std::shared_ptr<Buffer> buffer, CharReader::Cursor &parentReadCursor, - CharReader::Cursor &parentPeekCursor); + CharReader::Cursor &parentPeekCursor, bool coherent); public: /** |