diff options
-rw-r--r-- | src/corelib/tools/qringbuffer.cpp | 53 | ||||
-rw-r--r-- | src/corelib/tools/qringbuffer_p.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp | 26 |
3 files changed, 55 insertions, 28 deletions
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index 5345b44204..e38245ca0a 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -65,6 +65,8 @@ const char *QRingBuffer::readPointerAtPosition(qint64 pos, qint64 &length) const void QRingBuffer::free(qint64 bytes) { + Q_ASSERT(bytes <= bufferSize); + while (bytes > 0) { const qint64 blockSize = buffers.first().size() - head; @@ -100,20 +102,25 @@ char *QRingBuffer::reserve(qint64 bytes) if (bytes <= 0 || bytes >= MaxByteArraySize) return 0; - const qint64 newSize = bytes + tail; - // if need buffer reallocation - if (newSize > buffers.last().size()) { - if (newSize > buffers.last().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; + if (buffers.isEmpty()) { + buffers.append(QByteArray()); + buffers.first().resize(qMax(basicBlockSize, int(bytes))); + } else { + const qint64 newSize = bytes + tail; + // if need buffer reallocation + if (newSize > buffers.last().size()) { + if (newSize > buffers.last().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))); } - buffers.last().resize(qMax(basicBlockSize, tail + int(bytes))); } char *writePtr = buffers.last().data() + tail; @@ -134,9 +141,13 @@ char *QRingBuffer::reserveFront(qint64 bytes) return 0; if (head < bytes) { - buffers.first().remove(0, head); - if (tailBuffer == 0) - tail -= head; + if (buffers.isEmpty()) { + buffers.append(QByteArray()); + } else { + buffers.first().remove(0, head); + if (tailBuffer == 0) + tail -= head; + } head = qMax(basicBlockSize, int(bytes)); if (bufferSize == 0) { @@ -155,6 +166,8 @@ char *QRingBuffer::reserveFront(qint64 bytes) void QRingBuffer::chop(qint64 bytes) { + Q_ASSERT(bytes <= bufferSize); + while (bytes > 0) { if (tailBuffer == 0 || tail > bytes) { // keep a single block around if it does not exceed @@ -185,6 +198,9 @@ void QRingBuffer::chop(qint64 bytes) void QRingBuffer::clear() { + if (buffers.isEmpty()) + return; + buffers.erase(buffers.begin() + 1, buffers.end()); buffers.first().clear(); @@ -301,7 +317,10 @@ qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const void QRingBuffer::append(const QByteArray &qba) { if (tail == 0) { - buffers.last() = qba; + if (buffers.isEmpty()) + buffers.append(qba); + else + buffers.last() = qba; } else { buffers.last().resize(tail); buffers.append(qba); diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index e7e80bc02c..3a5ae1c4cc 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -54,9 +54,7 @@ class QRingBuffer { public: explicit inline QRingBuffer(int growth = 4096) : - head(0), tail(0), tailBuffer(0), basicBlockSize(growth), bufferSize(0) { - buffers.append(QByteArray()); - } + head(0), tail(0), tailBuffer(0), basicBlockSize(growth), bufferSize(0) { } inline qint64 nextDataBlockSize() const { return (tailBuffer == 0 ? tail : buffers.first().size()) - head; diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index 74b6edf11f..2695e6238c 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -39,11 +39,11 @@ class tst_QRingBuffer : public QObject { Q_OBJECT private slots: + void constructing(); void readPointerAtPositionWriteRead(); void readPointerAtPositionEmptyRead(); void readPointerAtPositionWithHead(); void readPointerAtPositionReadTooMuch(); - void sizeWhenEmpty(); void sizeWhenReservedAndChopped(); void sizeWhenReserved(); void free(); @@ -57,6 +57,23 @@ private slots: void readLine(); }; +void tst_QRingBuffer::constructing() +{ + QRingBuffer ringBuffer; + + QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); + QVERIFY(ringBuffer.isEmpty()); + QCOMPARE(ringBuffer.nextDataBlockSize(), Q_INT64_C(0)); + QVERIFY(ringBuffer.readPointer() == Q_NULLPTR); + QCOMPARE(ringBuffer.skip(5), Q_INT64_C(0)); + QCOMPARE(ringBuffer.read(), QByteArray()); + QCOMPARE(ringBuffer.getChar(), -1); + QVERIFY(!ringBuffer.canReadLine()); + + char buf[5]; + QCOMPARE(ringBuffer.peek(buf, sizeof(buf)), Q_INT64_C(0)); +} + void tst_QRingBuffer::sizeWhenReserved() { QRingBuffer ringBuffer; @@ -74,13 +91,6 @@ void tst_QRingBuffer::sizeWhenReservedAndChopped() QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); } -void tst_QRingBuffer::sizeWhenEmpty() -{ - QRingBuffer ringBuffer; - - QCOMPARE(ringBuffer.size(), Q_INT64_C(0)); -} - void tst_QRingBuffer::readPointerAtPositionReadTooMuch() { QRingBuffer ringBuffer; |