diff options
Diffstat (limited to 'src/corelib/io/qiodevice_p.h')
-rw-r--r-- | src/corelib/io/qiodevice_p.h | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h new file mode 100644 index 0000000000..06de7d7781 --- /dev/null +++ b/src/corelib/io/qiodevice_p.h @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIODEVICE_P_H +#define QIODEVICE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qiodevice.h" +#include "QtCore/qbytearray.h" +#include "QtCore/qobjectdefs.h" +#include "QtCore/qstring.h" +#include "private/qringbuffer_p.h" +#ifndef QT_NO_QOBJECT +#include "private/qobject_p.h" +#endif + +QT_BEGIN_NAMESPACE + +#ifndef QIODEVICE_BUFFERSIZE +#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384) +#endif + +// This is QIODevice's read buffer, optimized for read(), isEmpty() and getChar() +class QIODevicePrivateLinearBuffer +{ +public: + QIODevicePrivateLinearBuffer(int) : len(0), first(0), buf(0), capacity(0) { + } + ~QIODevicePrivateLinearBuffer() { + delete [] buf; + } + void clear() { + first = buf; + len = 0; + } + int size() const { + return len; + } + bool isEmpty() const { + return len == 0; + } + void skip(int n) { + if (n >= len) { + clear(); + } else { + len -= n; + first += n; + } + } + int getChar() { + if (len == 0) + return -1; + int ch = uchar(*first); + len--; + first++; + return ch; + } + int read(char* target, int size) { + int r = qMin(size, len); + memcpy(target, first, r); + len -= r; + first += r; + return r; + } + char* reserve(int size) { + makeSpace(size + len, freeSpaceAtEnd); + char* writePtr = first + len; + len += size; + return writePtr; + } + void chop(int size) { + if (size >= len) { + clear(); + } else { + len -= size; + } + } + QByteArray readAll() { + char* f = first; + int l = len; + clear(); + return QByteArray(f, l); + } + int readLine(char* target, int size) { + int r = qMin(size, len); + char* eol = static_cast<char*>(memchr(first, '\n', r)); + if (eol) + r = 1+(eol-first); + memcpy(target, first, r); + len -= r; + first += r; + return int(r); + } + bool canReadLine() const { + return memchr(first, '\n', len); + } + void ungetChar(char c) { + if (first == buf) { + // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer + makeSpace(len+1, freeSpaceAtStart); + } + first--; + len++; + *first = c; + } + void ungetBlock(const char* block, int size) { + if ((first - buf) < size) { + // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer + makeSpace(len + size, freeSpaceAtStart); + } + first -= size; + len += size; + memcpy(first, block, size); + } + +private: + enum FreeSpacePos {freeSpaceAtStart, freeSpaceAtEnd}; + void makeSpace(size_t required, FreeSpacePos where) { + size_t newCapacity = qMax(capacity, size_t(QIODEVICE_BUFFERSIZE)); + while (newCapacity < required) + newCapacity *= 2; + int moveOffset = (where == freeSpaceAtEnd) ? 0 : newCapacity - len; + if (newCapacity > capacity) { + // allocate more space + char* newBuf = new char[newCapacity]; + memmove(newBuf + moveOffset, first, len); + delete [] buf; + buf = newBuf; + capacity = newCapacity; + } else { + // shift any existing data to make space + memmove(buf + moveOffset, first, len); + } + first = buf + moveOffset; + } + +private: + // length of the unread data + int len; + // start of the unread data + char* first; + // the allocated buffer + char* buf; + // allocated buffer size + size_t capacity; +}; + +class Q_CORE_EXPORT QIODevicePrivate +#ifndef QT_NO_QOBJECT + : public QObjectPrivate +#endif +{ + Q_DECLARE_PUBLIC(QIODevice) + +public: + QIODevicePrivate(); + virtual ~QIODevicePrivate(); + + QIODevice::OpenMode openMode; + QString errorString; + + QIODevicePrivateLinearBuffer buffer; + qint64 pos; + qint64 devicePos; + // these three are for fast position updates during read, avoiding isSequential test + qint64 seqDumpPos; + qint64 *pPos; + qint64 *pDevicePos; + bool baseReadLineDataCalled; + bool firstRead; + + virtual bool putCharHelper(char c); + + enum AccessMode { + Unset, + Sequential, + RandomAccess + }; + mutable AccessMode accessMode; + inline bool isSequential() const + { + if (accessMode == Unset) + accessMode = q_func()->isSequential() ? Sequential : RandomAccess; + return accessMode == Sequential; + } + + virtual qint64 peek(char *data, qint64 maxSize); + virtual QByteArray peek(qint64 maxSize); + +#ifdef QT_NO_QOBJECT + QIODevice *q_ptr; +#endif +}; + +QT_END_NAMESPACE + +#endif // QIODEVICE_P_H |