summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorIan Walters <ian.walters@nokia.com>2009-05-14 04:24:59 (GMT)
committerIan Walters <ian.walters@nokia.com>2009-05-14 04:24:59 (GMT)
commita8e4628a1f74b52a61b11b4b1fcc8ccdd4002a46 (patch)
treebac5b6e440ac7e5c7f9fe1eee53a75fb44a7e9dd /src/corelib/io
parentdf69dfe0ec549a259ed78cf48dff898d8a044c41 (diff)
parent9820412d2551b655fec24ffde7b2a56e3ad168ea (diff)
downloadQt-a8e4628a1f74b52a61b11b4b1fcc8ccdd4002a46.zip
Qt-a8e4628a1f74b52a61b11b4b1fcc8ccdd4002a46.tar.gz
Qt-a8e4628a1f74b52a61b11b4b1fcc8ccdd4002a46.tar.bz2
Merge branch 'master' of ../master into contiguouscache
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/io.pri3
-rw-r--r--src/corelib/io/qfileinfo_p.h145
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp2
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp542
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h189
5 files changed, 734 insertions, 147 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 3690d4b..8f37e25 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -10,9 +10,9 @@ HEADERS += \
io/qdiriterator.h \
io/qfile.h \
io/qfileinfo.h \
- io/qfileinfo_p.h \
io/qiodevice.h \
io/qiodevice_p.h \
+ io/qnoncontiguousbytedevice_p.h \
io/qprocess.h \
io/qprocess_p.h \
io/qtextstream.h \
@@ -38,6 +38,7 @@ SOURCES += \
io/qfile.cpp \
io/qfileinfo.cpp \
io/qiodevice.cpp \
+ io/qnoncontiguousbytedevice.cpp \
io/qprocess.cpp \
io/qtextstream.cpp \
io/qtemporaryfile.cpp \
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
deleted file mode 100644
index 7d66581..0000000
--- a/src/corelib/io/qfileinfo_p.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, 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.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFILEINFO_P_H
-#define QFILEINFO_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 "qfileinfo.h"
-
-QT_BEGIN_NAMESPACE
-
-class QFileInfoPrivate
-{
-public:
- QFileInfoPrivate(const QFileInfo *copy=0);
- ~QFileInfoPrivate();
-
- void initFileEngine(const QString &);
-
- enum Access {
- ReadAccess,
- WriteAccess,
- ExecuteAccess
- };
- bool hasAccess(Access access) const;
-
- uint getFileFlags(QAbstractFileEngine::FileFlags) const;
- QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
- QString getFileName(QAbstractFileEngine::FileName) const;
-
- enum {
- CachedFileFlags = 0x01,
- CachedLinkTypeFlag = 0x02,
- CachedBundleTypeFlag= 0x04,
- CachedMTime = 0x10,
- CachedCTime = 0x20,
- CachedATime = 0x40,
- CachedSize = 0x08
- };
-
- struct Data
- {
- inline Data()
- : ref(1), fileEngine(0), cache_enabled(1)
- {
- clear();
- }
-
- inline Data(const Data &copy)
- : ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)),
- fileName(copy.fileName), cache_enabled(copy.cache_enabled)
- {
- clear();
- }
-
- inline ~Data()
- {
- delete fileEngine;
- }
-
- inline void clear()
- {
- fileNames.clear();
- fileFlags = 0;
- cachedFlags = 0;
- }
-
- mutable QAtomicInt ref;
-
- QAbstractFileEngine *fileEngine;
- mutable QString fileName;
- mutable QHash<int, QString> fileNames;
- mutable uint cachedFlags : 31;
- mutable uint cache_enabled : 1;
- mutable uint fileFlags;
- mutable qint64 fileSize;
- mutable QDateTime fileTimes[3];
-
- inline bool getCachedFlag(uint c) const
- { return cache_enabled ? (cachedFlags & c) : 0; }
-
- inline void setCachedFlag(uint c)
- { if (cache_enabled) cachedFlags |= c; }
- } *data;
-
- inline void reset() {
- detach();
- data->clear();
- }
-
- void detach();
-};
-
-
-QT_END_NAMESPACE
-#endif
-
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 8a0a3f5..7a6a85b 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -780,7 +780,7 @@ QString QFSFileEngine::fileName(FileName file) const
#endif
if (len > 0) {
QString ret;
- if (S_ISDIR(d->st.st_mode) && s[0] != '/') {
+ if (d->doStat() && S_ISDIR(d->st.st_mode) && s[0] != '/') {
QDir parent(d->filePath);
parent.cdUp();
ret = parent.path();
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
new file mode 100644
index 0000000..6233fde
--- /dev/null
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnoncontiguousbytedevice_p.h"
+#include <QObject>
+#include <QBuffer>
+#include <QDebug>
+#include <QFile>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QNonContiguousByteDevice
+ \brief A QNonContiguousByteDevice is a representation of a
+ file, array or buffer that allows access with a read pointer.
+ \since 4.6
+
+ \inmodule QtCore
+
+ The goal of this class is to have a data representation that
+ allows us to avoid doing a memcpy as we have to do with QIODevice.
+
+ \sa QNonContiguousByteDeviceFactory
+
+ \internal
+*/
+/*!
+ \fn virtual const char* QNonContiguousByteDevice::readPointer(qint64 maximumLength, qint64 &len)
+
+ Return a byte pointer for at most \a maximumLength bytes of that device.
+ if \a maximumLength is -1, the caller does not care about the length and
+ the device may return what it desires to.
+ The actual number of bytes the pointer is valid for is returned in
+ the \a len variable.
+ \a len will be -1 if EOF or an error occurs.
+ If it was really EOF can then afterwards be checked with atEnd()
+ Returns 0 if it is not possible to read at that position.
+
+ \sa atEnd()
+
+ \internal
+*/
+/*!
+ \fn virtual bool QNonContiguousByteDevice::advanceReadPointer(qint64 amount)
+
+ will advance the internal read pointer by \a amount bytes.
+ The old readPointer is invalid after this call.
+
+ \sa readPointer()
+
+ \internal
+*/
+/*!
+ \fn virtual bool QNonContiguousByteDevice::atEnd()
+
+ Returns true if everything has been read and the read
+ pointer cannot be advanced anymore.
+
+ \sa readPointer(), advanceReadPointer(), reset()
+
+ \internal
+*/
+/*!
+ \fn virtual bool QNonContiguousByteDevice::reset()
+
+ Moves the internal read pointer back to the beginning.
+ Returns false if this was not possible.
+
+ \sa atEnd(), disableReset()
+
+ \internal
+*/
+/*!
+ \fn void QNonContiguousByteDevice::disableReset()
+
+ Disable the reset() call, e.g. it will always
+ do nothing and return false.
+
+ \sa reset()
+
+ \internal
+*/
+/*!
+ \fn virtual qint64 QNonContiguousByteDevice::size()
+
+ Returns the size of the complete device or -1 if unknown.
+ May also return less/more than what can be actually read with readPointer()
+
+ \internal
+*/
+/*!
+ \fn void QNonContiguousByteDevice::readyRead()
+
+ Emitted when there is data available
+
+ \internal
+*/
+/*!
+ \fn void QNonContiguousByteDevice::readProgress(qint64 current, qint64 total)
+
+ Emitted when data has been "read" by advancing the read pointer
+
+ \internal
+*/
+
+QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)0), resetDisabled(false)
+{
+};
+
+QNonContiguousByteDevice::~QNonContiguousByteDevice()
+{
+};
+
+void QNonContiguousByteDevice::disableReset()
+{
+ resetDisabled = true;
+}
+
+QNonContiguousByteDeviceBufferImpl::QNonContiguousByteDeviceBufferImpl(QBuffer *b) : QNonContiguousByteDevice()
+{
+ buffer = b;
+ byteArray = QByteArray::fromRawData(buffer->buffer().constData() + buffer->pos(), buffer->size() - buffer->pos());
+ arrayImpl = new QNonContiguousByteDeviceByteArrayImpl(&byteArray);
+ arrayImpl->setParent(this);
+ connect(arrayImpl, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ connect(arrayImpl, SIGNAL(readProgress(qint64,qint64)), SIGNAL(readProgress(qint64,qint64)));
+}
+
+QNonContiguousByteDeviceBufferImpl::~QNonContiguousByteDeviceBufferImpl()
+{
+}
+
+const char* QNonContiguousByteDeviceBufferImpl::readPointer(qint64 maximumLength, qint64 &len)
+{
+ return arrayImpl->readPointer(maximumLength, len);
+}
+
+bool QNonContiguousByteDeviceBufferImpl::advanceReadPointer(qint64 amount)
+{
+ return arrayImpl->advanceReadPointer(amount);
+}
+
+bool QNonContiguousByteDeviceBufferImpl::atEnd()
+{
+ return arrayImpl->atEnd();
+}
+
+bool QNonContiguousByteDeviceBufferImpl::reset()
+{
+ if (resetDisabled)
+ return false;
+ return arrayImpl->reset();
+}
+
+qint64 QNonContiguousByteDeviceBufferImpl::size()
+{
+ return arrayImpl->size();
+}
+
+QNonContiguousByteDeviceByteArrayImpl::QNonContiguousByteDeviceByteArrayImpl(QByteArray *ba) : QNonContiguousByteDevice(), currentPosition(0)
+{
+ byteArray = ba;
+}
+
+QNonContiguousByteDeviceByteArrayImpl::~QNonContiguousByteDeviceByteArrayImpl()
+{
+}
+
+const char* QNonContiguousByteDeviceByteArrayImpl::readPointer(qint64 maximumLength, qint64 &len)
+{
+ if (atEnd()) {
+ len = -1;
+ return 0;
+ }
+
+ if (maximumLength != -1)
+ len = qMin(maximumLength, size() - currentPosition);
+ else
+ len = size() - currentPosition;
+
+ return byteArray->constData() + currentPosition;
+}
+
+bool QNonContiguousByteDeviceByteArrayImpl::advanceReadPointer(qint64 amount)
+{
+ currentPosition += amount;
+ emit readProgress(currentPosition, size());
+ return true;
+}
+
+bool QNonContiguousByteDeviceByteArrayImpl::atEnd()
+{
+ return currentPosition >= size();
+}
+
+bool QNonContiguousByteDeviceByteArrayImpl::reset()
+{
+ if (resetDisabled)
+ return false;
+
+ currentPosition = 0;
+ return true;
+}
+
+qint64 QNonContiguousByteDeviceByteArrayImpl::size()
+{
+ return byteArray->size();
+}
+
+QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QRingBuffer *rb)
+ : QNonContiguousByteDevice(), currentPosition(0)
+{
+ ringBuffer = rb;
+}
+
+QNonContiguousByteDeviceRingBufferImpl::~QNonContiguousByteDeviceRingBufferImpl()
+{
+};
+
+const char* QNonContiguousByteDeviceRingBufferImpl::readPointer(qint64 maximumLength, qint64 &len)
+{
+ if (atEnd()) {
+ len = -1;
+ return 0;
+ }
+
+ const char *returnValue = ringBuffer->readPointerAtPosition(currentPosition, len);
+
+ if (maximumLength != -1)
+ len = qMin(len, maximumLength);
+
+ return returnValue;
+};
+
+bool QNonContiguousByteDeviceRingBufferImpl::advanceReadPointer(qint64 amount)
+{
+ currentPosition += amount;
+ emit readProgress(currentPosition, size());
+ return true;
+};
+
+bool QNonContiguousByteDeviceRingBufferImpl::atEnd()
+{
+ return currentPosition >= size();
+};
+
+bool QNonContiguousByteDeviceRingBufferImpl::reset()
+{
+ if (resetDisabled)
+ return false;
+
+ currentPosition = 0;
+ return true;
+};
+
+qint64 QNonContiguousByteDeviceRingBufferImpl::size()
+{
+ return ringBuffer->size();
+};
+
+QNonContiguousByteDeviceIoDeviceImpl::QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d)
+ : QNonContiguousByteDevice(),
+ currentReadBuffer(0), currentReadBufferSize(16*1024),
+ currentReadBufferAmount(0), currentReadBufferPosition(0), totalAdvancements(0),
+ eof(false)
+{
+ device = d;
+ initialPosition = d->pos();
+ connect(device, SIGNAL(readyRead()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
+ connect(device, SIGNAL(readChannelFinished()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
+};
+
+QNonContiguousByteDeviceIoDeviceImpl::~QNonContiguousByteDeviceIoDeviceImpl()
+{
+ delete currentReadBuffer;
+};
+
+const char* QNonContiguousByteDeviceIoDeviceImpl::readPointer(qint64 maximumLength, qint64 &len)
+{
+ if (eof == true) {
+ len = -1;
+ return 0;
+ }
+
+ if (currentReadBuffer == 0)
+ currentReadBuffer = new QByteArray(currentReadBufferSize, '\0'); // lazy alloc
+
+ if (maximumLength == -1)
+ maximumLength = currentReadBufferSize;
+
+ if (currentReadBufferAmount - currentReadBufferPosition > 0) {
+ len = currentReadBufferAmount - currentReadBufferPosition;
+ return currentReadBuffer->data() + currentReadBufferPosition;
+ }
+
+ qint64 haveRead = device->read(currentReadBuffer->data(), qMin(maximumLength, currentReadBufferSize));
+
+ if ((haveRead == -1) || (haveRead == 0 && device->atEnd() && !device->isSequential())) {
+ eof = true;
+ len = -1;
+ // size was unknown before, emit a readProgress with the final size
+ if (size() == -1)
+ emit readProgress(totalAdvancements, totalAdvancements);
+ return 0;
+ }
+
+ currentReadBufferAmount = haveRead;
+ currentReadBufferPosition = 0;
+
+ len = haveRead;
+ return currentReadBuffer->data();
+};
+
+bool QNonContiguousByteDeviceIoDeviceImpl::advanceReadPointer(qint64 amount)
+{
+ totalAdvancements += amount;
+
+ // normal advancement
+ currentReadBufferPosition += amount;
+
+ // advancing over that what has actually been read before
+ if (currentReadBufferPosition > currentReadBufferAmount) {
+ qint64 i = currentReadBufferPosition - currentReadBufferAmount;
+ while (i > 0) {
+ if (device->getChar(0) == false) {
+ emit readProgress(totalAdvancements - i, size());
+ return false; // ### FIXME handle eof
+ }
+ i--;
+ }
+
+ currentReadBufferPosition = 0;
+ currentReadBufferAmount = 0;
+ }
+
+ if (size() == -1)
+ emit readProgress(totalAdvancements, totalAdvancements);
+ else
+ emit readProgress(totalAdvancements, size());
+
+ return true;
+};
+
+bool QNonContiguousByteDeviceIoDeviceImpl::atEnd()
+{
+ return eof == true;
+};
+
+bool QNonContiguousByteDeviceIoDeviceImpl::reset()
+{
+ if (resetDisabled)
+ return false;
+
+ if (device->seek(initialPosition)) {
+ eof = false; // assume eof is false, it will be true after a read has been attempted
+ return true;
+ }
+
+ return false;
+};
+
+qint64 QNonContiguousByteDeviceIoDeviceImpl::size()
+{
+ // note that this is different from the size() implementation of QIODevice!
+
+ if (device->isSequential())
+ return -1;
+
+ return device->size() - initialPosition;
+};
+
+QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0)
+{
+ byteDevice = bd;
+ connect(bd, SIGNAL(readyRead()), SIGNAL(readyRead()));
+
+ open(ReadOnly);
+}
+
+QByteDeviceWrappingIoDevice::~QByteDeviceWrappingIoDevice()
+{
+
+}
+
+bool QByteDeviceWrappingIoDevice::isSequential() const
+{
+ return (byteDevice->size() == -1);
+}
+
+bool QByteDeviceWrappingIoDevice::atEnd() const
+{
+ return byteDevice->atEnd();
+}
+
+bool QByteDeviceWrappingIoDevice::reset()
+{
+ return byteDevice->reset();
+}
+
+qint64 QByteDeviceWrappingIoDevice::size() const
+{
+ if (isSequential())
+ return 0;
+
+ return byteDevice->size();
+}
+
+
+qint64 QByteDeviceWrappingIoDevice::readData( char * data, qint64 maxSize)
+{
+ qint64 len;
+ const char *readPointer = byteDevice->readPointer(maxSize, len);
+ if (len == -1)
+ return -1;
+
+ memcpy(data, readPointer, len);
+ byteDevice->advanceReadPointer(len);
+ return len;
+}
+
+qint64 QByteDeviceWrappingIoDevice::writeData( const char* data, qint64 maxSize)
+{
+ return -1;
+}
+
+/*!
+ \class QNonContiguousByteDeviceFactory
+ \since 4.6
+
+ \inmodule QtCore
+
+ Creates a QNonContiguousByteDevice out of a QIODevice,
+ QByteArray etc.
+
+ \sa QNonContiguousByteDevice
+
+ \internal
+*/
+
+/*!
+ \fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QIODevice *device);
+
+ Create a QNonContiguousByteDevice out of a QIODevice.
+ For QFile, QBuffer and all other QIoDevice, sequential or not.
+
+ \internal
+*/
+QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QIODevice *device)
+{
+ // shortcut if it is a QBuffer
+ if (QBuffer* buffer = qobject_cast<QBuffer*>(device)) {
+ return new QNonContiguousByteDeviceBufferImpl(buffer);
+ }
+
+ // ### FIXME special case if device is a QFile that supports map()
+ // then we can actually deal with the file without using read/peek
+
+ // generic QIODevice
+ return new QNonContiguousByteDeviceIoDeviceImpl(device); // FIXME
+};
+
+/*!
+ \fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QRingBuffer *ringBuffer);
+
+ Create a QNonContiguousByteDevice out of a QRingBuffer.
+
+ \internal
+*/
+QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QRingBuffer *ringBuffer)
+{
+ return new QNonContiguousByteDeviceRingBufferImpl(ringBuffer);
+};
+
+/*!
+ \fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *byteArray);
+
+ Create a QNonContiguousByteDevice out of a QByteArray.
+
+ \internal
+*/
+QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *byteArray)
+{
+ return new QNonContiguousByteDeviceByteArrayImpl(byteArray);
+};
+
+/*!
+ \fn static QIODevice* QNonContiguousByteDeviceFactory::wrap(QNonContiguousByteDevice* byteDevice);
+
+ Wrap the \a byteDevice (possibly again) into a QIODevice.
+
+ \internal
+*/
+QIODevice* QNonContiguousByteDeviceFactory::wrap(QNonContiguousByteDevice* byteDevice)
+{
+ // ### FIXME if it already has been based on QIoDevice, we could that one out again
+ // and save some calling
+
+ // needed for FTP backend
+
+ return new QByteDeviceWrappingIoDevice(byteDevice);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
new file mode 100644
index 0000000..2a7e40b
--- /dev/null
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNONCONTIGUOUSBYTEDEVICE_H
+#define QNONCONTIGUOUSBYTEDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qbuffer.h>
+#include <QtCore/qiodevice.h>
+#include "private/qringbuffer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_CORE_EXPORT QNonContiguousByteDevice : public QObject
+{
+ Q_OBJECT
+public:
+ virtual const char* readPointer(qint64 maximumLength, qint64 &len) = 0;
+ virtual bool advanceReadPointer(qint64 amount) = 0;
+ virtual bool atEnd() = 0;
+ virtual bool reset() = 0;
+ void disableReset();
+ virtual qint64 size() = 0;
+
+protected:
+ QNonContiguousByteDevice();
+ virtual ~QNonContiguousByteDevice();
+
+ bool resetDisabled;
+signals:
+ void readyRead();
+ void readProgress(qint64 current, qint64 total);
+};
+
+class Q_CORE_EXPORT QNonContiguousByteDeviceFactory
+{
+public:
+ static QNonContiguousByteDevice* create(QIODevice *device);
+ static QNonContiguousByteDevice* create(QByteArray *byteArray);
+ static QNonContiguousByteDevice* create(QRingBuffer *ringBuffer);
+ static QIODevice* wrap(QNonContiguousByteDevice* byteDevice);
+};
+
+// the actual implementations
+//
+
+class QNonContiguousByteDeviceByteArrayImpl : public QNonContiguousByteDevice
+{
+ Q_OBJECT
+public:
+ QNonContiguousByteDeviceByteArrayImpl(QByteArray *ba);
+ ~QNonContiguousByteDeviceByteArrayImpl();
+ const char* readPointer(qint64 maximumLength, qint64 &len);
+ bool advanceReadPointer(qint64 amount);
+ bool atEnd();
+ bool reset();
+ qint64 size();
+protected:
+ QByteArray* byteArray;
+ qint64 currentPosition;
+};
+
+class QNonContiguousByteDeviceRingBufferImpl : public QNonContiguousByteDevice
+{
+ Q_OBJECT
+public:
+ QNonContiguousByteDeviceRingBufferImpl(QRingBuffer *rb);
+ ~QNonContiguousByteDeviceRingBufferImpl();
+ const char* readPointer(qint64 maximumLength, qint64 &len);
+ bool advanceReadPointer(qint64 amount);
+ bool atEnd();
+ bool reset();
+ qint64 size();
+protected:
+ QRingBuffer* ringBuffer;
+ qint64 currentPosition;
+};
+
+
+class QNonContiguousByteDeviceIoDeviceImpl : public QNonContiguousByteDevice
+{
+ Q_OBJECT
+public:
+ QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d);
+ ~QNonContiguousByteDeviceIoDeviceImpl();
+ const char* readPointer(qint64 maximumLength, qint64 &len);
+ bool advanceReadPointer(qint64 amount);
+ bool atEnd();
+ bool reset();
+ qint64 size();
+protected:
+ QIODevice* device;
+ QByteArray* currentReadBuffer;
+ qint64 currentReadBufferSize;
+ qint64 currentReadBufferAmount;
+ qint64 currentReadBufferPosition;
+ qint64 totalAdvancements;
+ bool eof;
+ qint64 initialPosition;
+};
+
+class QNonContiguousByteDeviceBufferImpl : public QNonContiguousByteDevice
+{
+ Q_OBJECT
+public:
+ QNonContiguousByteDeviceBufferImpl(QBuffer *b);
+ ~QNonContiguousByteDeviceBufferImpl();
+ const char* readPointer(qint64 maximumLength, qint64 &len);
+ bool advanceReadPointer(qint64 amount);
+ bool atEnd();
+ bool reset();
+ qint64 size();
+protected:
+ QBuffer* buffer;
+ QByteArray byteArray;
+ QNonContiguousByteDeviceByteArrayImpl* arrayImpl;
+};
+
+// ... and the reverse thing
+class QByteDeviceWrappingIoDevice : public QIODevice
+{
+ Q_OBJECT
+public:
+ QByteDeviceWrappingIoDevice (QNonContiguousByteDevice *bd);
+ ~QByteDeviceWrappingIoDevice ();
+ virtual bool isSequential () const;
+ virtual bool atEnd () const;
+ virtual bool reset ();
+ virtual qint64 size () const;
+protected:
+ virtual qint64 readData ( char * data, qint64 maxSize );
+ virtual qint64 writeData ( const char * data, qint64 maxSize );
+
+ QNonContiguousByteDevice *byteDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif