summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qringbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qringbuffer.cpp')
-rw-r--r--src/corelib/tools/qringbuffer.cpp89
1 files changed, 60 insertions, 29 deletions
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index 85cfdaf129..e9b655c01e 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();
@@ -193,20 +209,32 @@ void QRingBuffer::clear()
bufferSize = 0;
}
-qint64 QRingBuffer::indexOf(char c, qint64 maxLength) const
+qint64 QRingBuffer::indexOf(char c, qint64 maxLength, qint64 pos) const
{
- qint64 index = 0;
- qint64 j = head;
- for (int i = 0; index < maxLength && i < buffers.size(); ++i) {
- const char *ptr = buffers[i].constData() + j;
- j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength);
-
- while (index < j) {
- if (*ptr++ == c)
- return index;
- ++index;
+ if (maxLength <= 0 || pos < 0)
+ return -1;
+
+ qint64 index = -(pos + head);
+ for (int i = 0; i < buffers.size(); ++i) {
+ const qint64 nextBlockIndex = qMin(index + (i == tailBuffer ? tail : buffers[i].size()),
+ maxLength);
+
+ if (nextBlockIndex > 0) {
+ const char *ptr = buffers[i].constData();
+ if (index < 0) {
+ ptr -= index;
+ index = 0;
+ }
+
+ const char *findPtr = reinterpret_cast<const char *>(memchr(ptr, c,
+ nextBlockIndex - index));
+ if (findPtr)
+ return qint64(findPtr - ptr) + index + pos;
+
+ if (nextBlockIndex == maxLength)
+ return -1;
}
- j = 0;
+ index = nextBlockIndex;
}
return -1;
}
@@ -288,7 +316,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);