summaryrefslogtreecommitdiff
path: root/qtools/qiodevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtools/qiodevice.cpp')
-rw-r--r--qtools/qiodevice.cpp638
1 files changed, 638 insertions, 0 deletions
diff --git a/qtools/qiodevice.cpp b/qtools/qiodevice.cpp
new file mode 100644
index 0000000..43b2787
--- /dev/null
+++ b/qtools/qiodevice.cpp
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+**
+** Implementation of QIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qiodevice.h"
+
+// NOT REVISED
+/*!
+ \class QIODevice qiodevice.h
+
+ \brief The QIODevice class is the base class of I/O devices.
+
+ \ingroup io
+
+ An I/O device represents a medium that one can read bytes from
+ and/or write bytes to. The QIODevice class is the abstract
+ superclass of all such devices; classes like QFile, QBuffer and
+ QSocket inherit QIODevice and implement virtual functions like
+ write() appropriately.
+
+ While applications sometimes use QIODevice directly, mostly it is
+ better to go through QTextStream and QDataStream, which provide
+ stream operations on any QIODevice subclass. QTextStream provides
+ text-oriented stream functionality (for human-readable ASCII files,
+ for example), while QDataStream deals with binary data in a totally
+ platform-independent manner.
+
+ The public member functions in QIODevice roughly fall into two
+ groups: The action functions and the state access functions. The
+ most important action functions are: <ul>
+
+ <li> open() opens a device for reading and/or writing, depending on
+ the argument to open().
+
+ <li> close() closes the device and tidies up.
+
+ <li> readBlock() reads a block of data from the device.
+
+ <li> writeBlock() writes a block of data to the device.
+
+ <li> readLine() reads a line (of text, usually) from the device.
+
+ <li> flush() ensures that all buffered data are written to the real device.
+
+ </ul>There are also some other, less used, action functions: <ul>
+
+ <li> getch() reads a single character.
+
+ <li> ungetch() forgets the last call to getch(), if possible.
+
+ <li> putch() writes a single character.
+
+ <li> size() returns the size of the device, if there is one.
+
+ <li> at() returns the current read/write pointer, if there is one
+ for this device, or it moves the pointer.
+
+ <li> atEnd() says whether there is more to read, if that is a
+ meaningful question for this device.
+
+ <li> reset() moves the read/write pointer to the start of the
+ device, if that is possible for this device.
+
+ </ul>The state access are all "get" functions. The QIODevice subclass
+ calls setState() to update the state, and simple access functions
+ tell the user of the device what the device's state is. Here are
+ the settings, and their associated access functions: <ul>
+
+ <li> Access type. Some devices are direct access (it is possible to
+ read/write anywhere) while others are sequential. QIODevice
+ provides the access functions isDirectAccess(), isSequentialAccess()
+ and isCombinedAccess() to tell users what a given I/O device
+ supports.
+
+ <li> Buffering. Some devices are accessed in raw mode while others
+ are buffered. Buffering usually provides greater efficiency,
+ particularly for small read/write operations. isBuffered() tells
+ the user whether a given device is buffered. (This can often be set
+ by the application in the call to open().)
+
+ <li> Synchronicity. Synchronous devices work there and then, for
+ example files. When you read from a file, the file delivers its
+ data right away. Others, such as a socket connected to a HTTP
+ server, may not deliver the data until seconds after you ask to read
+ it. isSynchronous() and isAsynchronous() tells the user how this
+ device operates.
+
+ <li> CR/LF translation. For simplicity, applications often like to
+ see just a single CR/LF style, and QIODevice subclasses can provide
+ that. isTranslated() returns TRUE if this object translates CR/LF
+ to just LF. (This can often be set by the application in the call
+ to open().)
+
+ <li> Accessibility. Some files cannot be written, for example.
+ isReadable(), isWritable and isReadWrite() tells the application
+ whether it can read from and write to a given device. (This can
+ often be set by the application in the call to open().)
+
+ <li> Finally, isOpen() returns TRUE if the device is open. This can
+ quite obviously be set using open() :)
+
+ </ul>
+
+ QIODevice provides numerous pure virtual functions you need to
+ implement when subclassing it. Here is a skeleton subclass with all
+ the members you are certain to need, and some it's likely that you
+ will need:
+
+ \code
+ class YourDevice : public QIODevice
+ {
+ public:
+ YourDevice();
+ ~YourDevice();
+
+ bool open( int mode );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const; // not a pure virtual function
+ bool at( int ); // not a pure virtual function
+ bool atEnd() const; // not a pure virtual function
+
+ int readBlock( char *data, uint maxlen );
+ int writeBlock( const char *data, uint len );
+ int readLine( char *data, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+ };
+ \endcode
+
+ The three non-pure virtual functions can be ignored if your device
+ is sequential (e.g. an RS-232 port).
+
+ \sa QDataStream, QTextStream
+*/
+
+
+/*!
+ Constructs an I/O device.
+*/
+
+QIODevice::QIODevice()
+{
+ ioMode = 0; // initial mode
+ ioSt = IO_Ok;
+ ioIndex = 0;
+}
+
+/*!
+ Destructs the I/O device.
+*/
+
+QIODevice::~QIODevice()
+{
+}
+
+
+/*!
+ \fn int QIODevice::flags() const
+ Returns the current I/O device flags setting.
+
+ Flags consists of mode flags and state flags.
+
+ \sa mode(), state()
+*/
+
+/*!
+ \fn int QIODevice::mode() const
+ Returns bits OR'ed together that specify the current operation mode.
+
+ These are the flags that were given to the open() function.
+
+ The flags are: \c IO_ReadOnly, \c IO_WriteOnly, \c IO_ReadWrite,
+ \c IO_Append, \c IO_Truncate and \c IO_Translate.
+*/
+
+/*!
+ \fn int QIODevice::state() const
+ Returns bits OR'ed together that specify the current state.
+
+ The flags are: \c IO_Open.
+
+ Subclasses may define more flags.
+*/
+
+/*!
+ \fn bool QIODevice::isDirectAccess() const
+ Returns TRUE if the I/O device is a direct access (not sequential) device,
+ otherwise FALSE.
+ \sa isSequentialAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isSequentialAccess() const
+ Returns TRUE if the I/O device is a sequential access (not direct) device,
+ otherwise FALSE. Operations involving size() and at(int) are not valid
+ on sequential devices.
+ \sa isDirectAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isCombinedAccess() const
+ Returns TRUE if the I/O device is a combined access (both direct and
+ sequential) device, otherwise FALSE.
+
+ This access method is currently not in use.
+*/
+
+/*!
+ \fn bool QIODevice::isBuffered() const
+ Returns TRUE if the I/O device is a buffered (not raw) device, otherwise
+ FALSE.
+ \sa isRaw()
+*/
+
+/*!
+ \fn bool QIODevice::isRaw() const
+ Returns TRUE if the I/O device is a raw (not buffered) device, otherwise
+ FALSE.
+ \sa isBuffered()
+*/
+
+/*!
+ \fn bool QIODevice::isSynchronous() const
+ Returns TRUE if the I/O device is a synchronous device, otherwise
+ FALSE.
+ \sa isAsynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isAsynchronous() const
+ Returns TRUE if the I/O device is a asynchronous device, otherwise
+ FALSE.
+
+ This mode is currently not in use.
+
+ \sa isSynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isTranslated() const
+ Returns TRUE if the I/O device translates carriage-return and linefeed
+ characters.
+
+ A QFile is translated if it is opened with the \c IO_Translate mode
+ flag.
+*/
+
+/*!
+ \fn bool QIODevice::isReadable() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadOnly or
+ \c IO_ReadWrite mode.
+ \sa isWritable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isWritable() const
+ Returns TRUE if the I/O device was opened using \c IO_WriteOnly or
+ \c IO_ReadWrite mode.
+ \sa isReadable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isReadWrite() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadWrite mode.
+ \sa isReadable(), isWritable()
+*/
+
+/*!
+ \fn bool QIODevice::isInactive() const
+ Returns TRUE if the I/O device state is 0, i.e. the device is not open.
+ \sa isOpen()
+*/
+
+/*!
+ \fn bool QIODevice::isOpen() const
+ Returns TRUE if the I/O device state has been opened, otherwise FALSE.
+ \sa isInactive()
+*/
+
+
+/*!
+ \fn int QIODevice::status() const
+ Returns the I/O device status.
+
+ The I/O device status returns an error code. If open() returns FALSE
+ or readBlock() or writeBlock() return -1, this function can be called to
+ get the reason why the operation did not succeed.
+
+ The status codes are:
+ <ul>
+ <li>\c IO_Ok The operation was successful.
+ <li>\c IO_ReadError Could not read from the device.
+ <li>\c IO_WriteError Could not write to the device.
+ <li>\c IO_FatalError A fatal unrecoverable error occurred.
+ <li>\c IO_OpenError Could not open the device.
+ <li>\c IO_ConnectError Could not connect to the device.
+ <li>\c IO_AbortError The operation was unexpectedly aborted.
+ <li>\c IO_TimeOutError The operation timed out.
+ <li>\c IO_OnCloseError An unspecified error happened on close.
+ </ul>
+
+ \sa resetStatus()
+*/
+
+/*!
+ \fn void QIODevice::resetStatus()
+
+ Sets the I/O device status to \c IO_Ok.
+
+ \sa status()
+*/
+
+
+/*!
+ \fn void QIODevice::setFlags( int f )
+ \internal
+ Used by subclasses to set the device flags.
+*/
+
+/*!
+ \internal
+ Used by subclasses to set the device type.
+*/
+
+void QIODevice::setType( int t )
+{
+#if defined(CHECK_RANGE)
+ if ( (t & IO_TypeMask) != t )
+ qWarning( "QIODevice::setType: Specified type out of range" );
+#endif
+ ioMode &= ~IO_TypeMask; // reset type bits
+ ioMode |= t;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device mode.
+*/
+
+void QIODevice::setMode( int m )
+{
+#if defined(CHECK_RANGE)
+ if ( (m & IO_ModeMask) != m )
+ qWarning( "QIODevice::setMode: Specified mode out of range" );
+#endif
+ ioMode &= ~IO_ModeMask; // reset mode bits
+ ioMode |= m;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device state.
+*/
+
+void QIODevice::setState( int s )
+{
+#if defined(CHECK_RANGE)
+ if ( ((uint)s & IO_StateMask) != (uint)s )
+ qWarning( "QIODevice::setState: Specified state out of range" );
+#endif
+ ioMode &= ~IO_StateMask; // reset state bits
+ ioMode |= (uint)s;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device status (not state).
+*/
+
+void QIODevice::setStatus( int s )
+{
+ ioSt = s;
+}
+
+
+/*!
+ \fn bool QIODevice::open( int mode )
+ Opens the I/O device using the specified \e mode.
+ Returns TRUE if successful, or FALSE if the device could not be opened.
+
+ The mode parameter \e m must be a combination of the following flags.
+ <ul>
+ <li>\c IO_Raw specified raw (unbuffered) file access.
+ <li>\c IO_ReadOnly opens a file in read-only mode.
+ <li>\c IO_WriteOnly opens a file in write-only mode.
+ <li>\c IO_ReadWrite opens a file in read/write mode.
+ <li>\c IO_Append sets the file index to the end of the file.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Window, OS/2 and Macintosh. On Unix systems
+ this flag has no effect. Use with caution as it will also transform every linefeed
+ written to the file into a CRLF pair. This is likely to corrupt your file when
+ writing binary data to it. Cannot be combined with \c IO_Raw.
+ </ul>
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa close()
+*/
+
+/*!
+ \fn void QIODevice::close()
+ Closes the I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa open()
+*/
+
+/*!
+ \fn void QIODevice::flush()
+
+ Flushes an open I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+*/
+
+
+/*!
+ \fn uint QIODevice::size() const
+ Virtual function that returns the size of the I/O device.
+ \sa at()
+*/
+
+/*!
+ Virtual function that returns the current I/O device index.
+
+ This index is the data read/write head of the I/O device.
+
+ \sa size()
+*/
+
+int QIODevice::at() const
+{
+ return ioIndex;
+}
+
+/*!
+ Virtual function that sets the I/O device index to \e pos.
+ \sa size()
+*/
+
+bool QIODevice::at( int pos )
+{
+#if defined(CHECK_RANGE)
+ if ( (uint)pos > size() ) {
+ qWarning( "QIODevice::at: Index %d out of range", pos );
+ return FALSE;
+ }
+#endif
+ ioIndex = pos;
+ return TRUE;
+}
+
+/*!
+ Virtual function that returns TRUE if the I/O device index is at the
+ end of the input.
+*/
+
+bool QIODevice::atEnd() const
+{
+ if ( isSequentialAccess() || isTranslated() ) {
+ QIODevice* that = (QIODevice*)this;
+ int c = that->getch();
+ bool result = c < 0;
+ that->ungetch(c);
+ return result;
+ } else {
+ return at() == (int)size();
+ }
+}
+
+/*!
+ \fn bool QIODevice::reset()
+ Sets the device index to 0.
+ \sa at()
+*/
+
+
+/*!
+ \fn int QIODevice::readBlock( char *data, uint maxlen )
+ Reads at most \e maxlen bytes from the I/O device into \e data and
+ returns the number of bytes actually read.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa writeBlock()
+*/
+
+/*!
+ This convenience function returns all of the remaining data in the
+ device. Note that this only works for direct access devices, such
+ as QFile.
+
+ \sa isDirectAccess()
+*/
+QByteArray QIODevice::readAll()
+{
+ int n = size()-at();
+ QByteArray ba(size()-at());
+ char* c = ba.data();
+ while ( n ) {
+ int r = readBlock( c, n );
+ if ( r < 0 )
+ return QByteArray();
+ n -= r;
+ c += r;
+ }
+ return ba;
+}
+
+/*!
+ \fn int QIODevice::writeBlock( const char *data, uint len )
+ Writes \e len bytes from \e p to the I/O device and returns the number of
+ bytes actually written.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa readBlock()
+*/
+
+/*!
+ This convenience function is the same as calling
+ writeBlock( data.data(), data.size() ).
+*/
+int QIODevice::writeBlock( const QByteArray& data )
+{
+ return writeBlock( data.data(), data.size() );
+}
+
+/*!
+ Reads a line of text, up to \e maxlen bytes including a terminating
+ \0. If there is a newline at the end if the line, it is not stripped.
+
+ Returns the number of bytes read, or -1 in case of error.
+
+ This virtual function can be reimplemented much more efficiently by
+ the most subclasses.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QIODevice::readLine( char *data, uint maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+ int pos = at(); // get current position
+ int s = (int)size(); // size of I/O device
+ char *p = data;
+ if ( pos >= s )
+ return 0;
+ while ( pos++ < s && --maxlen ) { // read one byte at a time
+ readBlock( p, 1 );
+ if ( *p++ == '\n' ) // end of line
+ break;
+ }
+ *p++ = '\0';
+ return (int)((long)p - (long)data);
+}
+
+
+/*!
+ \fn int QIODevice::getch()
+
+ Reads a single byte/character from the I/O device.
+
+ Returns the byte/character read, or -1 if the end of the I/O device has been
+ reached.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa putch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::putch( int ch )
+
+ Writes the character \e ch to the I/O device.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::ungetch( int ch )
+
+ Puts the character \e ch back into the I/O device and decrements the
+ index if it is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), putch()
+*/