diff options
-rw-r--r-- | src/corelib/text/qbytedata_p.h | 49 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp | 55 |
2 files changed, 104 insertions, 0 deletions
diff --git a/src/corelib/text/qbytedata_p.h b/src/corelib/text/qbytedata_p.h index 551edc8b1b..053e4202d3 100644 --- a/src/corelib/text/qbytedata_p.h +++ b/src/corelib/text/qbytedata_p.h @@ -193,6 +193,55 @@ public: return originalAmount; } + /*! + \internal + Returns a view into the first QByteArray contained inside, + ignoring any already read data. Call advanceReadPointer() + to advance the view forward. When a QByteArray is exhausted + the view returned by this function will view into another + QByteArray if any. Returns a default constructed view if + no data is available. + + \sa advanceReadPointer + */ + QByteArrayView readPointer() const + { + if (isEmpty()) + return {}; + return { buffers.first().constData() + qsizetype(firstPos), + buffers.first().size() - qsizetype(firstPos) }; + } + + /*! + \internal + Advances the read pointer by \a distance. + + \sa readPointer + */ + void advanceReadPointer(qint64 distance) + { + qint64 newPos = firstPos + distance; + if (isEmpty()) { + newPos = 0; + } else if (auto size = buffers.first().size(); newPos >= size) { + while (newPos >= size) { + bufferCompleteSize -= (size - firstPos); + newPos -= size; + buffers.pop_front(); + if (isEmpty()) { + size = 0; + newPos = 0; + break; + } + size = buffers.front().size(); + } + bufferCompleteSize -= newPos; + } else { + bufferCompleteSize -= newPos - firstPos; + } + firstPos = newPos; + } + inline char getChar() { char c; diff --git a/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp b/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp index 7ef163349a..dfe37e4210 100644 --- a/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp +++ b/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp @@ -43,6 +43,7 @@ private Q_SLOTS: void readCompleteBuffer(); void readPartialBuffer_data(); void readPartialBuffer(); + void readPointer(); private: void readBuffer(int size, int readSize); }; @@ -170,5 +171,59 @@ void tst_QByteDataBuffer::readPartialBuffer() readBuffer(size, QIODEVICE_BUFFERSIZE); } +void tst_QByteDataBuffer::readPointer() +{ + QByteDataBuffer buffer; + + auto view = buffer.readPointer(); + QCOMPARE(view.size(), 0); + QCOMPARE(view, ""); + + buffer.append("Hello"); + buffer.append("World"); + + qint64 initialSize = buffer.byteAmount(); + view = buffer.readPointer(); + + QCOMPARE(initialSize, buffer.byteAmount()); + QCOMPARE(view.size(), 5); + QCOMPARE(view, "Hello"); + + buffer.advanceReadPointer(2); + view = buffer.readPointer(); + + QCOMPARE(initialSize - 2, buffer.byteAmount()); + QCOMPARE(view.size(), 3); + QCOMPARE(view, "llo"); + + buffer.advanceReadPointer(3); + view = buffer.readPointer(); + + QCOMPARE(initialSize - 5, buffer.byteAmount()); + QCOMPARE(view.size(), 5); + QCOMPARE(view, "World"); + + buffer.advanceReadPointer(5); + view = buffer.readPointer(); + + QVERIFY(buffer.isEmpty()); + QCOMPARE(view.size(), 0); + QCOMPARE(view, ""); + + // Advance past the current view's size + buffer.append("Hello"); + buffer.append("World"); + + buffer.advanceReadPointer(6); + view = buffer.readPointer(); + QCOMPARE(view, "orld"); + QCOMPARE(buffer.byteAmount(), 4); + + // Advance past the end of all contained data + buffer.advanceReadPointer(6); + view = buffer.readPointer(); + QCOMPARE(view, ""); +} + QTEST_MAIN(tst_QByteDataBuffer) #include "tst_qbytedatabuffer.moc" |