summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2016-07-12 16:14:11 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2016-07-23 09:05:13 +0000
commit3c6a7a96ef17d5bd1fbea1d9e06617d281c6ca20 (patch)
treefa9927bdf77e682b2efed3098d6fb663915cc48d
parent3605fc653b3f54c9cda59fb3bf29b97d85ae0737 (diff)
QRingBuffer: add packet mode
As a special case, setting the value of chunk size to zero forces QRingBuffer to produce a separate QByteArray on each call which appends the data. So, this enables a packet mode where portions of data are stored independently from each other. Change-Id: I2d0b331211901a289da7d4533e974f06830b5590 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qringbuffer.cpp46
-rw-r--r--tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp20
2 files changed, 44 insertions, 22 deletions
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index 4a2dfdec2b..cb11e72435 100644
--- a/src/corelib/tools/qringbuffer.cpp
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -108,24 +108,25 @@ char *QRingBuffer::reserve(qint64 bytes)
if (bytes <= 0 || bytes >= MaxByteArraySize)
return 0;
- if (buffers.isEmpty()) {
- buffers.append(QByteArray());
- buffers.first().resize(qMax(basicBlockSize, int(bytes)));
+ if (bufferSize == 0) {
+ if (buffers.isEmpty())
+ buffers.append(QByteArray(qMax(basicBlockSize, int(bytes)), Qt::Uninitialized));
+ else
+ buffers.first().resize(qMax(basicBlockSize, int(bytes)));
} else {
const qint64 newSize = bytes + tail;
- // if need buffer reallocation
- if (newSize > buffers.constLast().size()) {
- if (newSize > buffers.constLast().capacity() && (tail >= basicBlockSize
- || newSize >= MaxByteArraySize)) {
- // shrink this buffer to its current size
- buffers.last().resize(tail);
-
- // create a new QByteArray
- buffers.append(QByteArray());
- ++tailBuffer;
- tail = 0;
- }
- buffers.last().resize(qMax(basicBlockSize, tail + int(bytes)));
+ // if need a new buffer
+ if (basicBlockSize == 0 || (newSize > buffers.constLast().capacity()
+ && (tail >= basicBlockSize || newSize >= MaxByteArraySize))) {
+ // shrink this buffer to its current size
+ buffers.last().resize(tail);
+
+ // create a new QByteArray
+ buffers.append(QByteArray(qMax(basicBlockSize, int(bytes)), Qt::Uninitialized));
+ ++tailBuffer;
+ tail = 0;
+ } else if (newSize > buffers.constLast().size()) {
+ buffers.last().resize(qMax(basicBlockSize, int(newSize)));
}
}
@@ -146,10 +147,8 @@ char *QRingBuffer::reserveFront(qint64 bytes)
if (bytes <= 0 || bytes >= MaxByteArraySize)
return 0;
- if (head < bytes) {
- if (buffers.isEmpty()) {
- buffers.append(QByteArray());
- } else {
+ if (head < bytes || basicBlockSize == 0) {
+ if (head > 0) {
buffers.first().remove(0, head);
if (tailBuffer == 0)
tail -= head;
@@ -157,12 +156,15 @@ char *QRingBuffer::reserveFront(qint64 bytes)
head = qMax(basicBlockSize, int(bytes));
if (bufferSize == 0) {
+ if (buffers.isEmpty())
+ buffers.prepend(QByteArray(head, Qt::Uninitialized));
+ else
+ buffers.first().resize(head);
tail = head;
} else {
- buffers.prepend(QByteArray());
+ buffers.prepend(QByteArray(head, Qt::Uninitialized));
++tailBuffer;
}
- buffers.first().resize(head);
}
head -= int(bytes);
diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
index 4e14fd7a9b..145ba7ff72 100644
--- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
+++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
@@ -45,6 +45,7 @@ private slots:
void sizeWhenReserved();
void free();
void reserveAndRead();
+ void reserveAndReadInPacketMode();
void reserveFrontAndRead();
void chop();
void ungetChar();
@@ -243,6 +244,25 @@ void tst_QRingBuffer::reserveAndRead()
QCOMPARE(ringBuffer.size(), Q_INT64_C(0));
}
+void tst_QRingBuffer::reserveAndReadInPacketMode()
+{
+ QRingBuffer ringBuffer(0);
+ // try to allocate 255 buffers
+ for (int i = 1; i < 256; ++i) {
+ char *ringPos = ringBuffer.reserve(i);
+ QVERIFY(ringPos);
+ }
+
+ // count and check the size of stored buffers
+ int buffersCount = 0;
+ while (!ringBuffer.isEmpty()) {
+ QByteArray ba = ringBuffer.read();
+ ++buffersCount;
+ QCOMPARE(ba.size(), buffersCount);
+ }
+ QCOMPARE(buffersCount, 255);
+}
+
void tst_QRingBuffer::reserveFrontAndRead()
{
QRingBuffer ringBuffer;