1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the core module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "private/qinternal_p.h"
33
Creates an empty ring buffer. The buffer will grow in steps of \a
34
growth as data is written to it.
36
QRingBuffer::QRingBuffer(int growth)
37
: basicBlockSize(growth)
39
buffers << QByteArray();
45
Returns the number of bytes that can be read in one operation. The
46
data is read from readPointer().
48
int QRingBuffer::nextDataBlockSize() const
50
return (tailBuffer == 0 ? tail : buffers.at(0).size()) - head;
55
Returns a pointer to where no more than nextDataBlockSize() bytes
56
of data can be read. Call free() to remove data after reading.
58
char *QRingBuffer::readPointer() const
60
if (buffers.count() == 0)
62
return const_cast<char *>(buffers[0].data()) + head;
67
Removes \a bytes bytes from the front of the buffer. If \a bytes
68
is larger than the size of the buffer, the buffer is cleared.
70
void QRingBuffer::free(int bytes)
77
int nextBlockSize = nextDataBlockSize();
78
if (bytes < nextBlockSize) {
80
if (head == tail && tailBuffer == 0)
85
bytes -= nextBlockSize;
86
if (buffers.count() == 1) {
87
if (buffers.at(0).size() != basicBlockSize)
88
buffers[0].resize(basicBlockSize);
102
Reserves space in the buffer for \a bytes new bytes, and returns a
103
pointer to the first byte.
105
char *QRingBuffer::reserve(int bytes)
109
// if there is already enough space, simply return.
110
if (tail + bytes <= buffers.at(tailBuffer).size()) {
111
char *writePtr = buffers[tailBuffer].data() + tail;
116
// if our buffer isn't half full yet, simply resize it.
117
if (tail < buffers.at(tailBuffer).size() / 2) {
118
buffers[tailBuffer].resize(tail + bytes);
119
char *writePtr = buffers[tailBuffer].data() + tail;
124
// shrink this buffer to its current size
125
buffers[tailBuffer].resize(tail);
127
// create a new QByteArray with the right size
128
buffers << QByteArray();
130
buffers[tailBuffer].resize(qMax(basicBlockSize, bytes));
132
return buffers[tailBuffer].data();
137
Removes \a bytes bytes from the end of the buffer. If \a bytes is
138
larger than the buffer size, the buffer is cleared.
140
void QRingBuffer::truncate(int bytes)
147
// special case: head and tail are in the same buffer
148
if (tailBuffer == 0) {
161
buffers.removeAt(tailBuffer);
164
tail = buffers.at(tailBuffer).size();
170
Returns and removes the first character in the buffer. Returns -1
171
if the buffer is empty.
173
int QRingBuffer::getChar()
177
char c = *readPointer();
184
Appends the character \a c to the end of the buffer.
186
void QRingBuffer::putChar(char c)
188
char *ptr = reserve(1);
194
Prepends the character \a c to the front of the buffer.
196
void QRingBuffer::ungetChar(char c)
200
buffers.prepend(QByteArray());
201
buffers[0].resize(basicBlockSize);
202
head = basicBlockSize - 1;
205
buffers[0][head] = c;
211
Returns the size of the buffer; e.g. the number of bytes
214
int QRingBuffer::size() const
221
Removes all data from the buffer and resets its size to 0.
223
void QRingBuffer::clear()
225
QByteArray tmp = buffers[0];
229
if (buffers.at(0).size() != basicBlockSize)
230
buffers[0].resize(basicBlockSize);
239
Returns true if the buffer is empty; otherwise returns false.
241
bool QRingBuffer::isEmpty() const
243
return tailBuffer == 0 && tail == 0;
248
Returns the index of the first occurrence of the character \a c in
249
the buffer. In no such character is found, -1 is returned.
251
int QRingBuffer::indexOf(char c) const
254
for (int i = 0; i < buffers.size(); ++i) {
256
int end = buffers.at(i).size();
262
const char *ptr = buffers.at(i).data() + start;
263
for (int j = start; j < end; ++j) {
275
Reads one line of data (all data up to and including the '\n'
276
character), no longer than \a maxSize - 1 bytes, and stores it in \a
277
data. If the line is too long, maxSize bytes of the line are read.
278
\a data is always terminated by a '\0' byte.
280
int QRingBuffer::readLine(char *data, int maxSize)
282
int index = indexOf('\n');
283
if (index == -1 || maxSize <= 0)
287
while (readSoFar < index && readSoFar < maxSize - 1) {
288
int bytesToRead = qMin((index + 1) - readSoFar, nextDataBlockSize());
289
bytesToRead = qMin(bytesToRead, (maxSize - 1) - readSoFar);
290
memcpy(data + readSoFar, readPointer(), bytesToRead);
291
readSoFar += bytesToRead;
296
data[readSoFar] = '\0';
302
Returns true if a line can be read from the buffer; otherwise
305
bool QRingBuffer::canReadLine() const
307
return indexOf('\n') != -1;