branch | RCL_3 |
changeset 7 | 3f74d0d4af4c |
parent 4 | 3b1da2848fc7 |
child 13 | c0432d11811c |
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 /*! |