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>
This commit is contained in:
parent
3605fc653b
commit
3c6a7a96ef
@ -108,24 +108,25 @@ char *QRingBuffer::reserve(qint64 bytes)
|
|||||||
if (bytes <= 0 || bytes >= MaxByteArraySize)
|
if (bytes <= 0 || bytes >= MaxByteArraySize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (buffers.isEmpty()) {
|
if (bufferSize == 0) {
|
||||||
buffers.append(QByteArray());
|
if (buffers.isEmpty())
|
||||||
buffers.first().resize(qMax(basicBlockSize, int(bytes)));
|
buffers.append(QByteArray(qMax(basicBlockSize, int(bytes)), Qt::Uninitialized));
|
||||||
|
else
|
||||||
|
buffers.first().resize(qMax(basicBlockSize, int(bytes)));
|
||||||
} else {
|
} else {
|
||||||
const qint64 newSize = bytes + tail;
|
const qint64 newSize = bytes + tail;
|
||||||
// if need buffer reallocation
|
// if need a new buffer
|
||||||
if (newSize > buffers.constLast().size()) {
|
if (basicBlockSize == 0 || (newSize > buffers.constLast().capacity()
|
||||||
if (newSize > buffers.constLast().capacity() && (tail >= basicBlockSize
|
&& (tail >= basicBlockSize || newSize >= MaxByteArraySize))) {
|
||||||
|| newSize >= MaxByteArraySize)) {
|
// shrink this buffer to its current size
|
||||||
// shrink this buffer to its current size
|
buffers.last().resize(tail);
|
||||||
buffers.last().resize(tail);
|
|
||||||
|
|
||||||
// create a new QByteArray
|
// create a new QByteArray
|
||||||
buffers.append(QByteArray());
|
buffers.append(QByteArray(qMax(basicBlockSize, int(bytes)), Qt::Uninitialized));
|
||||||
++tailBuffer;
|
++tailBuffer;
|
||||||
tail = 0;
|
tail = 0;
|
||||||
}
|
} else if (newSize > buffers.constLast().size()) {
|
||||||
buffers.last().resize(qMax(basicBlockSize, tail + int(bytes)));
|
buffers.last().resize(qMax(basicBlockSize, int(newSize)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,10 +147,8 @@ char *QRingBuffer::reserveFront(qint64 bytes)
|
|||||||
if (bytes <= 0 || bytes >= MaxByteArraySize)
|
if (bytes <= 0 || bytes >= MaxByteArraySize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (head < bytes) {
|
if (head < bytes || basicBlockSize == 0) {
|
||||||
if (buffers.isEmpty()) {
|
if (head > 0) {
|
||||||
buffers.append(QByteArray());
|
|
||||||
} else {
|
|
||||||
buffers.first().remove(0, head);
|
buffers.first().remove(0, head);
|
||||||
if (tailBuffer == 0)
|
if (tailBuffer == 0)
|
||||||
tail -= head;
|
tail -= head;
|
||||||
@ -157,12 +156,15 @@ char *QRingBuffer::reserveFront(qint64 bytes)
|
|||||||
|
|
||||||
head = qMax(basicBlockSize, int(bytes));
|
head = qMax(basicBlockSize, int(bytes));
|
||||||
if (bufferSize == 0) {
|
if (bufferSize == 0) {
|
||||||
|
if (buffers.isEmpty())
|
||||||
|
buffers.prepend(QByteArray(head, Qt::Uninitialized));
|
||||||
|
else
|
||||||
|
buffers.first().resize(head);
|
||||||
tail = head;
|
tail = head;
|
||||||
} else {
|
} else {
|
||||||
buffers.prepend(QByteArray());
|
buffers.prepend(QByteArray(head, Qt::Uninitialized));
|
||||||
++tailBuffer;
|
++tailBuffer;
|
||||||
}
|
}
|
||||||
buffers.first().resize(head);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
head -= int(bytes);
|
head -= int(bytes);
|
||||||
|
@ -45,6 +45,7 @@ private slots:
|
|||||||
void sizeWhenReserved();
|
void sizeWhenReserved();
|
||||||
void free();
|
void free();
|
||||||
void reserveAndRead();
|
void reserveAndRead();
|
||||||
|
void reserveAndReadInPacketMode();
|
||||||
void reserveFrontAndRead();
|
void reserveFrontAndRead();
|
||||||
void chop();
|
void chop();
|
||||||
void ungetChar();
|
void ungetChar();
|
||||||
@ -243,6 +244,25 @@ void tst_QRingBuffer::reserveAndRead()
|
|||||||
QCOMPARE(ringBuffer.size(), Q_INT64_C(0));
|
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()
|
void tst_QRingBuffer::reserveFrontAndRead()
|
||||||
{
|
{
|
||||||
QRingBuffer ringBuffer;
|
QRingBuffer ringBuffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user