From 526d9b52ce966c0feeed95b20c024fd2b3026d3c Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 3 Jun 2015 12:56:27 +0300 Subject: QRingBuffer: allow to search from any position Change-Id: I348cd9da88fc81c3dd0789ce8cce9d80c4524e24 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Thiago Macieira --- src/corelib/tools/qringbuffer.cpp | 37 +++++++++++++++------- src/corelib/tools/qringbuffer_p.h | 2 +- .../corelib/tools/qringbuffer/tst_qringbuffer.cpp | 3 +- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index 85cfdaf129..5345b44204 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -193,20 +193,33 @@ 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; + } + + do { + if (*ptr++ == c) + return index + pos; + } while (++index < nextBlockIndex); + + if (index == maxLength) + return -1; + } else { + index = nextBlockIndex; } - j = 0; } return -1; } diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index 68509a6a80..e7e80bc02c 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -114,7 +114,7 @@ public: Q_CORE_EXPORT void clear(); inline qint64 indexOf(char c) const { return indexOf(c, size()); } - Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength) const; + Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength, qint64 pos = 0) const; Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength); Q_CORE_EXPORT QByteArray read(); Q_CORE_EXPORT qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const; diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index 77fc6ad6ae..74b6edf11f 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -284,7 +284,8 @@ void tst_QRingBuffer::indexOf() for (int i = 1; i < 256; ++i) { qint64 index = ringBuffer.indexOf(char(i)); QCOMPARE(index, qint64(i - 1)); - QCOMPARE(ringBuffer.indexOf(char(i), i), index); + QCOMPARE(ringBuffer.indexOf(char(i), i, i >> 1), index); + QCOMPARE(ringBuffer.indexOf(char(i), 256, i), Q_INT64_C(-1)); QCOMPARE(ringBuffer.indexOf(char(i), i - 1), -1); // test for absent char } } -- cgit v1.2.3