diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2016-07-12 16:14:11 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2016-07-23 09:05:13 +0000 |
commit | 3c6a7a96ef17d5bd1fbea1d9e06617d281c6ca20 (patch) | |
tree | fa9927bdf77e682b2efed3098d6fb663915cc48d | |
parent | 3605fc653b3f54c9cda59fb3bf29b97d85ae0737 (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.cpp | 46 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp | 20 |
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; |