17void QRingChunk::allocate(qsizetype alloc)
19 Q_ASSERT(alloc > 0 && size() == 0);
21 if (chunk.size() < alloc || isShared())
22 chunk = QByteArray(alloc, Qt::Uninitialized);
35QByteArray QRingChunk::toByteArray() &&
38 if (headOffset != 0 || tailOffset != chunk.size()) {
40 return chunk.sliced(head(), size());
42 chunk.resize(tailOffset);
43 chunk.remove(0, headOffset);
46 return std::move(chunk);
73void QRingBuffer::free(qint64 bytes)
75 Q_ASSERT(bytes <= bufferSize);
78 const qint64 chunkSize = buffers.constFirst().size();
80 if (buffers.size() == 1 || chunkSize > bytes) {
81 QRingChunk &chunk = buffers.first();
85 if (bufferSize == bytes) {
86 if (chunk.capacity() <= basicBlockSize && !chunk.isShared()) {
93 Q_ASSERT(bytes < QByteArray::maxSize());
100 bufferSize -= chunkSize;
102 buffers.removeFirst();
106char *QRingBuffer::reserve(qint64 bytes)
108 Q_ASSERT(bytes > 0 && bytes < QByteArray::maxSize());
110 const qsizetype chunkSize = qMax(qint64(basicBlockSize), bytes);
112 if (bufferSize == 0) {
113 if (buffers.isEmpty())
114 buffers.append(QRingChunk(chunkSize));
116 buffers.first().allocate(chunkSize);
118 const QRingChunk &chunk = buffers.constLast();
120 if (basicBlockSize == 0 || chunk.isShared() || bytes > chunk.available())
121 buffers.append(QRingChunk(chunkSize));
126 buffers.last().grow(bytes);
128 return buffers.last().data() + tail;
136char *QRingBuffer::reserveFront(qint64 bytes)
138 Q_ASSERT(bytes > 0 && bytes < QByteArray::maxSize());
140 const qsizetype chunkSize = qMax(qint64(basicBlockSize), bytes);
141 if (bufferSize == 0) {
142 if (buffers.isEmpty())
143 buffers.prepend(QRingChunk(chunkSize));
145 buffers.first().allocate(chunkSize);
146 buffers.first().grow(chunkSize);
147 buffers.first().advance(chunkSize - bytes);
149 const QRingChunk &chunk = buffers.constFirst();
151 if (basicBlockSize == 0 || chunk.isShared() || bytes > chunk.head()) {
152 buffers.prepend(QRingChunk(chunkSize));
153 buffers.first().grow(chunkSize);
154 buffers.first().advance(chunkSize - bytes);
156 buffers.first().advance(-bytes);
161 return buffers.first().data();
164void QRingBuffer::chop(qint64 bytes)
166 Q_ASSERT(bytes <= bufferSize);
169 const qsizetype chunkSize = buffers.constLast().size();
171 if (buffers.size() == 1 || chunkSize > bytes) {
172 QRingChunk &chunk = buffers.last();
176 if (bufferSize == bytes) {
177 if (chunk.capacity() <= basicBlockSize && !chunk.isShared()) {
184 Q_ASSERT(bytes < QByteArray::maxSize());
191 bufferSize -= chunkSize;
193 buffers.removeLast();
207qint64 QRingBuffer::indexOf(
char c, qint64 maxLength, qint64 pos)
const
209 Q_ASSERT(maxLength >= 0 && pos >= 0);
215 for (
const QRingChunk &chunk : buffers) {
216 const qint64 nextBlockIndex = qMin(index + chunk.size(), maxLength);
218 if (nextBlockIndex > 0) {
219 const char *ptr = chunk.data();
225 const char *findPtr =
reinterpret_cast<
const char *>(memchr(ptr, c,
226 nextBlockIndex - index));
228 return qint64(findPtr - ptr) + index + pos;
230 if (nextBlockIndex == maxLength)
233 index = nextBlockIndex;
238qint64 QRingBuffer::read(
char *data, qint64 maxLength)
240 const qint64 bytesToRead = qMin(size(), maxLength);
241 qint64 readSoFar = 0;
242 while (readSoFar < bytesToRead) {
243 const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
244 nextDataBlockSize());
246 memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock);
247 readSoFar += bytesToReadFromThisBlock;
248 free(bytesToReadFromThisBlock);
272qint64 QRingBuffer::peek(
char *data, qint64 maxLength, qint64 pos)
const
274 Q_ASSERT(maxLength >= 0 && pos >= 0);
276 qint64 readSoFar = 0;
277 for (
const QRingChunk &chunk : buffers) {
278 if (readSoFar == maxLength)
281 qint64 blockLength = chunk.size();
282 if (pos < blockLength) {
283 blockLength = qMin(blockLength - pos, maxLength - readSoFar);
284 memcpy(data + readSoFar, chunk.data() + pos, blockLength);
285 readSoFar += blockLength;