src/corelib/io/qiodevice.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 4 3b1da2848fc7
child 13 c0432d11811c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
    82 {
    82 {
    83     debugBinaryString(QByteArray(data, maxlen));
    83     debugBinaryString(QByteArray(data, maxlen));
    84 }
    84 }
    85 #endif
    85 #endif
    86 
    86 
    87 #ifndef QIODEVICE_BUFFERSIZE
       
    88 #define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
       
    89 #endif
       
    90 
       
    91 #define Q_VOID
    87 #define Q_VOID
    92 
    88 
    93 #define CHECK_MAXLEN(function, returnType) \
    89 #define CHECK_MAXLEN(function, returnType) \
    94     do { \
    90     do { \
    95         if (maxSize < 0) { \
    91         if (maxSize < 0) { \
   121 /*! \internal
   117 /*! \internal
   122  */
   118  */
   123 QIODevicePrivate::QIODevicePrivate()
   119 QIODevicePrivate::QIODevicePrivate()
   124     : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
   120     : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
   125       pos(0), devicePos(0)
   121       pos(0), devicePos(0)
       
   122        , pPos(&pos), pDevicePos(&devicePos)
   126        , baseReadLineDataCalled(false)
   123        , baseReadLineDataCalled(false)
       
   124        , firstRead(true)
   127        , accessMode(Unset)
   125        , accessMode(Unset)
   128 #ifdef QT_NO_QOBJECT
   126 #ifdef QT_NO_QOBJECT
   129        , q_ptr(0)
   127        , q_ptr(0)
   130 #endif
   128 #endif
   131 {
   129 {
   280     \value Unbuffered Any buffer in the device is bypassed.
   278     \value Unbuffered Any buffer in the device is bypassed.
   281 
   279 
   282     Certain flags, such as \c Unbuffered and \c Truncate, are
   280     Certain flags, such as \c Unbuffered and \c Truncate, are
   283     meaningless when used with some subclasses. Some of these
   281     meaningless when used with some subclasses. Some of these
   284     restrictions are implied by the type of device that is represented
   282     restrictions are implied by the type of device that is represented
   285     by a subclass; for example, access to a QBuffer is always
   283     by a subclass. In other cases, the restriction may be due to the
   286     unbuffered. In other cases, the restriction may be due to the
       
   287     implementation, or may be imposed by the underlying platform; for
   284     implementation, or may be imposed by the underlying platform; for
   288     example, QTcpSocket does not support \c Unbuffered mode, and
   285     example, QTcpSocket does not support \c Unbuffered mode, and
   289     limitations in the native API prevent QFile from supporting \c
   286     limitations in the native API prevent QFile from supporting \c
   290     Unbuffered on Windows.
   287     Unbuffered on Windows.
   291 */
   288 */
   448 
   445 
   449     \sa openMode() OpenMode
   446     \sa openMode() OpenMode
   450 */
   447 */
   451 void QIODevice::setOpenMode(OpenMode openMode)
   448 void QIODevice::setOpenMode(OpenMode openMode)
   452 {
   449 {
       
   450     Q_D(QIODevice);
   453 #if defined QIODEVICE_DEBUG
   451 #if defined QIODEVICE_DEBUG
   454     printf("%p QIODevice::setOpenMode(0x%x)\n", this, int(openMode));
   452     printf("%p QIODevice::setOpenMode(0x%x)\n", this, int(openMode));
   455 #endif
   453 #endif
   456     d_func()->openMode = openMode;
   454     d->openMode = openMode;
   457     d_func()->accessMode = QIODevicePrivate::Unset;
   455     d->accessMode = QIODevicePrivate::Unset;
       
   456     d->firstRead = true;
       
   457     if (!isReadable())
       
   458         d->buffer.clear();
   458 }
   459 }
   459 
   460 
   460 /*!
   461 /*!
   461     If \a enabled is true, this function sets the \l Text flag on the device;
   462     If \a enabled is true, this function sets the \l Text flag on the device;
   462     otherwise the \l Text flag is removed. This feature is useful for classes
   463     otherwise the \l Text flag is removed. This feature is useful for classes
   536     Q_D(QIODevice);
   537     Q_D(QIODevice);
   537     d->openMode = mode;
   538     d->openMode = mode;
   538     d->pos = (mode & Append) ? size() : qint64(0);
   539     d->pos = (mode & Append) ? size() : qint64(0);
   539     d->buffer.clear();
   540     d->buffer.clear();
   540     d->accessMode = QIODevicePrivate::Unset;
   541     d->accessMode = QIODevicePrivate::Unset;
       
   542     d->firstRead = true;
   541 #if defined QIODEVICE_DEBUG
   543 #if defined QIODEVICE_DEBUG
   542     printf("%p QIODevice::open(0x%x)\n", this, quint32(mode));
   544     printf("%p QIODevice::open(0x%x)\n", this, quint32(mode));
   543 #endif
   545 #endif
   544     return true;
   546     return true;
   545 }
   547 }
   565 #endif
   567 #endif
   566     d->openMode = NotOpen;
   568     d->openMode = NotOpen;
   567     d->errorString.clear();
   569     d->errorString.clear();
   568     d->pos = 0;
   570     d->pos = 0;
   569     d->buffer.clear();
   571     d->buffer.clear();
       
   572     d->firstRead = true;
   570 }
   573 }
   571 
   574 
   572 /*!
   575 /*!
   573     For random-access devices, this function returns the position that
   576     For random-access devices, this function returns the position that
   574     data is written to or read from. For sequential devices or closed
   577     data is written to or read from. For sequential devices or closed
   728 qint64 QIODevice::bytesToWrite() const
   731 qint64 QIODevice::bytesToWrite() const
   729 {
   732 {
   730     return qint64(0);
   733     return qint64(0);
   731 }
   734 }
   732 
   735 
       
   736 #ifdef Q_CC_RVCT
       
   737 // arm mode makes the 64-bit integer operations much faster in RVCT 2.2
       
   738 #pragma push
       
   739 #pragma arm
       
   740 #endif
       
   741 
   733 /*!
   742 /*!
   734     Reads at most \a maxSize bytes from the device into \a data, and
   743     Reads at most \a maxSize bytes from the device into \a data, and
   735     returns the number of bytes read. If an error occurs, such as when
   744     returns the number of bytes read. If an error occurs, such as when
   736     attempting to read from a device opened in WriteOnly mode, this
   745     attempting to read from a device opened in WriteOnly mode, this
   737     function returns -1.
   746     function returns -1.
   744     \sa readData() readLine() write()
   753     \sa readData() readLine() write()
   745 */
   754 */
   746 qint64 QIODevice::read(char *data, qint64 maxSize)
   755 qint64 QIODevice::read(char *data, qint64 maxSize)
   747 {
   756 {
   748     Q_D(QIODevice);
   757     Q_D(QIODevice);
   749     CHECK_READABLE(read, qint64(-1));
       
   750     CHECK_MAXLEN(read, qint64(-1));
       
   751 
   758 
   752 #if defined QIODEVICE_DEBUG
   759 #if defined QIODEVICE_DEBUG
   753     printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n",
   760     printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n",
   754            this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
   761            this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
   755 #endif
   762 #endif
   756     const bool sequential = d->isSequential();
       
   757 
   763 
   758     // Short circuit for getChar()
   764     // Short circuit for getChar()
   759     if (maxSize == 1) {
   765     if (maxSize == 1) {
   760         int chint;
   766         int chint;
   761         while ((chint = d->buffer.getChar()) != -1) {
   767         while ((chint = d->buffer.getChar()) != -1) {
   762             if (!sequential)
   768             ++(*d->pPos);
   763                 ++d->pos;
       
   764 
   769 
   765             char c = char(uchar(chint));
   770             char c = char(uchar(chint));
   766             if (c == '\r' && (d->openMode & Text))
   771             if (c == '\r' && (d->openMode & Text))
   767                 continue;
   772                 continue;
   768             *data = c;
   773             *data = c;
   772 #endif
   777 #endif
   773             return qint64(1);
   778             return qint64(1);
   774         }
   779         }
   775     }
   780     }
   776 
   781 
       
   782     CHECK_MAXLEN(read, qint64(-1));
   777     qint64 readSoFar = 0;
   783     qint64 readSoFar = 0;
   778     bool moreToRead = true;
   784     bool moreToRead = true;
   779     do {
   785     do {
   780         int lastReadChunkSize = 0;
       
   781 
       
   782         // Try reading from the buffer.
   786         // Try reading from the buffer.
   783         if (!d->buffer.isEmpty()) {
   787         int lastReadChunkSize = d->buffer.read(data, maxSize);
   784             lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
   788         *d->pPos += lastReadChunkSize;
   785             readSoFar += lastReadChunkSize;
   789         readSoFar += lastReadChunkSize;
   786             if (!sequential)
   790         // fast exit when satisfied by buffer
   787                 d->pos += lastReadChunkSize;
   791         if (lastReadChunkSize == maxSize && !(d->openMode & Text))
       
   792             return readSoFar;
       
   793 
       
   794         if (lastReadChunkSize > 0) {
       
   795             data += lastReadChunkSize;
       
   796             maxSize -= lastReadChunkSize;
   788 #if defined QIODEVICE_DEBUG
   797 #if defined QIODEVICE_DEBUG
   789             printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
   798             printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
   790                    int(readSoFar) - lastReadChunkSize);
   799                    int(readSoFar) - lastReadChunkSize);
   791 #endif
   800 #endif
   792         } else if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
   801         } else {
   793             // In buffered mode, we try to fill up the QIODevice buffer before
   802             if (d->firstRead) {
   794             // we do anything else.
   803                 // this is the first time the file has been read, check it's valid and set up pos pointers
   795             int bytesToBuffer = qMax(maxSize - readSoFar, QIODEVICE_BUFFERSIZE);
   804                 // for fast pos updates.
   796             char *writePointer = d->buffer.reserve(bytesToBuffer);
   805                 CHECK_READABLE(read, qint64(-1));
   797 
   806                 d->firstRead = false;
   798             // Make sure the device is positioned correctly.
   807                 if (d->isSequential()) {
   799             if (d->pos != d->devicePos && !sequential && !seek(d->pos))
   808                     d->pPos = &d->seqDumpPos;
   800                 return qint64(-1);
   809                     d->pDevicePos = &d->seqDumpPos;
   801             qint64 readFromDevice = readData(writePointer, bytesToBuffer);
   810                 }
   802             d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
   811             }
   803 
   812 
   804             if (readFromDevice > 0) {
   813             if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
   805                 if (!sequential)
   814                 // In buffered mode, we try to fill up the QIODevice buffer before
   806                     d->devicePos += readFromDevice;
   815                 // we do anything else.
   807 #if defined QIODEVICE_DEBUG
   816                 // buffer is empty at this point, try to fill it
   808                 printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
   817                 int bytesToBuffer = QIODEVICE_BUFFERSIZE;
   809 #endif
   818                 char *writePointer = d->buffer.reserve(bytesToBuffer);
   810 
   819 
   811                 if (readFromDevice < bytesToBuffer)
   820                 // Make sure the device is positioned correctly.
   812                     d->buffer.truncate(int(readFromDevice));
   821                 if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
   813                 if (!d->buffer.isEmpty()) {
   822                     return readSoFar ? readSoFar : qint64(-1);
   814                     lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
   823                 qint64 readFromDevice = readData(writePointer, bytesToBuffer);
   815                     readSoFar += lastReadChunkSize;
   824                 d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
   816                     if (!sequential)
   825 
   817                         d->pos += lastReadChunkSize;
   826                 if (readFromDevice > 0) {
   818 #if defined QIODEVICE_DEBUG
   827                     *d->pDevicePos += readFromDevice;
   819                     printf("%p \treading %d bytes from buffer at position %d\n", this,
   828 #if defined QIODEVICE_DEBUG
   820                            lastReadChunkSize, int(readSoFar));
   829                     printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
   821 #endif
   830 #endif
       
   831 
       
   832                     if (!d->buffer.isEmpty()) {
       
   833                         lastReadChunkSize = d->buffer.read(data, maxSize);
       
   834                         readSoFar += lastReadChunkSize;
       
   835                         data += lastReadChunkSize;
       
   836                         maxSize -= lastReadChunkSize;
       
   837                         *d->pPos += lastReadChunkSize;
       
   838 #if defined QIODEVICE_DEBUG
       
   839                         printf("%p \treading %d bytes from buffer at position %d\n", this,
       
   840                                lastReadChunkSize, int(readSoFar));
       
   841 #endif
       
   842                     }
   822                 }
   843                 }
   823             }
   844             }
   824         }
   845         }
   825 
   846 
   826         // If we need more, try reading from the device.
   847         // If we need more, try reading from the device.
   827         if (readSoFar < maxSize) {
   848         if (maxSize > 0) {
   828             // Make sure the device is positioned correctly.
   849             // Make sure the device is positioned correctly.
   829             if (d->pos != d->devicePos && !sequential && !seek(d->pos))
   850             if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
   830                 return qint64(-1);
   851                 return readSoFar ? readSoFar : qint64(-1);
   831             qint64 readFromDevice = readData(data + readSoFar, maxSize - readSoFar);
   852             qint64 readFromDevice = readData(data, maxSize);
   832 #if defined QIODEVICE_DEBUG
   853 #if defined QIODEVICE_DEBUG
   833             printf("%p \treading %d bytes from device (total %d)\n", this, int(readFromDevice), int(readSoFar));
   854             printf("%p \treading %d bytes from device (total %d)\n", this, int(readFromDevice), int(readSoFar));
   834 #endif
   855 #endif
   835             if (readFromDevice == -1 && readSoFar == 0) {
   856             if (readFromDevice == -1 && readSoFar == 0) {
   836                 // error and we haven't read anything: return immediately
   857                 // error and we haven't read anything: return immediately
   837                 return -1;
   858                 return -1;
   838             }
   859             }
   839             if (readFromDevice <= 0) {
   860             if (readFromDevice > 0) {
   840                 moreToRead = false;
       
   841             } else {
       
   842                 // see if we read as much data as we asked for
       
   843                 if (readFromDevice < maxSize - readSoFar)
       
   844                     moreToRead = false;
       
   845 
       
   846                 lastReadChunkSize += int(readFromDevice);
   861                 lastReadChunkSize += int(readFromDevice);
   847                 readSoFar += readFromDevice;
   862                 readSoFar += readFromDevice;
   848                 if (!sequential) {
   863                 data += readFromDevice;
   849                     d->pos += readFromDevice;
   864                 maxSize -= readFromDevice;
   850                     d->devicePos += readFromDevice;
   865                 *d->pPos += readFromDevice;
   851                 }
   866                 *d->pDevicePos += readFromDevice;
   852             }
   867             }
   853         } else {
       
   854             moreToRead = false;
       
   855         }
   868         }
       
   869         // Best attempt has been made to read data, don't try again except for text mode adjustment below
       
   870         moreToRead = false;
   856 
   871 
   857         if (readSoFar && d->openMode & Text) {
   872         if (readSoFar && d->openMode & Text) {
   858             char *readPtr = data + readSoFar - lastReadChunkSize;
   873             char *readPtr = data - lastReadChunkSize;
   859             const char *endPtr = data + readSoFar;
   874             const char *endPtr = data;
   860 
   875 
   861             if (readPtr < endPtr) {
   876             if (readPtr < endPtr) {
   862                 // optimization to avoid initial self-assignment
   877                 // optimization to avoid initial self-assignment
   863                 while (*readPtr != '\r') {
   878                 while (*readPtr != '\r') {
   864                     if (++readPtr == endPtr)
   879                     if (++readPtr == endPtr)
   869 
   884 
   870                 while (readPtr < endPtr) {
   885                 while (readPtr < endPtr) {
   871                     char ch = *readPtr++;
   886                     char ch = *readPtr++;
   872                     if (ch != '\r')
   887                     if (ch != '\r')
   873                         *writePtr++ = ch;
   888                         *writePtr++ = ch;
   874                     else
   889                     else {
   875                         --readSoFar;
   890                         --readSoFar;
       
   891                         --data;
       
   892                         ++maxSize;
       
   893                     }
   876                 }
   894                 }
   877 
   895 
   878                 // Make sure we get more data if there is room for more. This
   896                 // Make sure we get more data if there is room for more. This
   879                 // is very important for when someone seeks to the start of a
   897                 // is very important for when someone seeks to the start of a
   880                 // '\r\n' and reads one character - they should get the '\n'.
   898                 // '\r\n' and reads one character - they should get the '\n'.
   884     } while (moreToRead);
   902     } while (moreToRead);
   885 
   903 
   886 #if defined QIODEVICE_DEBUG
   904 #if defined QIODEVICE_DEBUG
   887     printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this,
   905     printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this,
   888            int(readSoFar), int(d->pos), d->buffer.size());
   906            int(readSoFar), int(d->pos), d->buffer.size());
   889     debugBinaryString(data, readSoFar);
   907     debugBinaryString(data - readSoFar, readSoFar);
   890 #endif
   908 #endif
   891     return readSoFar;
   909     return readSoFar;
   892 }
   910 }
       
   911 
       
   912 #ifdef Q_CC_RVCT
       
   913 #pragma pop
       
   914 #endif
   893 
   915 
   894 /*!
   916 /*!
   895     \overload
   917     \overload
   896 
   918 
   897     Reads at most \a maxSize bytes from the device, and returns the
   919     Reads at most \a maxSize bytes from the device, and returns the
   996         result.resize(int(readBytes));
  1018         result.resize(int(readBytes));
   997 
  1019 
   998     return result;
  1020     return result;
   999 }
  1021 }
  1000 
  1022 
       
  1023 #ifdef Q_CC_RVCT
       
  1024 // arm mode makes the 64-bit integer operations much faster in RVCT 2.2
       
  1025 #pragma push
       
  1026 #pragma arm
       
  1027 #endif
       
  1028 
  1001 /*!
  1029 /*!
  1002     This function reads a line of ASCII characters from the device, up
  1030     This function reads a line of ASCII characters from the device, up
  1003     to a maximum of \a maxSize - 1 bytes, stores the characters in \a
  1031     to a maximum of \a maxSize - 1 bytes, stores the characters in \a
  1004     data, and returns the number of bytes read. If a line could not be
  1032     data, and returns the number of bytes read. If a line could not be
  1005     read but no error ocurred, this function returns 0. If an error
  1033     read but no error ocurred, this function returns 0. If an error
  1006     occurs, this function returns what it could the length of what
  1034     occurs, this function returns the length of what could be read, or
  1007     could be read, or -1 if nothing was read.
  1035     -1 if nothing was read.
  1008 
  1036 
  1009     A terminating '\0' byte is always appended to \a data, so \a
  1037     A terminating '\0' byte is always appended to \a data, so \a
  1010     maxSize must be larger than 1.
  1038     maxSize must be larger than 1.
  1011 
  1039 
  1012     Data is read until either of the following conditions are met:
  1040     Data is read until either of the following conditions are met:
  1227 #endif
  1255 #endif
  1228     if (lastReadReturn != 1 && readSoFar == 0)
  1256     if (lastReadReturn != 1 && readSoFar == 0)
  1229         return isSequential() ? lastReadReturn : -1;
  1257         return isSequential() ? lastReadReturn : -1;
  1230     return readSoFar;
  1258     return readSoFar;
  1231 }
  1259 }
       
  1260 
       
  1261 #ifdef Q_CC_RVCT
       
  1262 #pragma pop
       
  1263 #endif
  1232 
  1264 
  1233 /*!
  1265 /*!
  1234     Returns true if a complete line of data can be read from the device;
  1266     Returns true if a complete line of data can be read from the device;
  1235     otherwise returns false.
  1267     otherwise returns false.
  1236 
  1268 
  1415 
  1447 
  1416     \sa read() putChar() ungetChar()
  1448     \sa read() putChar() ungetChar()
  1417 */
  1449 */
  1418 bool QIODevice::getChar(char *c)
  1450 bool QIODevice::getChar(char *c)
  1419 {
  1451 {
  1420     Q_D(QIODevice);
  1452     // readability checked in read()
  1421     CHECK_READABLE(getChar, false);
       
  1422 
       
  1423     char ch;
  1453     char ch;
  1424     return (1 == read(c ? c : &ch, 1));
  1454     return (1 == read(c ? c : &ch, 1));
  1425 }
  1455 }
  1426 
  1456 
  1427 /*!
  1457 /*!