Qt 4.8
qiodevice.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 //#define QIODEVICE_DEBUG
43 
44 #include "qbytearray.h"
45 #include "qdebug.h"
46 #include "qiodevice_p.h"
47 #include "qfile.h"
48 #include "qstringlist.h"
49 #include <limits.h>
50 
51 #ifdef QIODEVICE_DEBUG
52 # include <ctype.h>
53 #endif
54 
56 
57 #ifdef QIODEVICE_DEBUG
58 void debugBinaryString(const QByteArray &input)
59 {
60  QByteArray tmp;
61  int startOffset = 0;
62  for (int i = 0; i < input.size(); ++i) {
63  tmp += input[i];
64 
65  if ((i % 16) == 15 || i == (input.size() - 1)) {
66  printf("\n%15d:", startOffset);
67  startOffset += tmp.size();
68 
69  for (int j = 0; j < tmp.size(); ++j)
70  printf(" %02x", int(uchar(tmp[j])));
71  for (int j = tmp.size(); j < 16 + 1; ++j)
72  printf(" ");
73  for (int j = 0; j < tmp.size(); ++j)
74  printf("%c", isprint(int(uchar(tmp[j]))) ? tmp[j] : '.');
75  tmp.clear();
76  }
77  }
78  printf("\n\n");
79 }
80 
81 void debugBinaryString(const char *data, qint64 maxlen)
82 {
83  debugBinaryString(QByteArray(data, maxlen));
84 }
85 #endif
86 
87 #define Q_VOID
88 
89 #define CHECK_MAXLEN(function, returnType) \
90  do { \
91  if (maxSize < 0) { \
92  qWarning("QIODevice::"#function": Called with maxSize < 0"); \
93  return returnType; \
94  } \
95  } while (0)
96 
97 #define CHECK_WRITABLE(function, returnType) \
98  do { \
99  if ((d->openMode & WriteOnly) == 0) { \
100  if (d->openMode == NotOpen) \
101  return returnType; \
102  qWarning("QIODevice::"#function": ReadOnly device"); \
103  return returnType; \
104  } \
105  } while (0)
106 
107 #define CHECK_READABLE(function, returnType) \
108  do { \
109  if ((d->openMode & ReadOnly) == 0) { \
110  if (d->openMode == NotOpen) \
111  return returnType; \
112  qWarning("QIODevice::"#function": WriteOnly device"); \
113  return returnType; \
114  } \
115  } while (0)
116 
120  : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
121  pos(0), devicePos(0), seqDumpPos(0)
122  , pPos(&pos), pDevicePos(&devicePos)
123  , baseReadLineDataCalled(false)
124  , firstRead(true)
125  , accessMode(Unset)
126 #ifdef QT_NO_QOBJECT
127  , q_ptr(0)
128 #endif
129 {
130 }
131 
135 {
136 }
137 
370 #ifdef QT_NO_QOBJECT
372  : d_ptr(new QIODevicePrivate)
373 {
374  d_ptr->q_ptr = this;
375 }
376 
380  : d_ptr(&dd)
381 {
382  d_ptr->q_ptr = this;
383 }
384 #else
385 
391  : QObject(*new QIODevicePrivate, 0)
392 {
393 #if defined QIODEVICE_DEBUG
394  QFile *file = qobject_cast<QFile *>(this);
395  printf("%p QIODevice::QIODevice(\"%s\") %s\n", this, metaObject()->className(),
396  qPrintable(file ? file->fileName() : QString()));
397 #endif
398 }
399 
405  : QObject(*new QIODevicePrivate, parent)
406 {
407 #if defined QIODEVICE_DEBUG
408  printf("%p QIODevice::QIODevice(%p \"%s\")\n", this, parent, metaObject()->className());
409 #endif
410 }
411 
415  : QObject(dd, parent)
416 {
417 }
418 #endif
419 
420 
428 {
429 #if defined QIODEVICE_DEBUG
430  printf("%p QIODevice::~QIODevice()\n", this);
431 #endif
432 }
433 
455 {
456  return false;
457 }
458 
465 QIODevice::OpenMode QIODevice::openMode() const
466 {
467  return d_func()->openMode;
468 }
469 
478 {
479  Q_D(QIODevice);
480 #if defined QIODEVICE_DEBUG
481  printf("%p QIODevice::setOpenMode(0x%x)\n", this, int(openMode));
482 #endif
483  d->openMode = openMode;
484  d->accessMode = QIODevicePrivate::Unset;
485  d->firstRead = true;
486  if (!isReadable())
487  d->buffer.clear();
488 }
489 
500 {
501  Q_D(QIODevice);
502  if (!isOpen()) {
503  qWarning("QIODevice::setTextModeEnabled: The device is not open");
504  return;
505  }
506  if (enabled)
507  d->openMode |= Text;
508  else
509  d->openMode &= ~Text;
510 }
511 
518 {
519  return d_func()->openMode & Text;
520 }
521 
530 bool QIODevice::isOpen() const
531 {
532  return d_func()->openMode != NotOpen;
533 }
534 
545 {
546  return (openMode() & ReadOnly) != 0;
547 }
548 
559 {
560  return (openMode() & WriteOnly) != 0;
561 }
562 
570 bool QIODevice::open(OpenMode mode)
571 {
572  Q_D(QIODevice);
573  d->openMode = mode;
574  d->pos = (mode & Append) ? size() : qint64(0);
575  d->buffer.clear();
576  d->accessMode = QIODevicePrivate::Unset;
577  d->firstRead = true;
578 #if defined QIODEVICE_DEBUG
579  printf("%p QIODevice::open(0x%x)\n", this, quint32(mode));
580 #endif
581  return true;
582 }
583 
591 {
592  Q_D(QIODevice);
593  if (d->openMode == NotOpen)
594  return;
595 
596 #if defined QIODEVICE_DEBUG
597  printf("%p QIODevice::close()\n", this);
598 #endif
599 
600 #ifndef QT_NO_QOBJECT
601  emit aboutToClose();
602 #endif
603  d->openMode = NotOpen;
604  d->errorString.clear();
605  d->pos = 0;
606  d->seqDumpPos = 0;
607  d->buffer.clear();
608  d->firstRead = true;
609 }
610 
625 {
626  Q_D(const QIODevice);
627 #if defined QIODEVICE_DEBUG
628  printf("%p QIODevice::pos() == %d\n", this, int(d->pos));
629 #endif
630  return d->pos;
631 }
632 
643 {
644  return d_func()->isSequential() ? bytesAvailable() : qint64(0);
645 }
646 
660 {
661  Q_D(QIODevice);
662  if (d->openMode == NotOpen) {
663  qWarning("QIODevice::seek: The device is not open");
664  return false;
665  }
666  if (pos < 0) {
667  qWarning("QIODevice::seek: Invalid pos: %d", int(pos));
668  return false;
669  }
670 
671 #if defined QIODEVICE_DEBUG
672  printf("%p QIODevice::seek(%d), before: d->pos = %d, d->buffer.size() = %d\n",
673  this, int(pos), int(d->pos), d->buffer.size());
674 #endif
675 
676  qint64 offset = pos - d->pos;
677  if (!d->isSequential()) {
678  d->pos = pos;
679  d->devicePos = pos;
680  }
681 
682  if (offset < 0
683  || offset >= qint64(d->buffer.size()))
684  // When seeking backwards, an operation that is only allowed for
685  // random-access devices, the buffer is cleared. The next read
686  // operation will then refill the buffer. We can optimize this, if we
687  // find that seeking backwards becomes a significant performance hit.
688  d->buffer.clear();
689  else if (!d->buffer.isEmpty())
690  d->buffer.skip(int(offset));
691 
692 #if defined QIODEVICE_DEBUG
693  printf("%p \tafter: d->pos == %d, d->buffer.size() == %d\n", this, int(d->pos),
694  d->buffer.size());
695 #endif
696  return true;
697 }
698 
711 bool QIODevice::atEnd() const
712 {
713  Q_D(const QIODevice);
714 #if defined QIODEVICE_DEBUG
715  printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %d\n", this, (d->openMode == NotOpen || d->pos == size()) ? "true" : "false",
716  int(d->openMode), int(d->pos));
717 #endif
718  return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0);
719 }
720 
733 {
734 #if defined QIODEVICE_DEBUG
735  printf("%p QIODevice::reset()\n", this);
736 #endif
737  return seek(0);
738 }
739 
753 {
754  Q_D(const QIODevice);
755  if (!d->isSequential())
756  return qMax(size() - d->pos, qint64(0));
757  return d->buffer.size();
758 }
759 
768 {
769  return qint64(0);
770 }
771 
772 #ifdef Q_CC_RVCT
773 // arm mode makes the 64-bit integer operations much faster in RVCT 2.2
774 #pragma push
775 #pragma arm
776 #endif
777 
791 qint64 QIODevice::read(char *data, qint64 maxSize)
792 {
793  Q_D(QIODevice);
794 
795 #if defined QIODEVICE_DEBUG
796  printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n",
797  this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
798 #endif
799 
800  // Short circuit for getChar()
801  if (maxSize == 1) {
802  int chint;
803  while ((chint = d->buffer.getChar()) != -1) {
804  ++(*d->pPos);
805 
806  char c = char(uchar(chint));
807  if (c == '\r' && (d->openMode & Text))
808  continue;
809  *data = c;
810 #if defined QIODEVICE_DEBUG
811  printf("%p \tread 0x%hhx (%c) returning 1 (shortcut)\n", this,
812  int(c), isprint(c) ? c : '?');
813 #endif
814  return qint64(1);
815  }
816  }
817 
818  CHECK_MAXLEN(read, qint64(-1));
819  qint64 readSoFar = 0;
820  bool moreToRead = true;
821  do {
822  // Try reading from the buffer.
823  int lastReadChunkSize = d->buffer.read(data, maxSize);
824  if (lastReadChunkSize > 0) {
825  *d->pPos += lastReadChunkSize;
826  readSoFar += lastReadChunkSize;
827  // fast exit when satisfied by buffer
828  if (lastReadChunkSize == maxSize && !(d->openMode & Text))
829  return readSoFar;
830 
831  data += lastReadChunkSize;
832  maxSize -= lastReadChunkSize;
833 #if defined QIODEVICE_DEBUG
834  printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
835  int(readSoFar) - lastReadChunkSize);
836 #endif
837  } else {
838  if (d->firstRead) {
839  // this is the first time the file has been read, check it's valid and set up pos pointers
840  // for fast pos updates.
841  CHECK_READABLE(read, qint64(-1));
842  d->firstRead = false;
843  if (d->isSequential()) {
844  d->pPos = &d->seqDumpPos;
845  d->pDevicePos = &d->seqDumpPos;
846  }
847  }
848 
849  if (!maxSize)
850  return readSoFar;
851 
852  if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
853  // In buffered mode, we try to fill up the QIODevice buffer before
854  // we do anything else.
855  // buffer is empty at this point, try to fill it
856  int bytesToBuffer = QIODEVICE_BUFFERSIZE;
857  char *writePointer = d->buffer.reserve(bytesToBuffer);
858 
859  // Make sure the device is positioned correctly.
860  if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
861  return readSoFar ? readSoFar : qint64(-1);
862  qint64 readFromDevice = readData(writePointer, bytesToBuffer);
863  d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
864 
865  if (readFromDevice > 0) {
866  *d->pDevicePos += readFromDevice;
867 #if defined QIODEVICE_DEBUG
868  printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
869 #endif
870 
871  if (!d->buffer.isEmpty()) {
872  lastReadChunkSize = d->buffer.read(data, maxSize);
873  readSoFar += lastReadChunkSize;
874  data += lastReadChunkSize;
875  maxSize -= lastReadChunkSize;
876  *d->pPos += lastReadChunkSize;
877 #if defined QIODEVICE_DEBUG
878  printf("%p \treading %d bytes from buffer at position %d\n", this,
879  lastReadChunkSize, int(readSoFar));
880 #endif
881  }
882  }
883  }
884  }
885 
886  // If we need more, try reading from the device.
887  if (maxSize > 0) {
888  // Make sure the device is positioned correctly.
889  if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
890  return readSoFar ? readSoFar : qint64(-1);
891  qint64 readFromDevice = readData(data, maxSize);
892 #if defined QIODEVICE_DEBUG
893  printf("%p \treading %d bytes from device (total %d)\n", this, int(readFromDevice), int(readSoFar));
894 #endif
895  if (readFromDevice == -1 && readSoFar == 0) {
896  // error and we haven't read anything: return immediately
897  return -1;
898  }
899  if (readFromDevice > 0) {
900  lastReadChunkSize += int(readFromDevice);
901  readSoFar += readFromDevice;
902  data += readFromDevice;
903  maxSize -= readFromDevice;
904  *d->pPos += readFromDevice;
905  *d->pDevicePos += readFromDevice;
906  }
907  }
908  // Best attempt has been made to read data, don't try again except for text mode adjustment below
909  moreToRead = false;
910 
911  if (readSoFar && d->openMode & Text) {
912  char *readPtr = data - lastReadChunkSize;
913  const char *endPtr = data;
914 
915  if (readPtr < endPtr) {
916  // optimization to avoid initial self-assignment
917  while (*readPtr != '\r') {
918  if (++readPtr == endPtr)
919  return readSoFar;
920  }
921 
922  char *writePtr = readPtr;
923 
924  while (readPtr < endPtr) {
925  char ch = *readPtr++;
926  if (ch != '\r')
927  *writePtr++ = ch;
928  else {
929  --readSoFar;
930  --data;
931  ++maxSize;
932  }
933  }
934 
935  // Make sure we get more data if there is room for more. This
936  // is very important for when someone seeks to the start of a
937  // '\r\n' and reads one character - they should get the '\n'.
938  moreToRead = (readPtr != writePtr);
939  }
940  }
941  } while (moreToRead);
942 
943 #if defined QIODEVICE_DEBUG
944  printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this,
945  int(readSoFar), int(d->pos), d->buffer.size());
946  debugBinaryString(data - readSoFar, readSoFar);
947 #endif
948  return readSoFar;
949 }
950 
951 #ifdef Q_CC_RVCT
952 #pragma pop
953 #endif
954 
969 {
970  Q_D(QIODevice);
971  QByteArray result;
972 
973  CHECK_MAXLEN(read, result);
974 
975 #if defined QIODEVICE_DEBUG
976  printf("%p QIODevice::read(%d), d->pos = %d, d->buffer.size() = %d\n",
977  this, int(maxSize), int(d->pos), int(d->buffer.size()));
978 #else
979  Q_UNUSED(d);
980 #endif
981 
982  if (maxSize != qint64(int(maxSize))) {
983  qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit");
984  maxSize = INT_MAX;
985  }
986 
987  qint64 readBytes = 0;
988  if (maxSize) {
989  result.resize(int(maxSize));
990  if (!result.size()) {
991  // If resize fails, read incrementally.
992  qint64 readResult;
993  do {
994  result.resize(int(qMin(maxSize, result.size() + QIODEVICE_BUFFERSIZE)));
995  readResult = read(result.data() + readBytes, result.size() - readBytes);
996  if (readResult > 0 || readBytes == 0)
997  readBytes += readResult;
998  } while (readResult == QIODEVICE_BUFFERSIZE);
999  } else {
1000  readBytes = read(result.data(), result.size());
1001  }
1002  }
1003 
1004  if (readBytes <= 0)
1005  result.clear();
1006  else
1007  result.resize(int(readBytes));
1008 
1009  return result;
1010 }
1011 
1026 {
1027  Q_D(QIODevice);
1028 #if defined QIODEVICE_DEBUG
1029  printf("%p QIODevice::readAll(), d->pos = %d, d->buffer.size() = %d\n",
1030  this, int(d->pos), int(d->buffer.size()));
1031 #endif
1032 
1033  QByteArray result;
1034  qint64 readBytes = 0;
1035 
1036  // flush internal read buffer
1037  if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
1038  result = d->buffer.readAll();
1039  readBytes = result.size();
1040  d->pos += readBytes;
1041  }
1042 
1043  qint64 theSize;
1044  if (d->isSequential() || (theSize = size()) == 0) {
1045  // Size is unknown, read incrementally.
1046  qint64 readResult;
1047  do {
1048  result.resize(result.size() + QIODEVICE_BUFFERSIZE);
1049  readResult = read(result.data() + readBytes, result.size() - readBytes);
1050  if (readResult > 0 || readBytes == 0)
1051  readBytes += readResult;
1052  } while (readResult > 0);
1053  } else {
1054  // Read it all in one go.
1055  // If resize fails, don't read anything.
1056  result.resize(int(readBytes + theSize - d->pos));
1057  readBytes += read(result.data() + readBytes, result.size() - readBytes);
1058  }
1059 
1060  if (readBytes <= 0)
1061  result.clear();
1062  else
1063  result.resize(int(readBytes));
1064 
1065  return result;
1066 }
1067 
1068 #ifdef Q_CC_RVCT
1069 // arm mode makes the 64-bit integer operations much faster in RVCT 2.2
1070 #pragma push
1071 #pragma arm
1072 #endif
1073 
1110 qint64 QIODevice::readLine(char *data, qint64 maxSize)
1111 {
1112  Q_D(QIODevice);
1113  if (maxSize < 2) {
1114  qWarning("QIODevice::readLine: Called with maxSize < 2");
1115  return qint64(-1);
1116  }
1117 
1118 #if defined QIODEVICE_DEBUG
1119  printf("%p QIODevice::readLine(%p, %d), d->pos = %d, d->buffer.size() = %d\n",
1120  this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
1121 #endif
1122 
1123  // Leave room for a '\0'
1124  --maxSize;
1125 
1126  const bool sequential = d->isSequential();
1127 
1128  qint64 readSoFar = 0;
1129  if (!d->buffer.isEmpty()) {
1130  readSoFar = d->buffer.readLine(data, maxSize);
1131  if (!sequential)
1132  d->pos += readSoFar;
1133 #if defined QIODEVICE_DEBUG
1134  printf("%p \tread from buffer: %d bytes, last character read: %hhx\n", this,
1135  int(readSoFar), data[int(readSoFar) - 1]);
1136  if (readSoFar)
1137  debugBinaryString(data, int(readSoFar));
1138 #endif
1139 #if defined(Q_OS_SYMBIAN)
1140  // Open C fgets strips '\r' but readSoFar gets returned as if it was still there
1141  if ((d->openMode & Text) &&
1142  readSoFar > 1 &&
1143  data[readSoFar - 1] == '\0' &&
1144  data[readSoFar - 2] == '\n') {
1145  --readSoFar;
1146  }
1147 #endif
1148  if (readSoFar && data[readSoFar - 1] == '\n') {
1149  if (d->openMode & Text) {
1150  // QRingBuffer::readLine() isn't Text aware.
1151  if (readSoFar > 1 && data[readSoFar - 2] == '\r') {
1152  --readSoFar;
1153  data[readSoFar - 1] = '\n';
1154  }
1155  }
1156  data[readSoFar] = '\0';
1157  return readSoFar;
1158  }
1159  }
1160 
1161  if (d->pos != d->devicePos && !sequential && !seek(d->pos))
1162  return qint64(-1);
1163  d->baseReadLineDataCalled = false;
1164  qint64 readBytes = readLineData(data + readSoFar, maxSize - readSoFar);
1165 #if defined QIODEVICE_DEBUG
1166  printf("%p \tread from readLineData: %d bytes, readSoFar = %d bytes\n", this,
1167  int(readBytes), int(readSoFar));
1168  if (readBytes > 0) {
1169  debugBinaryString(data, int(readSoFar + readBytes));
1170  }
1171 #endif
1172  if (readBytes < 0) {
1173  data[readSoFar] = '\0';
1174  return readSoFar ? readSoFar : -1;
1175  }
1176  readSoFar += readBytes;
1177  if (!d->baseReadLineDataCalled && !sequential) {
1178  d->pos += readBytes;
1179  // If the base implementation was not called, then we must
1180  // assume the device position is invalid and force a seek.
1181  d->devicePos = qint64(-1);
1182  }
1183  data[readSoFar] = '\0';
1184 
1185  if (d->openMode & Text) {
1186 #if defined(Q_OS_SYMBIAN)
1187  // Open C fgets strips '\r' but readSoFar gets returned as if it was still there
1188  if (readSoFar > 1 && data[readSoFar - 1] == '\0' && data[readSoFar - 2] == '\n') {
1189  --readSoFar;
1190  }
1191 #endif
1192  if (readSoFar > 1 && data[readSoFar - 1] == '\n' && data[readSoFar - 2] == '\r') {
1193  data[readSoFar - 2] = '\n';
1194  data[readSoFar - 1] = '\0';
1195  --readSoFar;
1196  }
1197  }
1198 
1199 #if defined QIODEVICE_DEBUG
1200  printf("%p \treturning %d, d->pos = %d, d->buffer.size() = %d, size() = %d\n",
1201  this, int(readSoFar), int(d->pos), d->buffer.size(), int(size()));
1202  debugBinaryString(data, int(readSoFar));
1203 #endif
1204  return readSoFar;
1205 }
1206 
1221 {
1222  Q_D(QIODevice);
1223  QByteArray result;
1224 
1225  CHECK_MAXLEN(readLine, result);
1226 
1227 #if defined QIODEVICE_DEBUG
1228  printf("%p QIODevice::readLine(%d), d->pos = %d, d->buffer.size() = %d\n",
1229  this, int(maxSize), int(d->pos), int(d->buffer.size()));
1230 #else
1231  Q_UNUSED(d);
1232 #endif
1233 
1234  if (maxSize > INT_MAX) {
1235  qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit");
1236  maxSize = INT_MAX;
1237  }
1238 
1239  result.resize(int(maxSize));
1240  qint64 readBytes = 0;
1241  if (!result.size()) {
1242  // If resize fails or maxSize == 0, read incrementally
1243  if (maxSize == 0)
1244  maxSize = INT_MAX;
1245 
1246  // The first iteration needs to leave an extra byte for the terminating null
1247  result.resize(1);
1248 
1249  qint64 readResult;
1250  do {
1251  result.resize(int(qMin(maxSize, result.size() + QIODEVICE_BUFFERSIZE)));
1252  readResult = readLine(result.data() + readBytes, result.size() - readBytes);
1253  if (readResult > 0 || readBytes == 0)
1254  readBytes += readResult;
1255  } while (readResult == QIODEVICE_BUFFERSIZE
1256  && result[int(readBytes - 1)] != '\n');
1257  } else
1258  readBytes = readLine(result.data(), result.size());
1259 
1260  if (readBytes <= 0)
1261  result.clear();
1262  else
1263  result.resize(readBytes);
1264 
1265  return result;
1266 }
1267 
1286 {
1287  Q_D(QIODevice);
1288  qint64 readSoFar = 0;
1289  char c;
1290  int lastReadReturn = 0;
1291  d->baseReadLineDataCalled = true;
1292 
1293  while (readSoFar < maxSize && (lastReadReturn = read(&c, 1)) == 1) {
1294  *data++ = c;
1295  ++readSoFar;
1296  if (c == '\n')
1297  break;
1298  }
1299 
1300 #if defined QIODEVICE_DEBUG
1301  printf("%p QIODevice::readLineData(%p, %d), d->pos = %d, d->buffer.size() = %d, returns %d\n",
1302  this, data, int(maxSize), int(d->pos), int(d->buffer.size()), int(readSoFar));
1303 #endif
1304  if (lastReadReturn != 1 && readSoFar == 0)
1305  return isSequential() ? lastReadReturn : -1;
1306  return readSoFar;
1307 }
1308 
1309 #ifdef Q_CC_RVCT
1310 #pragma pop
1311 #endif
1312 
1331 {
1332  return d_func()->buffer.canReadLine();
1333 }
1334 
1342 qint64 QIODevice::write(const char *data, qint64 maxSize)
1343 {
1344  Q_D(QIODevice);
1345  CHECK_WRITABLE(write, qint64(-1));
1346  CHECK_MAXLEN(write, qint64(-1));
1347 
1348  const bool sequential = d->isSequential();
1349  // Make sure the device is positioned correctly.
1350  if (d->pos != d->devicePos && !sequential && !seek(d->pos))
1351  return qint64(-1);
1352 
1353 #ifdef Q_OS_WIN
1354  if (d->openMode & Text) {
1355  const char *endOfData = data + maxSize;
1356  const char *startOfBlock = data;
1357 
1358  qint64 writtenSoFar = 0;
1359 
1360  forever {
1361  const char *endOfBlock = startOfBlock;
1362  while (endOfBlock < endOfData && *endOfBlock != '\n')
1363  ++endOfBlock;
1364 
1365  qint64 blockSize = endOfBlock - startOfBlock;
1366  if (blockSize > 0) {
1367  qint64 ret = writeData(startOfBlock, blockSize);
1368  if (ret <= 0) {
1369  if (writtenSoFar && !sequential)
1370  d->buffer.skip(writtenSoFar);
1371  return writtenSoFar ? writtenSoFar : ret;
1372  }
1373  if (!sequential) {
1374  d->pos += ret;
1375  d->devicePos += ret;
1376  }
1377  writtenSoFar += ret;
1378  }
1379 
1380  if (endOfBlock == endOfData)
1381  break;
1382 
1383  qint64 ret = writeData("\r\n", 2);
1384  if (ret <= 0) {
1385  if (writtenSoFar && !sequential)
1386  d->buffer.skip(writtenSoFar);
1387  return writtenSoFar ? writtenSoFar : ret;
1388  }
1389  if (!sequential) {
1390  d->pos += ret;
1391  d->devicePos += ret;
1392  }
1393  ++writtenSoFar;
1394 
1395  startOfBlock = endOfBlock + 1;
1396  }
1397 
1398  if (writtenSoFar && !sequential)
1399  d->buffer.skip(writtenSoFar);
1400  return writtenSoFar;
1401  }
1402 #endif
1403 
1404  qint64 written = writeData(data, maxSize);
1405  if (written > 0) {
1406  if (!sequential) {
1407  d->pos += written;
1408  d->devicePos += written;
1409  }
1410  if (!d->buffer.isEmpty() && !sequential)
1411  d->buffer.skip(written);
1412  }
1413  return written;
1414 }
1415 
1435 qint64 QIODevice::write(const char *data)
1436 {
1437  return write(data, qstrlen(data));
1438 }
1439 
1463 {
1464  Q_D(QIODevice);
1466 
1467 #if defined QIODEVICE_DEBUG
1468  printf("%p QIODevice::ungetChar(0x%hhx '%c')\n", this, c, isprint(c) ? c : '?');
1469 #endif
1470 
1471  d->buffer.ungetChar(c);
1472  if (!d->isSequential())
1473  --d->pos;
1474 }
1475 
1487 {
1488  return d_func()->putCharHelper(c);
1489 }
1490 
1495 {
1496  return q_func()->write(&c, 1) == 1;
1497 }
1498 
1503 {
1504  qint64 readBytes = q_func()->read(data, maxSize);
1505  if (readBytes <= 0)
1506  return readBytes;
1507 
1508  buffer.ungetBlock(data, readBytes);
1509  *pPos -= readBytes;
1510  return readBytes;
1511 }
1512 
1517 {
1518  QByteArray result = q_func()->read(maxSize);
1519 
1520  if (result.isEmpty())
1521  return result;
1522 
1523  buffer.ungetBlock(result.constData(), result.size());
1524  *pPos -= result.size();
1525  return result;
1526 }
1527 
1537 {
1538  // readability checked in read()
1539  char ch;
1540  return (1 == read(c ? c : &ch, 1));
1541 }
1542 
1563 qint64 QIODevice::peek(char *data, qint64 maxSize)
1564 {
1565  return d_func()->peek(data, maxSize);
1566 }
1567 
1589 {
1590  return d_func()->peek(maxSize);
1591 }
1592 
1617 {
1618  Q_UNUSED(msecs);
1619  return false;
1620 }
1621 
1649 {
1650  Q_UNUSED(msecs);
1651  return false;
1652 }
1653 
1661 {
1662  d_func()->errorString = str;
1663 }
1664 
1672 {
1673  Q_D(const QIODevice);
1674  if (d->errorString.isEmpty()) {
1675 #ifdef QT_NO_QOBJECT
1676  return QLatin1String(QT_TRANSLATE_NOOP(QIODevice, "Unknown error"));
1677 #else
1678  return tr("Unknown error");
1679 #endif
1680  }
1681  return d->errorString;
1682 }
1683 
1907 #if defined QT3_SUPPORT
1909 {
1910 #if !defined(QT_NO_QOBJECT)
1911  const QFile *f = qobject_cast<const QFile *>(this);
1912  if (f) return (int) f->error();
1913 #endif
1914  return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
1915 }
1916 
1923 void QIODevice::resetStatus()
1924 {
1925 #if !defined(QT_NO_QOBJECT)
1926  QFile *f = qobject_cast<QFile *>(this);
1927  if (f) f->unsetError();
1928 #endif
1929 }
1930 #endif
1931 
1932 #if !defined(QT_NO_DEBUG_STREAM)
1933 QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)
1934 {
1935  debug << "OpenMode(";
1936  QStringList modeList;
1937  if (modes == QIODevice::NotOpen) {
1938  modeList << QLatin1String("NotOpen");
1939  } else {
1940  if (modes & QIODevice::ReadOnly)
1941  modeList << QLatin1String("ReadOnly");
1942  if (modes & QIODevice::WriteOnly)
1943  modeList << QLatin1String("WriteOnly");
1944  if (modes & QIODevice::Append)
1945  modeList << QLatin1String("Append");
1946  if (modes & QIODevice::Truncate)
1947  modeList << QLatin1String("Truncate");
1948  if (modes & QIODevice::Text)
1949  modeList << QLatin1String("Text");
1950  if (modes & QIODevice::Unbuffered)
1951  modeList << QLatin1String("Unbuffered");
1952  }
1953  qSort(modeList);
1954  debug << modeList.join(QLatin1String("|"));
1955  debug << ')';
1956  return debug;
1957 }
1958 #endif
1959 
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
double d
Definition: qnumeric_p.h:62
const int blockSize
QString fileName() const
Returns the name set by setFileName() or to the QFile constructors.
Definition: qfile.cpp:470
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
Definition: qiodevice.cpp:642
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void setOpenMode(OpenMode openMode)
Sets the OpenMode of the device to openMode.
Definition: qiodevice.cpp:477
#define CHECK_WRITABLE(function, returnType)
Definition: qiodevice.cpp:97
virtual bool waitForReadyRead(int msecs)
Blocks until new data is available for reading and the readyRead() signal has been emitted...
Definition: qiodevice.cpp:1616
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
bool isReadable() const
Returns true if data can be read from the device; otherwise returns false.
Definition: qiodevice.cpp:544
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
Definition: qiodevice.cpp:590
#define CHECK_MAXLEN(function, returnType)
Definition: qiodevice.cpp:89
virtual qint64 peek(char *data, qint64 maxSize)
Definition: qiodevice.cpp:1502
void aboutToClose()
This signal is emitted when the device is about to close.
virtual qint64 writeData(const char *data, qint64 len)=0
Writes up to maxSize bytes from data to the device.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QString errorString() const
Returns a human-readable description of the last device error that occurred.
Definition: qiodevice.cpp:1671
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
bool getChar(char *c)
Reads one character from the device and stores it in c.
Definition: qiodevice.cpp:1536
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
#define QT_TRANSLATE_NOOP(scope, x)
Marks the string literal sourceText for dynamic translation in the given context; i...
Definition: qglobal.h:2487
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool putChar(char c)
Writes the character c to the device.
Definition: qiodevice.cpp:1486
#define QIODEVICE_BUFFERSIZE
Definition: qiodevice_p.h:68
void ungetChar(char c)
Puts the character c back into the device, and decrements the current position unless the position is...
Definition: qiodevice.cpp:1462
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_VOID
Definition: qiodevice.cpp:87
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i.e.
Definition: qiodevice.cpp:711
void setTextModeEnabled(bool enabled)
If enabled is true, this function sets the Text flag on the device; otherwise the Text flag is remove...
Definition: qiodevice.cpp:499
const char * className
Definition: qwizard.cpp:137
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
virtual qint64 readLineData(char *data, qint64 maxlen)
Reads up to maxSize characters into data and returns the number of characters read.
Definition: qiodevice.cpp:1285
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
unsigned char uchar
Definition: qglobal.h:994
virtual qint64 bytesToWrite() const
For buffered devices, this function returns the number of bytes waiting to be written.
Definition: qiodevice.cpp:767
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual ~QIODevice()
The destructor is virtual, and QIODevice is an abstract base class.
Definition: qiodevice.cpp:427
bool isOpen() const
Returns true if the device is open; otherwise returns false.
Definition: qiodevice.cpp:530
virtual bool putCharHelper(char c)
Definition: qiodevice.cpp:1494
#define emit
Definition: qobjectdefs.h:76
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
qint64 peek(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, without side effects (i.
Definition: qiodevice.cpp:1563
Q_CORE_EXPORT void qWarning(const char *,...)
QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)
Definition: qiodevice.cpp:1933
static const char * data(const QByteArray &arr)
__int64 qint64
Definition: qglobal.h:942
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
Definition: qiodevice.cpp:454
virtual qint64 readData(char *data, qint64 maxlen)=0
Reads up to maxSize bytes from the device into data, and returns the number of bytes read or -1 if an...
void unsetError()
Sets the file&#39;s error to QFile::NoError.
Definition: qfile.cpp:1996
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString join(const QString &sep) const
Joins all the string list&#39;s strings into a single string with each element separated by the given sep...
Definition: qstringlist.h:162
uint qstrlen(const char *str)
Definition: qbytearray.h:79
virtual ~QIODevicePrivate()
Definition: qiodevice.cpp:134
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
qint64 readLine(char *data, qint64 maxlen)
This function reads a line of ASCII characters from the device, up to a maximum of maxSize - 1 bytes...
Definition: qiodevice.cpp:1110
OpenMode openMode() const
Returns the mode in which the device has been opened; i.e.
Definition: qiodevice.cpp:465
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setErrorString(const QString &errorString)
Sets the human readable description of the last device error that occurred to str.
Definition: qiodevice.cpp:1660
void resize(int size)
Sets the size of the byte array to size bytes.
unsigned int quint32
Definition: qglobal.h:938
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
Definition: qiodevice.cpp:752
QIODevice()
Constructs a QIODevice object.
Definition: qiodevice.cpp:390
virtual bool reset()
Seeks to the start of input for random-access devices.
Definition: qiodevice.cpp:732
virtual bool waitForBytesWritten(int msecs)
For buffered devices, this function waits until a payload of buffered written data has been written t...
Definition: qiodevice.cpp:1648
QByteArray readAll()
Reads all available data from the device, and returns it as a QByteArray.
Definition: qiodevice.cpp:1025
#define CHECK_READABLE(function, returnType)
Definition: qiodevice.cpp:107
bool isTextModeEnabled() const
Returns true if the Text flag is enabled; otherwise returns false.
Definition: qiodevice.cpp:517
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
virtual bool open(OpenMode mode)
Opens the device and sets its OpenMode to mode.
Definition: qiodevice.cpp:570
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false...
Definition: qiodevice.cpp:1330
FileError error() const
Returns the file error status.
Definition: qfile.cpp:1984
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
#define qPrintable(string)
Definition: qglobal.h:1750
#define Status
Definition: qcursor_x11.cpp:59
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
#define INT_MAX
#define enabled
void clear()
Clears the contents of the byte array and makes it empty.
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
The Text item allows you to add formatted text to a scene.
#define forever
This macro is provided for convenience for writing infinite loops.
Definition: qglobal.h:2452