QtBase  v6.3.1
qtextstream.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 //#define QTEXTSTREAM_DEBUG
42 static const int QTEXTSTREAM_BUFFERSIZE = 16384;
43 
227 #include "qtextstream.h"
228 #include "private/qtextstream_p.h"
229 #include "qbuffer.h"
230 #include "qfile.h"
231 #include "qnumeric.h"
232 #include "qvarlengtharray.h"
233 #include <private/qdebug_p.h>
234 
235 #include <locale.h>
236 #include "private/qlocale_p.h"
237 #include "private/qstringconverter_p.h"
238 
239 #include <stdlib.h>
240 #include <limits.h>
241 #include <new>
242 
243 // A precondition macro
244 #define Q_VOID
245 #define CHECK_VALID_STREAM(x) do { \
246  if (!d->string && !d->device) { \
247  qWarning("QTextStream: No device"); \
248  return x; \
249  } } while (0)
250 
251 // Base implementations of operator>> for ints and reals
252 #define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type) do { \
253  Q_D(QTextStream); \
254  CHECK_VALID_STREAM(*this); \
255  qulonglong tmp; \
256  switch (d->getNumber(&tmp)) { \
257  case QTextStreamPrivate::npsOk: \
258  i = (type)tmp; \
259  break; \
260  case QTextStreamPrivate::npsMissingDigit: \
261  case QTextStreamPrivate::npsInvalidPrefix: \
262  i = (type)0; \
263  setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
264  break; \
265  } \
266  return *this; } while (0)
267 
268 #define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type) do { \
269  Q_D(QTextStream); \
270  CHECK_VALID_STREAM(*this); \
271  double tmp; \
272  if (d->getReal(&tmp)) { \
273  f = (type)tmp; \
274  } else { \
275  f = (type)0; \
276  setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
277  } \
278  return *this; } while (0)
279 
281 
282 //-------------------------------------------------------------------
283 
288  : readConverterSavedStateOffset(0),
289  locale(QLocale::c())
290 {
291  this->q_ptr = q_ptr;
292  reset();
293 }
294 
299 {
300  if (deleteDevice) {
301 #ifndef QT_NO_QOBJECT
302  device->blockSignals(true);
303 #endif
304  delete device;
305  }
306 }
307 
309 {
311  integerBase = 0;
312  fieldWidth = 0;
313  padChar = QLatin1Char(' ');
316  numberFlags = { };
317 }
318 
323 {
324  params.reset();
325 
326  device = nullptr;
327  deleteDevice = false;
328  string = nullptr;
329  stringOffset = 0;
331 
332  readBufferOffset = 0;
334  lastTokenSize = 0;
335 
336  hasWrittenData = false;
337  generateBOM = false;
341  autoDetectUnicode = true;
342 }
343 
348 {
349  // no buffer next to the QString itself; this function should only
350  // be called internally, for devices.
351  Q_ASSERT(!string);
352  Q_ASSERT(device);
353 
354  // handle text translation and bypass the Text flag in the device.
355  bool textModeEnabled = device->isTextModeEnabled();
356  if (textModeEnabled)
357  device->setTextModeEnabled(false);
358 
359  // read raw data into a temporary buffer
360  char buf[QTEXTSTREAM_BUFFERSIZE];
361  qint64 bytesRead = 0;
362 #if defined(Q_OS_WIN)
363  // On Windows, there is no non-blocking stdin - so we fall back to reading
364  // lines instead. If there is no QOBJECT, we read lines for all sequential
365  // devices; otherwise, we read lines only for stdin.
366  QFile *file = 0;
367  Q_UNUSED(file);
368  if (device->isSequential()
369 #if !defined(QT_NO_QOBJECT)
370  && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
371 #endif
372  ) {
373  if (maxBytes != -1)
374  bytesRead = device->readLine(buf, qMin<qint64>(sizeof(buf), maxBytes));
375  else
376  bytesRead = device->readLine(buf, sizeof(buf));
377  } else
378 #endif
379  {
380  if (maxBytes != -1)
381  bytesRead = device->read(buf, qMin<qint64>(sizeof(buf), maxBytes));
382  else
383  bytesRead = device->read(buf, sizeof(buf));
384  }
385 
386  // reset the Text flag.
387  if (textModeEnabled)
388  device->setTextModeEnabled(true);
389 
390  if (bytesRead <= 0)
391  return false;
392 
393  if (autoDetectUnicode) {
394  autoDetectUnicode = false;
395 
397  // QStringConverter::Locale implies unknown, so keep the current encoding
398  if (e) {
399  encoding = *e;
402  }
403  }
404 #if defined (QTEXTSTREAM_DEBUG)
405  qDebug("QTextStreamPrivate::fillReadBuffer(), using %s encoding", QStringConverter::nameForEncoding(encoding));
406 #endif
407 
408 #if defined (QTEXTSTREAM_DEBUG)
409  qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
410  QtDebugUtils::toPrintable(buf, bytesRead, 32).constData(), int(sizeof(buf)), int(bytesRead));
411 #endif
412 
413  int oldReadBufferSize = readBuffer.size();
414  readBuffer += toUtf16(QByteArrayView(buf, bytesRead));
415 
416  // remove all '\r\n' in the string.
417  if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
418  QChar CR = QLatin1Char('\r');
419  QChar *writePtr = readBuffer.data() + oldReadBufferSize;
420  QChar *readPtr = readBuffer.data() + oldReadBufferSize;
421  QChar *endPtr = readBuffer.data() + readBuffer.size();
422 
423  int n = oldReadBufferSize;
424  if (readPtr < endPtr) {
425  // Cut-off to avoid unnecessary self-copying.
426  while (*readPtr++ != CR) {
427  ++n;
428  if (++writePtr == endPtr)
429  break;
430  }
431  }
432  while (readPtr < endPtr) {
433  QChar ch = *readPtr++;
434  if (ch != CR) {
435  *writePtr++ = ch;
436  } else {
437  if (n < readBufferOffset)
439  --bytesRead;
440  }
441  ++n;
442  }
443  readBuffer.resize(writePtr - readBuffer.data());
444  }
445 
446 #if defined (QTEXTSTREAM_DEBUG)
447  qDebug("QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]", int(bytesRead),
448  QtDebugUtils::toPrintable(readBuffer.toLatin1(), readBuffer.size(), readBuffer.size()).constData());
449 #endif
450  return true;
451 }
452 
457 {
458  readBuffer.clear();
459  readBufferOffset = 0;
461 }
462 
467 {
468  // no buffer next to the QString itself; this function should only
469  // be called internally, for devices.
470  if (string || !device)
471  return;
472 
473  // Stream went bye-bye already. Appending further data may succeed again,
474  // but would create a corrupted stream anyway.
475  if (status != QTextStream::Ok)
476  return;
477 
478  if (writeBuffer.isEmpty())
479  return;
480 
481 #if defined (Q_OS_WIN)
482  // handle text translation and bypass the Text flag in the device.
483  bool textModeEnabled = device->isTextModeEnabled();
484  if (textModeEnabled) {
485  device->setTextModeEnabled(false);
486  writeBuffer.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
487  }
488 #endif
489 
491  writeBuffer.clear();
492  hasWrittenData = true;
493 
494  // write raw data to the device
496 #if defined (QTEXTSTREAM_DEBUG)
497  qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
498  QtDebugUtils::toPrintable(data.constData(), data.size(), 32).constData(), int(bytesWritten));
499 #endif
500 
501 #if defined (Q_OS_WIN)
502  // reset the text flag
503  if (textModeEnabled)
504  device->setTextModeEnabled(true);
505 #endif
506 
507  if (bytesWritten <= 0) {
509  return;
510  }
511 
512  // flush the file
513 #ifndef QT_NO_QOBJECT
514  QFileDevice *file = qobject_cast<QFileDevice *>(device);
515  bool flushed = !file || file->flush();
516 #else
517  bool flushed = true;
518 #endif
519 
520 #if defined (QTEXTSTREAM_DEBUG)
521  qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes",
522  int(bytesWritten));
523 #endif
524  if (!flushed || bytesWritten != qint64(data.size()))
526 }
527 
529 {
530  QString ret;
531  if (string) {
532  lastTokenSize = qMin(maxlen, string->size() - stringOffset);
533  ret = string->mid(stringOffset, lastTokenSize);
534  } else {
535  while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) ;
536  lastTokenSize = qMin(maxlen, readBuffer.size() - readBufferOffset);
538  }
540 
541 #if defined (QTEXTSTREAM_DEBUG)
542  qDebug("QTextStreamPrivate::read() maxlen = %d, token length = %d", maxlen, ret.length());
543 #endif
544  return ret;
545 }
546 
554 bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenDelimiter delimiter)
555 {
556  int totalSize = 0;
557  int delimSize = 0;
558  bool consumeDelimiter = false;
559  bool foundToken = false;
560  int startOffset = device ? readBufferOffset : stringOffset;
561  QChar lastChar;
562 
563  do {
564  int endOffset;
565  const QChar *chPtr;
566  if (device) {
567  chPtr = readBuffer.constData();
568  endOffset = readBuffer.size();
569  } else {
570  chPtr = string->constData();
571  endOffset = string->size();
572  }
573  chPtr += startOffset;
574 
575  for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
576  const QChar ch = *chPtr++;
577  ++totalSize;
578 
579  switch (delimiter) {
580  case Space:
581  if (ch.isSpace()) {
582  foundToken = true;
583  delimSize = 1;
584  }
585  break;
586  case NotSpace:
587  if (!ch.isSpace()) {
588  foundToken = true;
589  delimSize = 1;
590  }
591  break;
592  case EndOfLine:
593  if (ch == QLatin1Char('\n')) {
594  foundToken = true;
595  delimSize = (lastChar == QLatin1Char('\r')) ? 2 : 1;
596  consumeDelimiter = true;
597  }
598  lastChar = ch;
599  break;
600  }
601  }
602  } while (!foundToken
603  && (!maxlen || totalSize < maxlen)
604  && device && fillReadBuffer());
605 
606  if (totalSize == 0) {
607 #if defined (QTEXTSTREAM_DEBUG)
608  qDebug("QTextStreamPrivate::scan() reached the end of input.");
609 #endif
610  return false;
611  }
612 
613  // if we find a '\r' at the end of the data when reading lines,
614  // don't make it part of the line.
615  if (delimiter == EndOfLine && totalSize > 0 && !foundToken) {
616  if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
617  && lastChar == QLatin1Char('\r')) {
618  consumeDelimiter = true;
619  ++delimSize;
620  }
621  }
622 
623  // set the read offset and length of the token
624  if (length)
625  *length = totalSize - delimSize;
626  if (ptr)
627  *ptr = readPtr();
628 
629  // update last token size. the callee will call consumeLastToken() when
630  // done.
631  lastTokenSize = totalSize;
632  if (!consumeDelimiter)
633  lastTokenSize -= delimSize;
634 
635 #if defined (QTEXTSTREAM_DEBUG)
636  qDebug("QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
637  ptr, length, maxlen, (int)delimiter, totalSize - delimSize, delimSize);
638 #endif
639  return true;
640 }
641 
645 inline const QChar *QTextStreamPrivate::readPtr() const
646 {
648  if (string)
649  return string->constData() + stringOffset;
650  return readBuffer.constData() + readBufferOffset;
651 }
652 
657 {
658  if (lastTokenSize)
660  lastTokenSize = 0;
661 }
662 
667 {
668 #if defined (QTEXTSTREAM_DEBUG)
669  qDebug("QTextStreamPrivate::consume(%d)", size);
670 #endif
671  if (string) {
672  stringOffset += size;
673  if (stringOffset > string->size())
674  stringOffset = string->size();
675  } else {
677  if (readBufferOffset >= readBuffer.size()) {
678  readBufferOffset = 0;
679  readBuffer.clear();
681  } else if (readBufferOffset > QTEXTSTREAM_BUFFERSIZE) {
684  readBufferOffset = 0;
685  }
686  }
687 }
688 
693 {
694  // ### Hack, FIXME
695  memcpy((void *)&savedToUtf16, (void *)&toUtf16, sizeof(QStringDecoder));
696  readBufferStartDevicePos = newPos;
698 }
699 
704 {
705  if (savedToUtf16.isValid())
706  memcpy((void *)&toUtf16, (void *)&savedToUtf16, sizeof(QStringDecoder));
707  else
710 }
711 
716 {
717  if (string) {
718  // ### What about seek()??
719  string->append(data, len);
720  } else {
721  writeBuffer.append(data, len);
722  if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
724  }
725 }
726 
731 {
732  if (string) {
733  // ### What about seek()??
734  string->append(ch);
735  } else {
736  writeBuffer += ch;
737  if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
739  }
740 }
741 
746 {
747  if (string) {
748  // ### What about seek()??
749  string->append(data);
750  } else {
751  writeBuffer += data;
752  if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
754  }
755 }
756 
761 {
762  if (string) {
763  // ### What about seek()??
764  string->resize(string->size() + len, params.padChar);
765  } else {
766  writeBuffer.resize(writeBuffer.size() + len, params.padChar);
767  if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
769  }
770 }
771 
776 {
777  if ((string && stringOffset == string->size())
778  || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
779  if (ch)
780  *ch = QChar();
781  return false;
782  }
783  if (ch)
784  *ch = *readPtr();
785  consume(1);
786  return true;
787 }
788 
793 {
794  if (string) {
795  if (stringOffset == 0)
796  string->prepend(ch);
797  else
798  (*string)[--stringOffset] = ch;
799  return;
800  }
801 
802  if (readBufferOffset == 0) {
803  readBuffer.prepend(ch);
804  return;
805  }
806 
808 }
809 
814 {
815  if (params.fieldWidth > 0)
816  putString(&ch, 1);
817  else
818  write(ch);
819 }
820 
821 
826 {
827  Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
828 
829  int left = 0, right = 0;
830 
831  const int padSize = params.fieldWidth - len;
832 
833  switch (params.fieldAlignment) {
835  right = padSize;
836  break;
839  left = padSize;
840  break;
842  left = padSize/2;
843  right = padSize - padSize/2;
844  break;
845  }
846  return { left, right };
847 }
848 
853 {
854  if (Q_UNLIKELY(params.fieldWidth > len)) {
855 
856  // handle padding:
857 
858  const PaddingResult pad = padding(len);
859 
860  if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
861  const QChar sign = len > 0 ? data[0] : QChar();
862  if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
863  // write the sign before the padding, then skip it later
864  write(&sign, 1);
865  ++data;
866  --len;
867  }
868  }
869 
870  writePadding(pad.left);
871  write(data, len);
872  writePadding(pad.right);
873  } else {
874  write(data, len);
875  }
876 }
877 
882 {
883  if (Q_UNLIKELY(params.fieldWidth > data.size())) {
884 
885  // handle padding
886 
887  const PaddingResult pad = padding(data.size());
888 
889  if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
890  const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
891  if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
892  // write the sign before the padding, then skip it later
893  write(&sign, 1);
894  data = QLatin1String(data.data() + 1, data.size() - 1);
895  }
896  }
897 
898  writePadding(pad.left);
899  write(data);
900  writePadding(pad.right);
901  } else {
902  write(data);
903  }
904 }
905 
907 {
908  putString(data.toString(), number);
909 }
910 
918  : d_ptr(new QTextStreamPrivate(this))
919 {
920 #if defined (QTEXTSTREAM_DEBUG)
921  qDebug("QTextStream::QTextStream()");
922 #endif
923  Q_D(QTextStream);
924  d->status = Ok;
925 }
926 
931  : d_ptr(new QTextStreamPrivate(this))
932 {
933 #if defined (QTEXTSTREAM_DEBUG)
934  qDebug("QTextStream::QTextStream(QIODevice *device == *%p)",
935  device);
936 #endif
937  Q_D(QTextStream);
938  d->device = device;
939 #ifndef QT_NO_QOBJECT
940  d->deviceClosedNotifier.setupDevice(this, d->device);
941 #endif
942  d->status = Ok;
943 }
944 
949 QTextStream::QTextStream(QString *string, OpenMode openMode)
950  : d_ptr(new QTextStreamPrivate(this))
951 {
952 #if defined (QTEXTSTREAM_DEBUG)
953  qDebug("QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
954  string, int(openMode));
955 #endif
956  Q_D(QTextStream);
957  d->string = string;
958  d->stringOpenMode = openMode;
959  d->status = Ok;
960 }
961 
968  : d_ptr(new QTextStreamPrivate(this))
969 {
970 #if defined (QTEXTSTREAM_DEBUG)
971  qDebug("QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
972  array, int(openMode));
973 #endif
974  Q_D(QTextStream);
975  d->device = new QBuffer(array);
976  d->device->open(openMode);
977  d->deleteDevice = true;
978 #ifndef QT_NO_QOBJECT
979  d->deviceClosedNotifier.setupDevice(this, d->device);
980 #endif
981  d->status = Ok;
982 }
983 
994 QTextStream::QTextStream(const QByteArray &array, OpenMode openMode)
995  : d_ptr(new QTextStreamPrivate(this))
996 {
997 #if defined (QTEXTSTREAM_DEBUG)
998  qDebug("QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
999  &array, int(openMode));
1000 #endif
1001  QBuffer *buffer = new QBuffer;
1002  buffer->setData(array);
1003  buffer->open(openMode);
1004 
1005  Q_D(QTextStream);
1006  d->device = buffer;
1007  d->deleteDevice = true;
1008 #ifndef QT_NO_QOBJECT
1009  d->deviceClosedNotifier.setupDevice(this, d->device);
1010 #endif
1011  d->status = Ok;
1012 }
1013 
1025 QTextStream::QTextStream(FILE *fileHandle, OpenMode openMode)
1026  : d_ptr(new QTextStreamPrivate(this))
1027 {
1028 #if defined (QTEXTSTREAM_DEBUG)
1029  qDebug("QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
1030  fileHandle, int(openMode));
1031 #endif
1032  QFile *file = new QFile;
1033  file->open(fileHandle, openMode);
1034 
1035  Q_D(QTextStream);
1036  d->device = file;
1037  d->deleteDevice = true;
1038 #ifndef QT_NO_QOBJECT
1039  d->deviceClosedNotifier.setupDevice(this, d->device);
1040 #endif
1041  d->status = Ok;
1042 }
1043 
1051 {
1052  Q_D(QTextStream);
1053 #if defined (QTEXTSTREAM_DEBUG)
1054  qDebug("QTextStream::~QTextStream()");
1055 #endif
1056  if (!d->writeBuffer.isEmpty())
1057  d->flushWriteBuffer();
1058 }
1059 
1066 {
1067  Q_D(QTextStream);
1068 
1069  d->params.reset();
1070 }
1071 
1078 {
1079  Q_D(QTextStream);
1080  d->flushWriteBuffer();
1081 }
1082 
1088 {
1089  Q_D(QTextStream);
1090  d->lastTokenSize = 0;
1091 
1092  if (d->device) {
1093  // Empty the write buffer
1094  d->flushWriteBuffer();
1095  if (!d->device->seek(pos))
1096  return false;
1097  d->resetReadBuffer();
1098 
1099  d->toUtf16.resetState();
1100  d->fromUtf16.resetState();
1101  return true;
1102  }
1103 
1104  // string
1105  if (d->string && pos <= d->string->size()) {
1106  d->stringOffset = int(pos);
1107  return true;
1108  }
1109  return false;
1110 }
1111 
1127 {
1128  Q_D(const QTextStream);
1129  if (d->device) {
1130  // Cutoff
1131  if (d->readBuffer.isEmpty())
1132  return d->device->pos();
1133  if (d->device->isSequential())
1134  return 0;
1135 
1136  // Seek the device
1137  if (!d->device->seek(d->readBufferStartDevicePos))
1138  return qint64(-1);
1139 
1140  // Reset the read buffer
1141  QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
1142  thatd->readBuffer.clear();
1143 
1145  if (d->readBufferStartDevicePos == 0)
1146  thatd->autoDetectUnicode = true;
1147 
1148  // Rewind the device to get to the current position Ensure that
1149  // readBufferOffset is unaffected by fillReadBuffer()
1150  int oldReadBufferOffset = d->readBufferOffset + d->readConverterSavedStateOffset;
1151  while (d->readBuffer.size() < oldReadBufferOffset) {
1152  if (!thatd->fillReadBuffer(1))
1153  return qint64(-1);
1154  }
1155  thatd->readBufferOffset = oldReadBufferOffset;
1156  thatd->readConverterSavedStateOffset = 0;
1157 
1158  // Return the device position.
1159  return d->device->pos();
1160  }
1161 
1162  if (d->string)
1163  return d->stringOffset;
1164 
1165  qWarning("QTextStream::pos: no device");
1166  return qint64(-1);
1167 }
1168 
1181 {
1182  Q_D(QTextStream);
1184  d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1185  d->consumeLastToken();
1186 }
1187 
1199 {
1200  Q_D(QTextStream);
1201  flush();
1202  if (d->deleteDevice) {
1203 #ifndef QT_NO_QOBJECT
1204  d->deviceClosedNotifier.disconnect();
1205 #endif
1206  delete d->device;
1207  d->deleteDevice = false;
1208  }
1209 
1210  d->reset();
1211  d->status = Ok;
1212  d->device = device;
1213  d->resetReadBuffer();
1214 #ifndef QT_NO_QOBJECT
1215  d->deviceClosedNotifier.setupDevice(this, d->device);
1216 #endif
1217 }
1218 
1226 {
1227  Q_D(const QTextStream);
1228  return d->device;
1229 }
1230 
1238 void QTextStream::setString(QString *string, OpenMode openMode)
1239 {
1240  Q_D(QTextStream);
1241  flush();
1242  if (d->deleteDevice) {
1243 #ifndef QT_NO_QOBJECT
1244  d->deviceClosedNotifier.disconnect();
1245  d->device->blockSignals(true);
1246 #endif
1247  delete d->device;
1248  d->deleteDevice = false;
1249  }
1250 
1251  d->reset();
1252  d->status = Ok;
1253  d->string = string;
1254  d->stringOpenMode = openMode;
1255 }
1256 
1264 {
1265  Q_D(const QTextStream);
1266  return d->string;
1267 }
1268 
1278 {
1279  Q_D(QTextStream);
1280  d->params.fieldAlignment = mode;
1281 }
1282 
1289 {
1290  Q_D(const QTextStream);
1291  return d->params.fieldAlignment;
1292 }
1293 
1310 {
1311  Q_D(QTextStream);
1312  d->params.padChar = ch;
1313 }
1314 
1321 {
1322  Q_D(const QTextStream);
1323  return d->params.padChar;
1324 }
1325 
1339 {
1340  Q_D(QTextStream);
1341  d->params.fieldWidth = width;
1342 }
1343 
1350 {
1351  Q_D(const QTextStream);
1352  return d->params.fieldWidth;
1353 }
1354 
1364 {
1365  Q_D(QTextStream);
1366  d->params.numberFlags = flags;
1367 }
1368 
1374 QTextStream::NumberFlags QTextStream::numberFlags() const
1375 {
1376  Q_D(const QTextStream);
1377  return d->params.numberFlags;
1378 }
1379 
1391 {
1392  Q_D(QTextStream);
1393  d->params.integerBase = base;
1394 }
1395 
1403 {
1404  Q_D(const QTextStream);
1405  return d->params.integerBase;
1406 }
1407 
1417 {
1418  Q_D(QTextStream);
1419  d->params.realNumberNotation = notation;
1420 }
1421 
1428 {
1429  Q_D(const QTextStream);
1430  return d->params.realNumberNotation;
1431 }
1432 
1443 {
1444  Q_D(QTextStream);
1445  if (precision < 0) {
1446  qWarning("QTextStream::setRealNumberPrecision: Invalid precision (%d)", precision);
1447  d->params.realNumberPrecision = 6;
1448  return;
1449  }
1450  d->params.realNumberPrecision = precision;
1451 }
1452 
1460 {
1461  Q_D(const QTextStream);
1462  return d->params.realNumberPrecision;
1463 }
1464 
1472 {
1473  Q_D(const QTextStream);
1474  return d->status;
1475 }
1476 
1485 {
1486  Q_D(QTextStream);
1487  d->status = Ok;
1488 }
1489 
1501 {
1502  Q_D(QTextStream);
1503  if (d->status == Ok)
1504  d->status = status;
1505 }
1506 
1514 {
1515  Q_D(const QTextStream);
1516  CHECK_VALID_STREAM(true);
1517 
1518  if (d->string)
1519  return d->string->size() == d->stringOffset;
1520  return d->readBuffer.isEmpty() && d->device->atEnd();
1521 }
1522 
1534 {
1535  Q_D(QTextStream);
1537 
1538  return d->read(INT_MAX);
1539 }
1540 
1559 {
1560  QString line;
1561 
1562  readLineInto(&line, maxlen);
1563  return line;
1564 }
1565 
1592 {
1593  Q_D(QTextStream);
1594  // keep in sync with CHECK_VALID_STREAM
1595  if (!d->string && !d->device) {
1596  qWarning("QTextStream: No device");
1597  if (line && !line->isNull())
1598  line->resize(0);
1599  return false;
1600  }
1601 
1602  const QChar *readPtr;
1603  int length;
1604  if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) {
1605  if (line && !line->isNull())
1606  line->resize(0);
1607  return false;
1608  }
1609 
1610  if (Q_LIKELY(line))
1611  line->setUnicode(readPtr, length);
1612  d->consumeLastToken();
1613  return true;
1614 }
1615 
1625 {
1626  Q_D(QTextStream);
1628 
1629  if (maxlen <= 0)
1630  return QString::fromLatin1(""); // empty, not null
1631 
1632  return d->read(int(maxlen));
1633 }
1634 
1639 {
1640  scan(nullptr, nullptr, 0, NotSpace);
1641  consumeLastToken();
1642 
1643  // detect int encoding
1644  int base = params.integerBase;
1645  if (base == 0) {
1646  QChar ch;
1647  if (!getChar(&ch))
1648  return npsInvalidPrefix;
1649  if (ch == QLatin1Char('0')) {
1650  QChar ch2;
1651  if (!getChar(&ch2)) {
1652  // Result is the number 0
1653  *ret = 0;
1654  return npsOk;
1655  }
1656  ch2 = ch2.toLower();
1657 
1658  if (ch2 == QLatin1Char('x')) {
1659  base = 16;
1660  } else if (ch2 == QLatin1Char('b')) {
1661  base = 2;
1662  } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
1663  base = 8;
1664  } else {
1665  base = 10;
1666  }
1667  ungetChar(ch2);
1668  } else if (ch == locale.negativeSign() || ch == locale.positiveSign() || ch.isDigit()) {
1669  base = 10;
1670  } else {
1671  ungetChar(ch);
1672  return npsInvalidPrefix;
1673  }
1674  ungetChar(ch);
1675  // State of the stream is now the same as on entry
1676  // (cursor is at prefix),
1677  // and local variable 'base' has been set appropriately.
1678  }
1679 
1680  qulonglong val=0;
1681  switch (base) {
1682  case 2: {
1683  QChar pf1, pf2, dig;
1684  // Parse prefix '0b'
1685  if (!getChar(&pf1) || pf1 != QLatin1Char('0'))
1686  return npsInvalidPrefix;
1687  if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('b'))
1688  return npsInvalidPrefix;
1689  // Parse digits
1690  int ndigits = 0;
1691  while (getChar(&dig)) {
1692  int n = dig.toLower().unicode();
1693  if (n == '0' || n == '1') {
1694  val <<= 1;
1695  val += n - '0';
1696  } else {
1697  ungetChar(dig);
1698  break;
1699  }
1700  ndigits++;
1701  }
1702  if (ndigits == 0) {
1703  // Unwind the prefix and abort
1704  ungetChar(pf2);
1705  ungetChar(pf1);
1706  return npsMissingDigit;
1707  }
1708  break;
1709  }
1710  case 8: {
1711  QChar pf, dig;
1712  // Parse prefix '0'
1713  if (!getChar(&pf) || pf != QLatin1Char('0'))
1714  return npsInvalidPrefix;
1715  // Parse digits
1716  int ndigits = 0;
1717  while (getChar(&dig)) {
1718  int n = dig.toLower().unicode();
1719  if (n >= '0' && n <= '7') {
1720  val *= 8;
1721  val += n - '0';
1722  } else {
1723  ungetChar(dig);
1724  break;
1725  }
1726  ndigits++;
1727  }
1728  if (ndigits == 0) {
1729  // Unwind the prefix and abort
1730  ungetChar(pf);
1731  return npsMissingDigit;
1732  }
1733  break;
1734  }
1735  case 10: {
1736  // Parse sign (or first digit)
1737  QChar sign;
1738  int ndigits = 0;
1739  if (!getChar(&sign))
1740  return npsMissingDigit;
1741  if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1742  if (!sign.isDigit()) {
1743  ungetChar(sign);
1744  return npsMissingDigit;
1745  }
1746  val += sign.digitValue();
1747  ndigits++;
1748  }
1749  // Parse digits
1750  QChar ch;
1751  while (getChar(&ch)) {
1752  if (ch.isDigit()) {
1753  val *= 10;
1754  val += ch.digitValue();
1755  } else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
1756  continue;
1757  } else {
1758  ungetChar(ch);
1759  break;
1760  }
1761  ndigits++;
1762  }
1763  if (ndigits == 0)
1764  return npsMissingDigit;
1765  if (sign == locale.negativeSign()) {
1766  qlonglong ival = qlonglong(val);
1767  if (ival > 0)
1768  ival = -ival;
1769  val = qulonglong(ival);
1770  }
1771  break;
1772  }
1773  case 16: {
1774  QChar pf1, pf2, dig;
1775  // Parse prefix ' 0x'
1776  if (!getChar(&pf1) || pf1 != QLatin1Char('0'))
1777  return npsInvalidPrefix;
1778  if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('x'))
1779  return npsInvalidPrefix;
1780  // Parse digits
1781  int ndigits = 0;
1782  while (getChar(&dig)) {
1783  int n = dig.toLower().unicode();
1784  if (n >= '0' && n <= '9') {
1785  val <<= 4;
1786  val += n - '0';
1787  } else if (n >= 'a' && n <= 'f') {
1788  val <<= 4;
1789  val += 10 + (n - 'a');
1790  } else {
1791  ungetChar(dig);
1792  break;
1793  }
1794  ndigits++;
1795  }
1796  if (ndigits == 0) {
1797  return npsMissingDigit;
1798  }
1799  break;
1800  }
1801  default:
1802  // Unsupported integerBase
1803  return npsInvalidPrefix;
1804  }
1805 
1806  if (ret)
1807  *ret = val;
1808  return npsOk;
1809 }
1810 
1816 {
1817  // We use a table-driven FSM to parse floating point numbers
1818  // strtod() cannot be used directly since we may be reading from a
1819  // QIODevice.
1820  enum ParserState {
1821  Init = 0,
1822  Sign = 1,
1823  Mantissa = 2,
1824  Dot = 3,
1825  Abscissa = 4,
1826  ExpMark = 5,
1827  ExpSign = 6,
1828  Exponent = 7,
1829  Nan1 = 8,
1830  Nan2 = 9,
1831  Inf1 = 10,
1832  Inf2 = 11,
1833  NanInf = 12,
1834  Done = 13
1835  };
1836  enum InputToken {
1837  None = 0,
1838  InputSign = 1,
1839  InputDigit = 2,
1840  InputDot = 3,
1841  InputExp = 4,
1842  InputI = 5,
1843  InputN = 6,
1844  InputF = 7,
1845  InputA = 8,
1846  InputT = 9
1847  };
1848 
1849  static const uchar table[13][10] = {
1850  // None InputSign InputDigit InputDot InputExp InputI InputN InputF InputA InputT
1851  { 0, Sign, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 0 Init
1852  { 0, 0, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 1 Sign
1853  { Done, Done, Mantissa, Dot, ExpMark, 0, 0, 0, 0, 0 }, // 2 Mantissa
1854  { 0, 0, Abscissa, 0, 0, 0, 0, 0, 0, 0 }, // 3 Dot
1855  { Done, Done, Abscissa, Done, ExpMark, 0, 0, 0, 0, 0 }, // 4 Abscissa
1856  { 0, ExpSign, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 5 ExpMark
1857  { 0, 0, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 6 ExpSign
1858  { Done, Done, Exponent, Done, Done, 0, 0, 0, 0, 0 }, // 7 Exponent
1859  { 0, 0, 0, 0, 0, 0, 0, 0, Nan2, 0 }, // 8 Nan1
1860  { 0, 0, 0, 0, 0, 0, NanInf, 0, 0, 0 }, // 9 Nan2
1861  { 0, 0, 0, 0, 0, 0, Inf2, 0, 0, 0 }, // 10 Inf1
1862  { 0, 0, 0, 0, 0, 0, 0, NanInf, 0, 0 }, // 11 Inf2
1863  { Done, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 11 NanInf
1864  };
1865 
1866  ParserState state = Init;
1867  InputToken input = None;
1868 
1869  scan(nullptr, nullptr, 0, NotSpace);
1870  consumeLastToken();
1871 
1872  const int BufferSize = 128;
1873  char buf[BufferSize];
1874  int i = 0;
1875 
1876  QChar c;
1877  while (getChar(&c)) {
1878  switch (c.unicode()) {
1879  case '0': case '1': case '2': case '3': case '4':
1880  case '5': case '6': case '7': case '8': case '9':
1881  input = InputDigit;
1882  break;
1883  case 'i': case 'I':
1884  input = InputI;
1885  break;
1886  case 'n': case 'N':
1887  input = InputN;
1888  break;
1889  case 'f': case 'F':
1890  input = InputF;
1891  break;
1892  case 'a': case 'A':
1893  input = InputA;
1894  break;
1895  case 't': case 'T':
1896  input = InputT;
1897  break;
1898  default: {
1899  QChar lc = c.toLower();
1900  if (lc == locale.decimalPoint().toLower())
1901  input = InputDot;
1902  else if (lc == locale.exponential().toLower())
1903  input = InputExp;
1904  else if (lc == locale.negativeSign().toLower()
1905  || lc == locale.positiveSign().toLower())
1906  input = InputSign;
1907  else if (locale != QLocale::c() // backward-compatibility
1908  && lc == locale.groupSeparator().toLower())
1909  input = InputDigit; // well, it isn't a digit, but no one cares.
1910  else
1911  input = None;
1912  }
1913  break;
1914  }
1915 
1916  state = ParserState(table[state][input]);
1917 
1918  if (state == Init || state == Done || i > (BufferSize - 5)) {
1919  ungetChar(c);
1920  if (i > (BufferSize - 5)) { // ignore rest of digits
1921  while (getChar(&c)) {
1922  if (!c.isDigit()) {
1923  ungetChar(c);
1924  break;
1925  }
1926  }
1927  }
1928  break;
1929  }
1930 
1931  buf[i++] = c.toLatin1();
1932  }
1933 
1934  if (i == 0)
1935  return false;
1936  if (!f)
1937  return true;
1938  buf[i] = '\0';
1939 
1940  // backward-compatibility. Old implementation supported +nan/-nan
1941  // for some reason. QLocale only checks for lower-case
1942  // nan/+inf/-inf, so here we also check for uppercase and mixed
1943  // case versions.
1944  if (!qstricmp(buf, "nan") || !qstricmp(buf, "+nan") || !qstricmp(buf, "-nan")) {
1945  *f = qQNaN();
1946  return true;
1947  } else if (!qstricmp(buf, "+inf") || !qstricmp(buf, "inf")) {
1948  *f = qInf();
1949  return true;
1950  } else if (!qstricmp(buf, "-inf")) {
1951  *f = -qInf();
1952  return true;
1953  }
1954  bool ok;
1956  return ok;
1957 }
1958 
1970 {
1971  Q_D(QTextStream);
1972  CHECK_VALID_STREAM(*this);
1973  d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1974  if (!d->getChar(&c))
1976  return *this;
1977 }
1978 
1989 {
1990  QChar ch;
1991  *this >> ch;
1992  c = ch.toLatin1();
1993  return *this;
1994 }
1995 
2021 {
2023 }
2024 
2031 {
2032  IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned short);
2033 }
2034 
2041 {
2043 }
2044 
2051 {
2053 }
2054 
2061 {
2063 }
2064 
2071 {
2072  IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned long);
2073 }
2074 
2081 {
2083 }
2084 
2091 {
2093 }
2094 
2107 {
2109 }
2110 
2117 {
2119 }
2120 
2129 {
2130  Q_D(QTextStream);
2131  CHECK_VALID_STREAM(*this);
2132 
2133  str.clear();
2134  d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2135  d->consumeLastToken();
2136 
2137  const QChar *ptr;
2138  int length;
2139  if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2141  return *this;
2142  }
2143 
2144  str = QString(ptr, length);
2145  d->consumeLastToken();
2146  return *this;
2147 }
2148 
2157 {
2158  Q_D(QTextStream);
2159  CHECK_VALID_STREAM(*this);
2160 
2161  d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2162  d->consumeLastToken();
2163 
2164  const QChar *ptr;
2165  int length;
2166  if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2168  array.clear();
2169  return *this;
2170  }
2171 
2172  array = QStringView(ptr, length).toUtf8();
2173 
2174  d->consumeLastToken();
2175  return *this;
2176 }
2177 
2193 {
2194  Q_D(QTextStream);
2195  *c = 0;
2196  CHECK_VALID_STREAM(*this);
2197  d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2198  d->consumeLastToken();
2199 
2200  const QChar *ptr;
2201  int length;
2202  if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2204  return *this;
2205  }
2206 
2208  char *e = encoder.appendToBuffer(c, QStringView(ptr, length));
2209  *e = '\0';
2210  d->consumeLastToken();
2211  return *this;
2212 }
2213 
2218 {
2219  QString result;
2220 
2221  unsigned flags = 0;
2222  const QTextStream::NumberFlags numberFlags = params.numberFlags;
2223  if (numberFlags & QTextStream::ShowBase)
2225  if (numberFlags & QTextStream::ForceSign)
2227  if (numberFlags & QTextStream::UppercaseBase)
2229  if (numberFlags & QTextStream::UppercaseDigits)
2231 
2232  // add thousands group separators. For backward compatibility we
2233  // don't add a group separator for C locale.
2236 
2237  const QLocaleData *dd = locale.d->m_data;
2238  int base = params.integerBase ? params.integerBase : 10;
2239  if (negative && base == 10) {
2240  result = dd->longLongToString(-static_cast<qlonglong>(number), -1,
2241  base, -1, flags);
2242  } else if (negative) {
2243  // Workaround for backward compatibility for writing negative
2244  // numbers in octal and hex:
2245  // QTextStream(result) << Qt::showbase << Qt::hex << -1 << oct << -1
2246  // should output: -0x1 -0b1
2247  result = dd->unsLongLongToString(number, -1, base, -1, flags);
2249  } else {
2250  result = dd->unsLongLongToString(number, -1, base, -1, flags);
2251  // workaround for backward compatibility - in octal form with
2252  // ShowBase flag set zero should be written as '00'
2253  if (number == 0 && base == 8 && params.numberFlags & QTextStream::ShowBase
2254  && result == QLatin1String("0")) {
2255  result.prepend(QLatin1Char('0'));
2256  }
2257  }
2258  putString(result, true);
2259 }
2260 
2268 {
2269  Q_D(QTextStream);
2270  CHECK_VALID_STREAM(*this);
2271  d->putChar(c);
2272  return *this;
2273 }
2274 
2281 {
2282  Q_D(QTextStream);
2283  CHECK_VALID_STREAM(*this);
2284  d->putChar(QChar::fromLatin1(c));
2285  return *this;
2286 }
2287 
2306 {
2307  Q_D(QTextStream);
2308  CHECK_VALID_STREAM(*this);
2309  d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2310  return *this;
2311 }
2312 
2319 {
2320  Q_D(QTextStream);
2321  CHECK_VALID_STREAM(*this);
2322  d->putNumber((qulonglong)i, false);
2323  return *this;
2324 }
2325 
2332 {
2333  Q_D(QTextStream);
2334  CHECK_VALID_STREAM(*this);
2335  d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2336  return *this;
2337 }
2338 
2345 {
2346  Q_D(QTextStream);
2347  CHECK_VALID_STREAM(*this);
2348  d->putNumber((qulonglong)i, false);
2349  return *this;
2350 }
2351 
2358 {
2359  Q_D(QTextStream);
2360  CHECK_VALID_STREAM(*this);
2361  d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2362  return *this;
2363 }
2364 
2371 {
2372  Q_D(QTextStream);
2373  CHECK_VALID_STREAM(*this);
2374  d->putNumber((qulonglong)i, false);
2375  return *this;
2376 }
2377 
2384 {
2385  Q_D(QTextStream);
2386  CHECK_VALID_STREAM(*this);
2387  d->putNumber((qulonglong)qAbs(i), i < 0);
2388  return *this;
2389 }
2390 
2397 {
2398  Q_D(QTextStream);
2399  CHECK_VALID_STREAM(*this);
2400  d->putNumber(i, false);
2401  return *this;
2402 }
2403 
2416 {
2417  return *this << double(f);
2418 }
2419 
2426 {
2427  Q_D(QTextStream);
2428  CHECK_VALID_STREAM(*this);
2429 
2431  switch (realNumberNotation()) {
2432  case FixedNotation:
2434  break;
2435  case ScientificNotation:
2437  break;
2438  case SmartNotation:
2440  break;
2441  }
2442 
2443  uint flags = 0;
2444  const QLocale::NumberOptions numberOptions = locale().numberOptions();
2445  if (numberFlags() & ShowBase)
2447  if (numberFlags() & ForceSign)
2449  if (numberFlags() & UppercaseBase)
2451  if (numberFlags() & UppercaseDigits)
2453  if (numberFlags() & ForcePoint) {
2455 
2456  // Only for backwards compatibility
2458  }
2459  if (locale() != QLocale::c() && !(numberOptions & QLocale::OmitGroupSeparator))
2461  if (!(numberOptions & QLocale::OmitLeadingZeroInExponent))
2463  if (numberOptions & QLocale::IncludeTrailingZeroesAfterDot)
2465 
2466  const QLocaleData *dd = d->locale.d->m_data;
2467  QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
2468  d->putString(num, true);
2469  return *this;
2470 }
2471 
2480 {
2481  Q_D(QTextStream);
2482  CHECK_VALID_STREAM(*this);
2483  d->putString(string);
2484  return *this;
2485 }
2486 
2495 {
2496  Q_D(QTextStream);
2497  CHECK_VALID_STREAM(*this);
2498  d->putString(string.cbegin(), int(string.size()));
2499  return *this;
2500 }
2501 
2509 {
2510  Q_D(QTextStream);
2511  CHECK_VALID_STREAM(*this);
2512  d->putString(string);
2513  return *this;
2514 }
2515 
2523 {
2524  Q_D(QTextStream);
2525  CHECK_VALID_STREAM(*this);
2526  d->putString(QString::fromUtf8(array.constData(), array.length()));
2527  return *this;
2528 }
2529 
2544 {
2545  Q_D(QTextStream);
2546  CHECK_VALID_STREAM(*this);
2547  d->putString(QUtf8StringView(string));
2548  return *this;
2549 }
2550 
2558 {
2559  Q_D(QTextStream);
2560  CHECK_VALID_STREAM(*this);
2561  const int oldBase = d->params.integerBase;
2562  const NumberFlags oldFlags = d->params.numberFlags;
2563  d->params.integerBase = 16;
2564  d->params.numberFlags |= ShowBase;
2565  d->putNumber(reinterpret_cast<quintptr>(ptr), false);
2566  d->params.integerBase = oldBase;
2567  d->params.numberFlags = oldFlags;
2568  return *this;
2569 }
2570 
2571 namespace Qt {
2572 
2582 {
2584  return stream;
2585 }
2586 
2596 {
2598  return stream;
2599 }
2600 
2610 {
2611  stream.setIntegerBase(10);
2612  return stream;
2613 }
2614 
2625 {
2626  stream.setIntegerBase(16);
2627  return stream;
2628 }
2629 
2639 {
2641  return stream;
2642 }
2643 
2653 {
2655  return stream;
2656 }
2657 
2667 {
2669  return stream;
2670 }
2671 
2681 {
2683  return stream;
2684 }
2685 
2695 {
2697  return stream;
2698 }
2699 
2709 {
2711  return stream;
2712 }
2713 
2723 {
2725  return stream;
2726 }
2727 
2737 {
2739  return stream;
2740 }
2741 
2751 {
2753  return stream;
2754 }
2755 
2765 {
2767  return stream;
2768 }
2769 
2779 {
2781  return stream;
2782 }
2783 
2793 {
2795  return stream;
2796 }
2797 
2807 {
2809  return stream;
2810 }
2811 
2821 {
2823  return stream;
2824 }
2825 
2835 {
2837  return stream;
2838 }
2839 
2855 {
2856  return stream << QLatin1Char('\n') << Qt::flush;
2857 }
2858 
2867 {
2868  stream.flush();
2869  return stream;
2870 }
2871 
2880 {
2881  stream.reset();
2882  return stream;
2883 }
2884 
2893 {
2895  return stream;
2896 }
2897 
2898 } // namespace Qt
2899 
2922 namespace Qt {
2932 {
2934  return stream;
2935 }
2936 
2937 } // namespace Qt
2938 
2939 
2956 {
2957  Q_D(QTextStream);
2958  if (d->encoding == encoding)
2959  return;
2960 
2961  qint64 seekPos = -1;
2962  if (!d->readBuffer.isEmpty()) {
2963  if (!d->device->isSequential()) {
2964  seekPos = pos();
2965  }
2966  }
2967 
2968  d->encoding = encoding;
2969  d->toUtf16 = QStringDecoder(d->encoding);
2970  bool generateBOM = d->hasWrittenData && d->generateBOM;
2971  d->fromUtf16 = QStringEncoder(d->encoding,
2973 
2974  if (seekPos >=0 && !d->readBuffer.isEmpty())
2975  seek(seekPos);
2976 }
2977 
2984 {
2985  Q_D(const QTextStream);
2986  return d->encoding;
2987 }
2988 
3001 {
3002  Q_D(QTextStream);
3003  d->autoDetectUnicode = enabled;
3004 }
3005 
3013 {
3014  Q_D(const QTextStream);
3015  return d->autoDetectUnicode;
3016 }
3017 
3027 {
3028  Q_D(QTextStream);
3029  if (d->hasWrittenData || d->generateBOM == generate)
3030  return;
3031 
3032  d->generateBOM = generate;
3034 }
3035 
3044 {
3045  Q_D(const QTextStream);
3046  return d->generateBOM;
3047 }
3048 
3060 void QTextStream::setLocale(const QLocale &locale)
3061 {
3062  Q_D(QTextStream);
3063  d->locale = locale;
3064 }
3065 
3074 {
3075  Q_D(const QTextStream);
3076  return d->locale;
3077 }
3078 
3080 
3081 #ifndef QT_NO_QOBJECT
3082 #include "moc_qtextstream_p.cpp"
3083 #endif
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:52
void setData(const QByteArray &data)
Definition: qbuffer.cpp:295
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const char * constData() const noexcept
Definition: qbytearray.h:144
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
constexpr bool isDigit() const noexcept
Definition: qchar.h:504
QChar toLower() const noexcept
Definition: qchar.h:479
int digitValue() const noexcept
Definition: qchar.h:478
constexpr char16_t unicode() const noexcept
Definition: qchar.h:489
static constexpr QChar fromLatin1(char c) noexcept
Definition: qchar.h:492
The QFileDevice class provides an interface for reading from and writing to open files.
Definition: qfiledevice.h:52
int handle() const
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:94
bool open(OpenMode flags) override
Definition: qfile.cpp:897
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:70
virtual qint64 pos() const
Definition: qiodevice.cpp:856
virtual bool isSequential() const
Definition: qiodevice.cpp:527
qint64 readLine(char *data, qint64 maxlen)
Definition: qiodevice.cpp:1356
void setTextModeEnabled(bool enabled)
Definition: qiodevice.cpp:571
qint64 write(const char *data, qint64 len)
Definition: qiodevice.cpp:1681
virtual bool atEnd() const
Definition: qiodevice.cpp:952
bool isTextModeEnabled() const
Definition: qiodevice.cpp:589
qint64 read(char *data, qint64 maxlen)
Definition: qiodevice.cpp:1030
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
QString decimalPoint() const
Definition: qlocale.cpp:2549
double toDouble(const QString &s, bool *ok=nullptr) const
Definition: qlocale.h:979
QString negativeSign() const
Definition: qlocale.cpp:2597
QString groupSeparator() const
Definition: qlocale.cpp:2561
static QLocale c()
Definition: qlocale.h:1134
QString exponential() const
Definition: qlocale.cpp:2622
QString positiveSign() const
Definition: qlocale.cpp:2609
NumberOptions numberOptions() const
Definition: qlocale.cpp:1169
@ OmitGroupSeparator
Definition: qlocale.h:897
@ IncludeTrailingZeroesAfterDot
Definition: qlocale.h:901
@ OmitLeadingZeroInExponent
Definition: qlocale.h:899
const QLocaleData *const m_data
Definition: qlocale_p.h:446
bool blockSignals(bool b) noexcept
Definition: qobject.cpp:1514
static Q_CORE_EXPORT const char * nameForEncoding(Encoding e)
bool isValid() const
static Q_CORE_EXPORT std::optional< Encoding > encodingForData(QByteArrayView data, char16_t expectedFirstCharacter=0)
The QStringDecoder class provides a state-based decoder for text. \reentrant.
The QStringEncoder class provides a state-based encoder for text. \reentrant.
char * appendToBuffer(char *out, QStringView in)
The QString class provides a Unicode character string.
Definition: qstring.h:388
QString & prepend(QChar c)
Definition: qstring.h:656
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
void clear()
Definition: qstring.h:1240
bool isNull() const
Definition: qstring.h:1078
QString & setUnicode(const QChar *unicode, qsizetype size)
Definition: qstring.cpp:5713
static QString fromUtf8(QByteArrayView utf8)
Definition: qstring.cpp:5632
QString toLower() const &
Definition: qstring.h:611
void resize(qsizetype size)
Definition: qstring.cpp:2670
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
QByteArray toUtf8() const
Definition: qstringview.h:255
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:62
void setStatus(Status status)
bool atEnd() const
void skipWhiteSpace()
QTextStream & operator>>(QChar &ch)
bool autoDetectUnicode() const
QString readAll()
void setRealNumberPrecision(int precision)
QChar padChar() const
QString read(qint64 maxlen)
void setRealNumberNotation(RealNumberNotation notation)
int realNumberPrecision() const
void setEncoding(QStringConverter::Encoding encoding)
void setPadChar(QChar ch)
QIODevice * device() const
void setGenerateByteOrderMark(bool generate)
bool seek(qint64 pos)
FieldAlignment fieldAlignment() const
NumberFlags numberFlags() const
virtual ~QTextStream()
QLocale locale() const
QString readLine(qint64 maxlen=0)
void setString(QString *string, OpenMode openMode=ReadWrite)
QString * string() const
bool readLineInto(QString *line, qint64 maxlen=0)
int integerBase() const
void setIntegerBase(int base)
RealNumberNotation realNumberNotation() const
void setFieldAlignment(FieldAlignment alignment)
bool generateByteOrderMark() const
void setAutoDetectUnicode(bool enabled)
Status status() const
void setFieldWidth(int width)
QStringConverter::Encoding encoding() const
@ ScientificNotation
Definition: qtextstream.h:69
qint64 pos() const
QTextStream & operator<<(QChar ch)
int fieldWidth() const
void setNumberFlags(NumberFlags flags)
void setLocale(const QLocale &locale)
@ AlignAccountingStyle
Definition: qtextstream.h:75
void resetStatus()
void setDevice(QIODevice *device)
QTextStream::FieldAlignment fieldAlignment
QTextStream::RealNumberNotation realNumberNotation
QTextStream::NumberFlags numberFlags
void saveConverterState(qint64 newPos)
bool getChar(QChar *ch)
void write(const QString &data)
void putChar(QChar ch)
void ungetChar(QChar ch)
void restoreToSavedConverterState()
QString read(int maxlen)
QStringDecoder savedToUtf16
const QChar * readPtr() const
PaddingResult padding(int len) const
bool scan(const QChar **ptr, int *tokenLength, int maxlen, TokenDelimiter delimiter)
QTextStreamPrivate(QTextStream *q_ptr)
qint64 readBufferStartDevicePos
bool fillReadBuffer(qint64 maxBytes=-1)
QIODevice * device
QTextStream * q_ptr
void consume(int nchars)
void putNumber(qulonglong number, bool negative)
QTextStream::Status status
void writePadding(int len)
QStringConverter::Encoding encoding
QStringDecoder toUtf16
QStringEncoder fromUtf16
NumberParsingStatus getNumber(qulonglong *l)
QIODevice::OpenMode stringOpenMode
bool getReal(double *f)
void putString(const QString &ch, bool number=false)
Definition: base.h:37
#define this
Definition: dialogs.cpp:56
QString str
[2]
double e
else opt state
[0]
auto generate(StringRef generatorName, SourceLineInfo const &lineInfo, L const &generatorExpression) -> decltype(std::declval< decltype(generatorExpression())>().get())
Definition: catch_p_p.h:4085
Q_CORE_EXPORT QByteArray toPrintable(const char *data, int len, int maxSize)
Definition: qdebug.cpp:65
Definition: qnamespace.h:55
QTextStream & flush(QTextStream &stream)
QTextStream & hex(QTextStream &stream)
QTextStream & uppercasebase(QTextStream &stream)
QTextStream & bin(QTextStream &stream)
QTextStream & showbase(QTextStream &stream)
QTextStream & lowercasebase(QTextStream &stream)
QTextStream & noforcesign(QTextStream &stream)
QTextStream & uppercasedigits(QTextStream &stream)
QTextStream & bom(QTextStream &stream)
QTextStream & reset(QTextStream &stream)
QTextStream & oct(QTextStream &stream)
QTextStream & lowercasedigits(QTextStream &stream)
QTextStream & noshowbase(QTextStream &stream)
QTextStream & right(QTextStream &stream)
QTextStream & dec(QTextStream &stream)
QTextStream & noforcepoint(QTextStream &stream)
QTextStream & ws(QTextStream &stream)
QTextStream & fixed(QTextStream &stream)
QTextStream & forcesign(QTextStream &stream)
QTextStream & left(QTextStream &stream)
QTextStream & center(QTextStream &stream)
QTextStream & forcepoint(QTextStream &stream)
QTextStream & endl(QTextStream &stream)
QTextStream & scientific(QTextStream &stream)
decltype(auto) cbegin(const T &t)
#define QString()
Definition: parse-defines.h:51
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if
Q_CORE_EXPORT int qstricmp(const char *, const char *)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
EGLStreamKHR stream
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Definition: qglobal.h:332
size_t quintptr
Definition: qglobal.h:310
quint64 qulonglong
Definition: qglobal.h:302
unsigned int uint
Definition: qglobal.h:334
long long qint64
Definition: qglobal.h:298
qint64 qlonglong
Definition: qglobal.h:301
#define qDebug
[1]
Definition: qlogging.h:177
#define qWarning
Definition: qlogging.h:179
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLenum GLsizei GLuint GLint * bytesWritten
GLenum mode
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLenum GLuint buffer
GLint GLsizei width
GLint left
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat n
void ** params
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLenum array
Definition: qopenglext.h:7028
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint writeBuffer
Definition: qopenglext.h:2640
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLuint num
Definition: qopenglext.h:5654
GLenum GLenum GLenum input
Definition: qopenglext.h:10816
GLenum GLenum GLsizei void * table
Definition: qopenglext.h:2745
GLenum GLint GLint * precision
Definition: qopenglext.h:1890
GLsizei const GLchar *const * string
[0]
Definition: qopenglext.h:694
GLbitfield GLuint readBuffer
Definition: qopenglext.h:10002
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type)
#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type)
#define Q_VOID
#define CHECK_VALID_STREAM(x)
QBasicUtf8StringView< false > QUtf8StringView
#define enabled
Definition: qopenglext.h:3098
const int BufferSize
Definition: semaphores.cpp:59
Q_UNUSED(salary)
[21]
QFile file
[0]
QString base
QGraphicsWidget * form
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition: qlocale.cpp:3556
@ ZeroPadExponent
Definition: qlocale_p.h:221
@ AddTrailingZeroes
Definition: qlocale_p.h:211
@ AlwaysShowSign
Definition: qlocale_p.h:215
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition: qlocale.cpp:3799
@ DFSignificantDigits
Definition: qlocale_p.h:205
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition: qlocale.cpp:3814