QByteDataBuffer: add readPointer functionality using QByteArrayView
While it could be done before it's nice to not have a custom "local" struct or the size in an out-parameter. Change-Id: Ie910f7060b1dadf037312d45e922f8e2deafe3ec Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
0011a45102
commit
43f01ec2e5
@ -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;
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user