/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the Qt3Support module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "q3membuf_p.h" | |
QT_BEGIN_NAMESPACE | |
// ******************************************************************* | |
// QMembuf declaration and implementation | |
// ******************************************************************* | |
/* \internal | |
This class implements an efficient buffering of data that is often used by | |
asynchronous IO classes like QSocket, QHttp and QProcess. | |
*/ | |
Q3Membuf::Q3Membuf() : _size(0), _index(0) | |
{ | |
} | |
Q3Membuf::~Q3Membuf() | |
{ | |
while (!buf.isEmpty()) | |
delete buf.takeFirst(); | |
} | |
/*! \internal | |
This function consumes \a nbytes bytes of data from the | |
buffer and copies it into \a sink. If \a sink is a 0 pointer | |
the data goes into the nirvana. | |
*/ | |
bool Q3Membuf::consumeBytes(Q_ULONG nbytes, char *sink) | |
{ | |
if (nbytes <= 0 || (qint64)nbytes > _size) | |
return false; | |
_size -= nbytes; | |
while (!buf.isEmpty()) { | |
QByteArray *a = buf.first(); | |
if ((int)(_index + nbytes) >= a->size()) { | |
// Here we skip the whole byte array and get the next later | |
int len = a->size() - _index; | |
if (sink) { | |
memcpy(sink, a->constData()+_index, len); | |
sink += len; | |
} | |
nbytes -= len; | |
buf.removeFirst(); | |
delete a; | |
_index = 0; | |
if (nbytes == 0) | |
break; | |
} else { | |
// Here we skip only a part of the first byte array | |
if (sink) | |
memcpy(sink, a->constData()+_index, nbytes); | |
_index += nbytes; | |
break; | |
} | |
} | |
return true; | |
} | |
/*! \internal | |
Scans for any occurrence of '\n' in the buffer. If \a store | |
is not 0 the text up to the first '\n' (or terminating 0) is | |
written to \a store, and a terminating 0 is appended to \a store | |
if necessary. Returns true if a '\n' was found; otherwise returns | |
false. | |
*/ | |
bool Q3Membuf::scanNewline(QByteArray *store) | |
{ | |
if (_size == 0) | |
return false; | |
int i = 0; // index into 'store' | |
QByteArray *a = 0; | |
char *p; | |
int n; | |
bool retval = false; | |
for (int j = 0; j < buf.size(); ++j) { | |
a = buf.at(j); | |
p = a->data(); | |
n = a->size(); | |
if (!j) { | |
// first buffer | |
p += _index; | |
n -= _index; | |
} | |
if (store) { | |
while (n-- > 0) { | |
*(store->data()+i) = *p; | |
if (++i == (int)store->size()) | |
store->resize(store->size() < 256 | |
? 1024 : store->size()*4); | |
if (*p == '\n') { | |
retval = true; | |
goto end; | |
} | |
p++; | |
} | |
} else { | |
while (n-- > 0) { | |
if(*p == '\n') | |
return true; | |
p++; | |
} | |
} | |
} | |
end: | |
if (store) | |
store->resize(i); | |
return retval; | |
} | |
int Q3Membuf::ungetch(int ch) | |
{ | |
if (buf.isEmpty() || _index==0) { | |
// we need a new QByteArray | |
QByteArray *ba = new QByteArray; | |
ba->resize(1); | |
buf.prepend(ba); | |
_size++; | |
(*ba)[0] = ch; | |
} else { | |
// we can reuse a place in the buffer | |
QByteArray *ba = buf.first(); | |
_index--; | |
_size++; | |
(*ba)[(int)_index] = ch; | |
} | |
return ch; | |
} | |
QT_END_NAMESPACE |