diff options
Diffstat (limited to 'src/corelib/io/qiodevice.cpp')
-rw-r--r-- | src/corelib/io/qiodevice.cpp | 202 |
1 files changed, 191 insertions, 11 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 116befbcbf..e60aaf7cb2 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -148,8 +148,12 @@ static void checkWarnMessage(const QIODevice *device, const char *function, cons \internal */ QIODevicePrivate::QIODevicePrivate() - : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE), + : openMode(QIODevice::NotOpen), pos(0), devicePos(0), + readChannelCount(0), + writeChannelCount(0), + currentReadChannel(0), + currentWriteChannel(0), transactionPos(0), transactionStarted(false) , baseReadLineDataCalled(false) @@ -278,6 +282,15 @@ QIODevicePrivate::~QIODevicePrivate() mechanism implemented by QIODevice. See startTransaction() and related functions for more details. + Some sequential devices support communicating via multiple channels. These + channels represent separate streams of data that have the property of + independently sequenced delivery. Once the device is opened, you can + determine the number of channels by calling the readChannelCount() and + writeChannelCount() functions. To switch between channels, call + setCurrentReadChannel() and setCurrentWriteChannel(), respectively. + QIODevice also provides additional signals to handle asynchronous + communication on a per-channel basis. + \sa QBuffer, QFile, QTcpSocket */ @@ -315,8 +328,8 @@ QIODevicePrivate::~QIODevicePrivate() /*! \fn QIODevice::bytesWritten(qint64 bytes) This signal is emitted every time a payload of data has been - written to the device. The \a bytes argument is set to the number - of bytes that were written in this payload. + written to the device's current write channel. The \a bytes argument is + set to the number of bytes that were written in this payload. bytesWritten() is not emitted recursively; if you reenter the event loop or call waitForBytesWritten() inside a slot connected to the @@ -327,12 +340,28 @@ QIODevicePrivate::~QIODevicePrivate() */ /*! + \fn QIODevice::channelBytesWritten(int channel, qint64 bytes) + \since 5.7 + + This signal is emitted every time a payload of data has been written to + the device. The \a bytes argument is set to the number of bytes that were + written in this payload, while \a channel is the channel they were written + to. Unlike bytesWritten(), it is emitted regardless of the + \l{currentWriteChannel()}{current write channel}. + + channelBytesWritten() can be emitted recursively - even for the same + channel. + + \sa bytesWritten(), channelReadyRead() +*/ + +/*! \fn QIODevice::readyRead() This signal is emitted once every time new data is available for - reading from the device. It will only be emitted again once new - data is available, such as when a new payload of network data has - arrived on your network socket, or when a new block of data has + reading from the device's current read channel. It will only be emitted + again once new data is available, such as when a new payload of network + data has arrived on your network socket, or when a new block of data has been appended to your device. readyRead() is not emitted recursively; if you reenter the event loop or @@ -348,6 +377,20 @@ QIODevicePrivate::~QIODevicePrivate() \sa bytesWritten() */ +/*! + \fn QIODevice::channelReadyRead(int channel) + \since 5.7 + + This signal is emitted when new data is available for reading from the + device. The \a channel argument is set to the index of the read channel on + which the data has arrived. Unlike readyRead(), it is emitted regardless of + the \l{currentReadChannel()}{current read channel}. + + channelReadyRead() can be emitted recursively - even for the same channel. + + \sa readyRead(), channelBytesWritten() +*/ + /*! \fn QIODevice::aboutToClose() This signal is emitted when the device is about to close. Connect @@ -483,8 +526,8 @@ void QIODevice::setOpenMode(OpenMode openMode) #endif d->openMode = openMode; d->accessMode = QIODevicePrivate::Unset; - if (!isReadable()) - d->buffer.clear(); + d->setReadChannelCount(isReadable() ? qMax(d->readChannelCount, 1) : 0); + d->setWriteChannelCount(isWritable() ? qMax(d->writeChannelCount, 1) : 0); } /*! @@ -561,6 +604,135 @@ bool QIODevice::isWritable() const } /*! + \since 5.7 + + Returns the number of available read channels if the device is open; + otherwise returns 0. + + \sa writeChannelCount(), QProcess +*/ +int QIODevice::readChannelCount() const +{ + return d_func()->readChannelCount; +} + +/*! + \since 5.7 + + Returns the number of available write channels if the device is open; + otherwise returns 0. + + \sa readChannelCount() +*/ +int QIODevice::writeChannelCount() const +{ + return d_func()->writeChannelCount; +} + +/*! + \since 5.7 + + Returns the index of the current read channel. + + \sa setCurrentReadChannel(), readChannelCount(), QProcess +*/ +int QIODevice::currentReadChannel() const +{ + return d_func()->currentReadChannel; +} + +/*! + \since 5.7 + + Sets the current read channel of the QIODevice to the given \a + channel. The current input channel is used by the functions + read(), readAll(), readLine(), and getChar(). It also determines + which channel triggers QIODevice to emit readyRead(). + + \sa currentReadChannel(), readChannelCount(), QProcess +*/ +void QIODevice::setCurrentReadChannel(int channel) +{ + Q_D(QIODevice); + + if (d->transactionStarted) { + checkWarnMessage(this, "setReadChannel", "Failed due to read transaction being in progress"); + return; + } + +#if defined QIODEVICE_DEBUG + qDebug("%p QIODevice::setCurrentReadChannel(%d), d->currentReadChannel = %d, d->readChannelCount = %d\n", + this, channel, d->currentReadChannel, d->readChannelCount); +#endif + + d->setCurrentReadChannel(channel); +} + +/*! + \internal +*/ +void QIODevicePrivate::setReadChannelCount(int count) +{ + if (count > readBuffers.size()) { + readBuffers.insert(readBuffers.end(), count - readBuffers.size(), + QRingBuffer(QIODEVICE_BUFFERSIZE)); + } else { + readBuffers.resize(count); + } + readChannelCount = count; + setCurrentReadChannel(currentReadChannel); +} + +/*! + \since 5.7 + + Returns the the index of the current write channel. + + \sa setCurrentWriteChannel(), writeChannelCount() +*/ +int QIODevice::currentWriteChannel() const +{ + return d_func()->currentWriteChannel; +} + +/*! + \since 5.7 + + Sets the current write channel of the QIODevice to the given \a + channel. The current output channel is used by the functions + write(), putChar(). It also determines which channel triggers + QIODevice to emit bytesWritten(). + + \sa currentWriteChannel(), writeChannelCount() +*/ +void QIODevice::setCurrentWriteChannel(int channel) +{ + Q_D(QIODevice); + +#if defined QIODEVICE_DEBUG + qDebug("%p QIODevice::setCurrentWriteChannel(%d), d->currentWriteChannel = %d, d->writeChannelCount = %d\n", + this, channel, d->currentWriteChannel, d->writeChannelCount); +#endif + + d->setCurrentWriteChannel(channel); +} + +/*! + \internal +*/ +void QIODevicePrivate::setWriteChannelCount(int count) +{ + if (count > writeBuffers.size()) { + writeBuffers.insert(writeBuffers.end(), count - writeBuffers.size(), + QRingBuffer(QIODEVICE_BUFFERSIZE)); + } else { + writeBuffers.resize(count); + } + writeChannelCount = count; + setCurrentWriteChannel(currentWriteChannel); +} + +/*! Opens the device and sets its OpenMode to \a mode. Returns \c true if successful; otherwise returns \c false. This function should be called from any reimplementations of open() or other functions that open the device. @@ -572,8 +744,11 @@ bool QIODevice::open(OpenMode mode) Q_D(QIODevice); d->openMode = mode; d->pos = (mode & Append) ? size() : qint64(0); - d->buffer.clear(); d->accessMode = QIODevicePrivate::Unset; + d->readBuffers.clear(); + d->writeBuffers.clear(); + d->setReadChannelCount(isReadable() ? 1 : 0); + d->setWriteChannelCount(isWritable() ? 1 : 0); #if defined QIODEVICE_DEBUG printf("%p QIODevice::open(0x%x)\n", this, quint32(mode)); #endif @@ -604,7 +779,9 @@ void QIODevice::close() d->pos = 0; d->transactionStarted = false; d->transactionPos = 0; - d->buffer.clear(); + d->setReadChannelCount(0); + // Do not clear write buffers to allow delayed close in sockets + d->writeChannelCount = 0; } /*! @@ -771,11 +948,14 @@ qint64 QIODevice::bytesAvailable() const waiting to be written. For devices with no buffer, this function returns 0. + Subclasses that reimplement this function must call the base + implementation in order to include the size of the buffer of QIODevice. + \sa bytesAvailable(), bytesWritten(), isSequential() */ qint64 QIODevice::bytesToWrite() const { - return qint64(0); + return d_func()->writeBuffer.size(); } /*! |