QRingBuffer: allow to peek bytes from any position

Add an ordinary peek() function which also allows retrieving data from
a specified position. We need this functionality in several places.

Change-Id: Ia4a1b6fe1d7f76cb8f6f1ea34b3e4b89e05a2a68
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Alex Trotsenko 2015-03-23 14:36:19 +02:00
parent 921b22e5ce
commit 853cba729b
2 changed files with 50 additions and 0 deletions

View File

@ -293,6 +293,30 @@ public:
return qba;
}
// peek the bytes from a specified position
inline qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const
{
qint64 readSoFar = 0;
if (pos >= 0) {
pos += head;
for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) {
qint64 blockLength = (i == tailBuffer ? tail : buffers[i].size());
if (pos < blockLength) {
blockLength = qMin(blockLength - pos, maxLength - readSoFar);
memcpy(data + readSoFar, buffers[i].constData() + pos, blockLength);
readSoFar += blockLength;
pos = 0;
} else {
pos -= blockLength;
}
}
}
return readSoFar;
}
// append a new buffer to the end
inline void append(const QByteArray &qba) {
if (tail == 0) {

View File

@ -52,6 +52,7 @@ private slots:
void ungetChar();
void indexOf();
void appendAndRead();
void peek();
void readLine();
};
@ -280,6 +281,31 @@ void tst_QRingBuffer::appendAndRead()
QVERIFY(ringBuffer.read() == ba3);
}
void tst_QRingBuffer::peek()
{
QRingBuffer ringBuffer;
QByteArray testBuffer;
// fill buffer with an arithmetic progression
for (int i = 1; i < 256; ++i) {
char *ringPos = ringBuffer.reserve(i);
QVERIFY(ringPos);
memset(ringPos, i, i);
testBuffer.append(ringPos, i);
}
// check stored data
QByteArray resultBuffer;
int peekPosition = testBuffer.size();
for (int i = 1; i < 256; ++i) {
QByteArray ba(i, 0);
peekPosition -= i;
qint64 thisPeek = ringBuffer.peek(ba.data(), i, peekPosition);
QCOMPARE(thisPeek, qint64(i));
resultBuffer.prepend(ba);
}
QCOMPARE(testBuffer, resultBuffer);
}
void tst_QRingBuffer::readLine()
{
QRingBuffer ringBuffer;