# # # patch "src/util/AbstractParser.cpp" # from [786005713ec406b5fc970cc9244368a0a6f94dae] # to [fc2fa0fd3e3b2e83add1dd69a461bcb328467b08] # # patch "src/util/AbstractParser.h" # from [9e8c5dbcca5ca5ea62036a43632ed1667378abd3] # to [3602e6ed957f2fe41b5c7335af1ebb0ed2547f5b] # # patch "src/util/BasicIOParser.cpp" # from [02cbfce11c34893f9bc5e4c74075cece7c1e1d73] # to [efa4e089d061a603c1db6ab8553fa4afa0ed3456] # # patch "src/util/StdioParser.cpp" # from [b616c228e2e63fc654376851fe43f7e8dc70fad8] # to [48c78328277cff98a5ba59e95e32c3440637c964] # ============================================================ --- src/util/AbstractParser.cpp 786005713ec406b5fc970cc9244368a0a6f94dae +++ src/util/AbstractParser.cpp fc2fa0fd3e3b2e83add1dd69a461bcb328467b08 @@ -18,34 +18,93 @@ #include "AbstractParser.h" -AbstractParser::AbstractParser(const QString & in) : input(in.toUtf8()) {} +AbstractParser::AbstractParser(const QString & in) +{ + init(in.toUtf8()); +} -AbstractParser::AbstractParser(const QByteArray & in) : input(in) {} +AbstractParser::AbstractParser(const QByteArray & in) +{ + init(in); +} -AbstractParser::~AbstractParser() {} +void AbstractParser::init(const QByteArray & in) +{ + input = in; + if (input.size() == 0) + charPos = -1; + else + charPos = 0; +} +AbstractParser::~AbstractParser() +{ + input.clear(); +} + void AbstractParser::eatSpaces() { - while (whatsNext() == ' ') { advance(); } + while (whatsNext(0) == ' ') { advance(1); } } -char AbstractParser::whatsNext(int count /* = 0 */) +char AbstractParser::whatsNext(int count /* = 0 */) const { - if (count > (input.size() - 1)) return '\0'; - return input.at(count); + if (charPos == -1) + return '\0'; + + int nextPos = charPos + count; + + if (nextPos >= input.size()) + return '\0'; + + return input.at(nextPos); } -bool AbstractParser::advance(int count /* = 1 */) +void AbstractParser::advance(int count /* = 1 */) { - if (count > input.size()) return false; - input.remove(0, count); - return true; + if (charPos == -1) + return; + + if (charPos + count >= input.size()) + { + charPos = -1; + return; + } + + charPos += count; } char AbstractParser::getNext() { - char ch = input.at(0); - advance(); + const char ch = whatsNext(0); + advance(1); return ch; } +QByteArray AbstractParser::getNext(int count) +{ + if ((charPos + count) > (input.size() - 1)) + { + QByteArray left = getLeftBytes(); + charPos = -1; + return left; + } + + QByteArray next = input.mid(charPos, count); + advance(count); + return next; +} + +QByteArray AbstractParser::getLeftBytes() const +{ + if (charPos == -1) return QByteArray(); + QByteArray left = input.mid(charPos); + return left; +} + +int AbstractParser::getLeftBytesCount() const +{ + if (charPos == -1) return 0; + return input.size() - charPos; +} + ============================================================ --- src/util/AbstractParser.h 9e8c5dbcca5ca5ea62036a43632ed1667378abd3 +++ src/util/AbstractParser.h 3602e6ed957f2fe41b5c7335af1ebb0ed2547f5b @@ -28,17 +28,21 @@ public: AbstractParser(const QByteArray &); AbstractParser(const QString &); virtual ~AbstractParser(); - virtual bool parse() = 0; - inline QByteArray getLeftBytes() const { return input; } + QByteArray getLeftBytes() const; + int getLeftBytesCount() const; protected: - char whatsNext(int count = 0); + char whatsNext(int count = 0) const; char getNext(); + QByteArray getNext(int); void eatSpaces(); - bool advance(int count = 1); + void advance(int count = 1); +private: + void init(const QByteArray &); QByteArray input; + int charPos; }; #endif ============================================================ --- src/util/BasicIOParser.cpp 02cbfce11c34893f9bc5e4c74075cece7c1e1d73 +++ src/util/BasicIOParser.cpp efa4e089d061a603c1db6ab8553fa4afa0ed3456 @@ -23,10 +23,9 @@ bool BasicIOParser::parse() bool BasicIOParser::parse() { - while (true) + while (getLeftBytesCount() > 0) { Stanza stanza = getStanza(); - if (stanza.empty()) break; stanzas.append(stanza); advance(); } @@ -70,10 +69,11 @@ Stanza BasicIOParser::getStanza() stanza.append(entry); eatSpaces(); + char cur = getNext(); - if (cur != '\n') + if (cur != '\n' && cur != '\0') { - W(QString("Expected '\\n', got '%1'").arg(cur)); + W(QString("Expected '\\n' or '\\0', got '%1'").arg(cur)); } } @@ -127,29 +127,22 @@ QString BasicIOParser::getHash() QString BasicIOParser::getHash() { eatSpaces(); - if (whatsNext() != QChar('[')) return QString(); + if (whatsNext() != '[') return QString(); advance(); - // special case: nonexistant revision ID - if (whatsNext() == QChar(']')) + QString hash; + while (true) { + char ch = whatsNext(); + if (ch < '0' || (ch > '9' && ch < 'a') || ch > 'f') + { + break; + } + hash.append(ch); advance(); - return QString(""); } + I(getNext() == ']'); - int hashLen = 40; - QString ret = QString::fromUtf8(input.mid(0, hashLen).data()); - advance(hashLen); - - char ch = whatsNext(); - if (ch == QChar(']')) - { - advance(); - } - else - { - W(QString("Expected ], got '%1'").arg(ch)); - } - return ret; + return hash; } ============================================================ --- src/util/StdioParser.cpp b616c228e2e63fc654376851fe43f7e8dc70fad8 +++ src/util/StdioParser.cpp 48c78328277cff98a5ba59e95e32c3440637c964 @@ -23,7 +23,7 @@ bool StdioParser::parse() bool StdioParser::parse() { - if (input.size() == 0) return false; + if (getLeftBytesCount() == 0) return false; // chunk format: :::: commandNumber = getNumber(); @@ -36,15 +36,13 @@ bool StdioParser::parse() chunkSize = getNumber(); I(getNext() == ':'); - int charsLeft = input.size(); + int charsLeft = getLeftBytesCount(); if (chunkSize > charsLeft) { return false; } - payload = input.mid(0, chunkSize); - advance(chunkSize); - + payload = getNext(chunkSize); return true; } @@ -53,8 +51,9 @@ int StdioParser::getNumber() int number = 0; int processedChars = 0; - while (char ch = whatsNext()) + while (true) { + char ch = whatsNext(); if (ch < '0' || ch > '9') { // ensure that we've read at least one char