Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtextstream.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5//#define QTEXTSTREAM_DEBUG
6static const int QTEXTSTREAM_BUFFERSIZE = 16384;
7
192#include "qtextstream.h"
193#include "private/qtextstream_p.h"
194#include "qbuffer.h"
195#include "qfile.h"
196#include "qnumeric.h"
197#include "qvarlengtharray.h"
198#include <private/qdebug_p.h>
199#include <private/qnumeric_p.h>
200#include <private/qtools_p.h>
201
202#include <locale.h>
203#include "private/qlocale_p.h"
204#include "private/qstringconverter_p.h"
205
206#include <stdlib.h>
207#include <limits.h>
208#include <new>
209
210// A precondition macro
211#define Q_VOID
212#define CHECK_VALID_STREAM(x) do { \
213 if (!d->string && !d->device) { \
214 qWarning("QTextStream: No device"); \
215 return x; \
216 } } while (0)
217
218// Base implementations of operator>> for ints and reals
219#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type) do { \
220 Q_D(QTextStream); \
221 CHECK_VALID_STREAM(*this); \
222 qulonglong tmp; \
223 switch (d->getNumber(&tmp)) { \
224 case QTextStreamPrivate::npsOk: \
225 i = (type)tmp; \
226 break; \
227 case QTextStreamPrivate::npsMissingDigit: \
228 case QTextStreamPrivate::npsInvalidPrefix: \
229 i = (type)0; \
230 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
231 break; \
232 } \
233 return *this; } while (0)
234
235#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type) do { \
236 Q_D(QTextStream); \
237 CHECK_VALID_STREAM(*this); \
238 double tmp; \
239 if (d->getReal(&tmp)) { \
240 f = (type)tmp; \
241 } else { \
242 f = (type)0; \
243 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
244 } \
245 return *this; } while (0)
246
248
249using namespace Qt::StringLiterals;
250using namespace QtMiscUtils;
251
252//-------------------------------------------------------------------
253
258 : readConverterSavedStateOffset(0),
259 locale(QLocale::c())
260{
261 this->q_ptr = q_ptr;
262 reset();
263}
264
269{
270 if (deleteDevice) {
271#ifndef QT_NO_QOBJECT
272 device->blockSignals(true);
273#endif
274 delete device;
275 }
276}
277
279{
281 integerBase = 0;
282 fieldWidth = 0;
283 padChar = u' ';
284 fieldAlignment = QTextStream::AlignRight;
285 realNumberNotation = QTextStream::SmartNotation;
286 numberFlags = { };
287}
288
293{
294 params.reset();
295
296 device = nullptr;
297 deleteDevice = false;
298 string = nullptr;
299 stringOffset = 0;
300 stringOpenMode = QTextStream::NotOpen;
301
304 lastTokenSize = 0;
305
306 hasWrittenData = false;
307 generateBOM = false;
311 autoDetectUnicode = true;
312}
313
318{
319 // no buffer next to the QString itself; this function should only
320 // be called internally, for devices.
321 Q_ASSERT(!string);
323
324 // handle text translation and bypass the Text flag in the device.
325 bool textModeEnabled = device->isTextModeEnabled();
326 if (textModeEnabled)
328
329 // read raw data into a temporary buffer
331 qint64 bytesRead = 0;
332#if defined(Q_OS_WIN)
333 // On Windows, there is no non-blocking stdin - so we fall back to reading
334 // lines instead. If there is no QOBJECT, we read lines for all sequential
335 // devices; otherwise, we read lines only for stdin.
336 QFile *file = 0;
337 Q_UNUSED(file);
338 if (device->isSequential()
339#if !defined(QT_NO_QOBJECT)
340 && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
341#endif
342 ) {
343 if (maxBytes != -1)
344 bytesRead = device->readLine(buf, qMin<qint64>(sizeof(buf), maxBytes));
345 else
346 bytesRead = device->readLine(buf, sizeof(buf));
347 } else
348#endif
349 {
350 if (maxBytes != -1)
351 bytesRead = device->read(buf, qMin<qint64>(sizeof(buf), maxBytes));
352 else
353 bytesRead = device->read(buf, sizeof(buf));
354 }
355
356 // reset the Text flag.
357 if (textModeEnabled)
359
360 if (bytesRead <= 0)
361 return false;
362
363#ifndef QT_BOOTSTRAPPED
364 if (autoDetectUnicode) {
365 autoDetectUnicode = false;
366
368 // QStringConverter::Locale implies unknown, so keep the current encoding
369 if (e) {
370 encoding = *e;
373 }
374 }
375#if defined (QTEXTSTREAM_DEBUG)
376 qDebug("QTextStreamPrivate::fillReadBuffer(), using %s encoding", QStringConverter::nameForEncoding(encoding));
377#endif
378#endif
379
380#if defined (QTEXTSTREAM_DEBUG)
381 qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
382 QtDebugUtils::toPrintable(buf, bytesRead, 32).constData(), int(sizeof(buf)), int(bytesRead));
383#endif
384
385 int oldReadBufferSize = readBuffer.size();
386 readBuffer += toUtf16(QByteArrayView(buf, bytesRead));
387
388 // remove all '\r\n' in the string.
389 if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
390 QChar CR = u'\r';
391 QChar *writePtr = readBuffer.data() + oldReadBufferSize;
392 QChar *readPtr = readBuffer.data() + oldReadBufferSize;
393 QChar *endPtr = readBuffer.data() + readBuffer.size();
394
395 int n = oldReadBufferSize;
396 if (readPtr < endPtr) {
397 // Cut-off to avoid unnecessary self-copying.
398 while (*readPtr++ != CR) {
399 ++n;
400 if (++writePtr == endPtr)
401 break;
402 }
403 }
404 while (readPtr < endPtr) {
405 QChar ch = *readPtr++;
406 if (ch != CR) {
407 *writePtr++ = ch;
408 } else {
409 if (n < readBufferOffset)
411 --bytesRead;
412 }
413 ++n;
414 }
415 readBuffer.resize(writePtr - readBuffer.data());
416 }
417
418#if defined (QTEXTSTREAM_DEBUG)
419 qDebug("QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]", int(bytesRead),
420 QtDebugUtils::toPrintable(readBuffer.toLatin1(), readBuffer.size(), readBuffer.size()).constData());
421#endif
422 return true;
423}
424
434
439{
440 // no buffer next to the QString itself; this function should only
441 // be called internally, for devices.
442 if (string || !device)
443 return;
444
445 // Stream went bye-bye already. Appending further data may succeed again,
446 // but would create a corrupted stream anyway.
447 if (status != QTextStream::Ok)
448 return;
449
450 if (writeBuffer.isEmpty())
451 return;
452
453#if defined (Q_OS_WIN)
454 // handle text translation and bypass the Text flag in the device.
455 bool textModeEnabled = device->isTextModeEnabled();
456 if (textModeEnabled) {
458 writeBuffer.replace(u'\n', "\r\n"_L1);
459 }
460#endif
461
463 writeBuffer.clear();
464 hasWrittenData = true;
465
466 // write raw data to the device
468#if defined (QTEXTSTREAM_DEBUG)
469 qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
470 QtDebugUtils::toPrintable(data.constData(), data.size(), 32).constData(), int(bytesWritten));
471#endif
472
473#if defined (Q_OS_WIN)
474 // reset the text flag
475 if (textModeEnabled)
477#endif
478
479 if (bytesWritten <= 0) {
480 status = QTextStream::WriteFailed;
481 return;
482 }
483
484 // flush the file
485#ifndef QT_NO_QOBJECT
486 QFileDevice *file = qobject_cast<QFileDevice *>(device);
487 bool flushed = !file || file->flush();
488#else
489 bool flushed = true;
490#endif
491
492#if defined (QTEXTSTREAM_DEBUG)
493 qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes",
494 int(bytesWritten));
495#endif
496 if (!flushed || bytesWritten != qint64(data.size()))
497 status = QTextStream::WriteFailed;
498}
499
501{
502 QString ret;
503 if (string) {
504 lastTokenSize = qMin(maxlen, string->size() - stringOffset);
505 ret = string->mid(stringOffset, lastTokenSize);
506 } else {
507 while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) ;
508 lastTokenSize = qMin(maxlen, readBuffer.size() - readBufferOffset);
510 }
512
513#if defined (QTEXTSTREAM_DEBUG)
514 qDebug("QTextStreamPrivate::read() maxlen = %d, token length = %d", maxlen, ret.length());
515#endif
516 return ret;
517}
518
526bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenDelimiter delimiter)
527{
528 int totalSize = 0;
529 int delimSize = 0;
530 bool consumeDelimiter = false;
531 bool foundToken = false;
532 int startOffset = device ? readBufferOffset : stringOffset;
533 QChar lastChar;
534
535 do {
536 int endOffset;
537 const QChar *chPtr;
538 if (device) {
539 chPtr = readBuffer.constData();
540 endOffset = readBuffer.size();
541 } else {
542 chPtr = string->constData();
543 endOffset = string->size();
544 }
545 chPtr += startOffset;
546
547 for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
548 const QChar ch = *chPtr++;
549 ++totalSize;
550
551 switch (delimiter) {
552 case Space:
553 if (ch.isSpace()) {
554 foundToken = true;
555 delimSize = 1;
556 }
557 break;
558 case NotSpace:
559 if (!ch.isSpace()) {
560 foundToken = true;
561 delimSize = 1;
562 }
563 break;
564 case EndOfLine:
565 if (ch == u'\n') {
566 foundToken = true;
567 delimSize = (lastChar == u'\r') ? 2 : 1;
568 consumeDelimiter = true;
569 }
570 lastChar = ch;
571 break;
572 }
573 }
574 } while (!foundToken
575 && (!maxlen || totalSize < maxlen)
576 && device && fillReadBuffer());
577
578 if (totalSize == 0) {
579#if defined (QTEXTSTREAM_DEBUG)
580 qDebug("QTextStreamPrivate::scan() reached the end of input.");
581#endif
582 return false;
583 }
584
585 // if we find a '\r' at the end of the data when reading lines,
586 // don't make it part of the line.
587 if (delimiter == EndOfLine && totalSize > 0 && !foundToken) {
588 if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
589 && lastChar == u'\r') {
590 consumeDelimiter = true;
591 ++delimSize;
592 }
593 }
594
595 // set the read offset and length of the token
596 if (length)
597 *length = totalSize - delimSize;
598 if (ptr)
599 *ptr = readPtr();
600
601 // update last token size. the callee will call consumeLastToken() when
602 // done.
603 lastTokenSize = totalSize;
604 if (!consumeDelimiter)
605 lastTokenSize -= delimSize;
606
607#if defined (QTEXTSTREAM_DEBUG)
608 qDebug("QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
609 ptr, length, maxlen, (int)delimiter, totalSize - delimSize, delimSize);
610#endif
611 return true;
612}
613
618{
620 if (string)
621 return string->constData() + stringOffset;
622 return readBuffer.constData() + readBufferOffset;
623}
624
634
639{
640#if defined (QTEXTSTREAM_DEBUG)
641 qDebug("QTextStreamPrivate::consume(%d)", size);
642#endif
643 if (string) {
645 if (stringOffset > string->size())
646 stringOffset = string->size();
647 } else {
649 if (readBufferOffset >= readBuffer.size()) {
651 readBuffer.clear();
657 }
658 }
659}
660
665{
666 // ### Hack, FIXME
667 memcpy((void *)&savedToUtf16, (void *)&toUtf16, sizeof(QStringDecoder));
670}
671
676{
677 if (savedToUtf16.isValid())
678 memcpy((void *)&toUtf16, (void *)&savedToUtf16, sizeof(QStringDecoder));
679 else
682}
683
688{
689 if (string) {
690 // ### What about seek()??
691 string->append(data, len);
692 } else {
693 writeBuffer.append(data, len);
696 }
697}
698
703{
704 if (string) {
705 // ### What about seek()??
706 string->append(ch);
707 } else {
708 writeBuffer += ch;
711 }
712}
713
718{
719 if (string) {
720 // ### What about seek()??
721 string->append(data);
722 } else {
723 writeBuffer += data;
726 }
727}
728
733{
734 if (string) {
735 // ### What about seek()??
736 string->resize(string->size() + len, params.padChar);
737 } else {
738 writeBuffer.resize(writeBuffer.size() + len, params.padChar);
741 }
742}
743
748{
749 if ((string && stringOffset == string->size())
750 || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
751 if (ch)
752 *ch = QChar();
753 return false;
754 }
755 if (ch)
756 *ch = *readPtr();
757 consume(1);
758 return true;
759}
760
765{
766 if (string) {
767 if (stringOffset == 0)
768 string->prepend(ch);
769 else
770 (*string)[--stringOffset] = ch;
771 return;
772 }
773
774 if (readBufferOffset == 0) {
775 readBuffer.prepend(ch);
776 return;
777 }
778
780}
781
786{
787 if (params.fieldWidth > 0)
788 putString(&ch, 1);
789 else
790 write(ch);
791}
792
793
798{
799 Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
800
801 int left = 0, right = 0;
802
803 const int padSize = params.fieldWidth - len;
804
805 switch (params.fieldAlignment) {
806 case QTextStream::AlignLeft:
807 right = padSize;
808 break;
809 case QTextStream::AlignRight:
810 case QTextStream::AlignAccountingStyle:
811 left = padSize;
812 break;
813 case QTextStream::AlignCenter:
814 left = padSize/2;
815 right = padSize - padSize/2;
816 break;
817 }
818 return { left, right };
819}
820
825{
826 if (Q_UNLIKELY(params.fieldWidth > len)) {
827
828 // handle padding:
829
830 const PaddingResult pad = padding(len);
831
832 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
833 const QChar sign = len > 0 ? data[0] : QChar();
834 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
835 // write the sign before the padding, then skip it later
836 write(&sign, 1);
837 ++data;
838 --len;
839 }
840 }
841
842 writePadding(pad.left);
843 write(data, len);
844 writePadding(pad.right);
845 } else {
846 write(data, len);
847 }
848}
849
854{
855 if (Q_UNLIKELY(params.fieldWidth > data.size())) {
856
857 // handle padding
858
859 const PaddingResult pad = padding(data.size());
860
861 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
862 const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
863 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
864 // write the sign before the padding, then skip it later
865 write(&sign, 1);
866 data = QLatin1StringView(data.data() + 1, data.size() - 1);
867 }
868 }
869
870 writePadding(pad.left);
871 write(data);
872 writePadding(pad.right);
873 } else {
874 write(data);
875 }
876}
877
882
889QTextStream::QTextStream()
890 : d_ptr(new QTextStreamPrivate(this))
891{
892#if defined (QTEXTSTREAM_DEBUG)
893 qDebug("QTextStream::QTextStream()");
894#endif
895 Q_D(QTextStream);
896 d->status = Ok;
897}
898
902QTextStream::QTextStream(QIODevice *device)
903 : d_ptr(new QTextStreamPrivate(this))
904{
905#if defined (QTEXTSTREAM_DEBUG)
906 qDebug("QTextStream::QTextStream(QIODevice *device == *%p)",
907 device);
908#endif
909 Q_D(QTextStream);
910 d->device = device;
911#ifndef QT_NO_QOBJECT
912 d->deviceClosedNotifier.setupDevice(this, d->device);
913#endif
914 d->status = Ok;
915}
916
921QTextStream::QTextStream(QString *string, OpenMode openMode)
922 : d_ptr(new QTextStreamPrivate(this))
923{
924#if defined (QTEXTSTREAM_DEBUG)
925 qDebug("QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
926 string, int(openMode));
927#endif
928 Q_D(QTextStream);
929 d->string = string;
930 d->stringOpenMode = openMode;
931 d->status = Ok;
932}
933
939QTextStream::QTextStream(QByteArray *array, OpenMode openMode)
940 : d_ptr(new QTextStreamPrivate(this))
941{
942#if defined (QTEXTSTREAM_DEBUG)
943 qDebug("QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
944 array, int(openMode));
945#endif
946 Q_D(QTextStream);
947 d->device = new QBuffer(array);
948 d->device->open(openMode);
949 d->deleteDevice = true;
950#ifndef QT_NO_QOBJECT
951 d->deviceClosedNotifier.setupDevice(this, d->device);
952#endif
953 d->status = Ok;
954}
955
966QTextStream::QTextStream(const QByteArray &array, OpenMode openMode)
967 : d_ptr(new QTextStreamPrivate(this))
968{
969#if defined (QTEXTSTREAM_DEBUG)
970 qDebug("QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
971 &array, int(openMode));
972#endif
973 QBuffer *buffer = new QBuffer;
975 buffer->open(openMode);
976
977 Q_D(QTextStream);
978 d->device = buffer;
979 d->deleteDevice = true;
980#ifndef QT_NO_QOBJECT
981 d->deviceClosedNotifier.setupDevice(this, d->device);
982#endif
983 d->status = Ok;
984}
985
997QTextStream::QTextStream(FILE *fileHandle, OpenMode openMode)
998 : d_ptr(new QTextStreamPrivate(this))
999{
1000#if defined (QTEXTSTREAM_DEBUG)
1001 qDebug("QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
1002 fileHandle, int(openMode));
1003#endif
1004 QFile *file = new QFile;
1005 // Discarding the return value of open; even if it failed
1006 // (and the file is not open), QTextStream still reports `Ok`
1007 // for closed QIODevices, so there's nothing really to do here.
1008 (void)file->open(fileHandle, openMode);
1009
1010 Q_D(QTextStream);
1011 d->device = file;
1012 d->deleteDevice = true;
1013#ifndef QT_NO_QOBJECT
1014 d->deviceClosedNotifier.setupDevice(this, d->device);
1015#endif
1016 d->status = Ok;
1017}
1018
1025QTextStream::~QTextStream()
1026{
1027 Q_D(QTextStream);
1028#if defined (QTEXTSTREAM_DEBUG)
1029 qDebug("QTextStream::~QTextStream()");
1030#endif
1031 if (!d->writeBuffer.isEmpty())
1032 d->flushWriteBuffer();
1033}
1034
1040void QTextStream::reset()
1041{
1042 Q_D(QTextStream);
1043
1044 d->params.reset();
1045}
1046
1052void QTextStream::flush()
1053{
1054 Q_D(QTextStream);
1055 d->flushWriteBuffer();
1056}
1057
1062bool QTextStream::seek(qint64 pos)
1063{
1064 Q_D(QTextStream);
1065 d->lastTokenSize = 0;
1066
1067 if (d->device) {
1068 // Empty the write buffer
1069 d->flushWriteBuffer();
1070 if (!d->device->seek(pos))
1071 return false;
1072 d->resetReadBuffer();
1073
1074 d->toUtf16.resetState();
1075 d->fromUtf16.resetState();
1076 return true;
1077 }
1078
1079 // string
1080 if (d->string && pos <= d->string->size()) {
1081 d->stringOffset = int(pos);
1082 return true;
1083 }
1084 return false;
1085}
1086
1101qint64 QTextStream::pos() const
1102{
1103 Q_D(const QTextStream);
1104 if (d->device) {
1105 // Cutoff
1106 if (d->readBuffer.isEmpty())
1107 return d->device->pos();
1108 if (d->device->isSequential())
1109 return 0;
1110
1111 // Seek the device
1112 if (!d->device->seek(d->readBufferStartDevicePos))
1113 return qint64(-1);
1114
1115 // Reset the read buffer
1116 QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
1117 thatd->readBuffer.clear();
1118
1119 thatd->restoreToSavedConverterState();
1120 if (d->readBufferStartDevicePos == 0)
1121 thatd->autoDetectUnicode = true;
1122
1123 // Rewind the device to get to the current position Ensure that
1124 // readBufferOffset is unaffected by fillReadBuffer()
1125 int oldReadBufferOffset = d->readBufferOffset + d->readConverterSavedStateOffset;
1126 while (d->readBuffer.size() < oldReadBufferOffset) {
1127 if (!thatd->fillReadBuffer(1))
1128 return qint64(-1);
1129 }
1130 thatd->readBufferOffset = oldReadBufferOffset;
1131 thatd->readConverterSavedStateOffset = 0;
1132
1133 // Return the device position.
1134 return d->device->pos();
1135 }
1136
1137 if (d->string)
1138 return d->stringOffset;
1139
1140 qWarning("QTextStream::pos: no device");
1141 return qint64(-1);
1142}
1143
1155void QTextStream::skipWhiteSpace()
1156{
1157 Q_D(QTextStream);
1159 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1160 d->consumeLastToken();
1161}
1162
1173void QTextStream::setDevice(QIODevice *device)
1174{
1175 Q_D(QTextStream);
1176 flush();
1177 if (d->deleteDevice) {
1178#ifndef QT_NO_QOBJECT
1179 d->deviceClosedNotifier.disconnect();
1180#endif
1181 delete d->device;
1182 d->deleteDevice = false;
1183 }
1184
1185 d->reset();
1186 d->status = Ok;
1187 d->device = device;
1188 d->resetReadBuffer();
1189#ifndef QT_NO_QOBJECT
1190 d->deviceClosedNotifier.setupDevice(this, d->device);
1191#endif
1192}
1193
1200QIODevice *QTextStream::device() const
1201{
1202 Q_D(const QTextStream);
1203 return d->device;
1204}
1205
1213void QTextStream::setString(QString *string, OpenMode openMode)
1214{
1215 Q_D(QTextStream);
1216 flush();
1217 if (d->deleteDevice) {
1218#ifndef QT_NO_QOBJECT
1219 d->deviceClosedNotifier.disconnect();
1220 d->device->blockSignals(true);
1221#endif
1222 delete d->device;
1223 d->deleteDevice = false;
1224 }
1225
1226 d->reset();
1227 d->status = Ok;
1228 d->string = string;
1229 d->stringOpenMode = openMode;
1230}
1231
1238QString *QTextStream::string() const
1239{
1240 Q_D(const QTextStream);
1241 return d->string;
1242}
1243
1252void QTextStream::setFieldAlignment(FieldAlignment mode)
1253{
1254 Q_D(QTextStream);
1255 d->params.fieldAlignment = mode;
1256}
1257
1263QTextStream::FieldAlignment QTextStream::fieldAlignment() const
1264{
1265 Q_D(const QTextStream);
1266 return d->params.fieldAlignment;
1267}
1268
1284void QTextStream::setPadChar(QChar ch)
1285{
1286 Q_D(QTextStream);
1287 d->params.padChar = ch;
1288}
1289
1295QChar QTextStream::padChar() const
1296{
1297 Q_D(const QTextStream);
1298 return d->params.padChar;
1299}
1300
1313void QTextStream::setFieldWidth(int width)
1314{
1315 Q_D(QTextStream);
1316 d->params.fieldWidth = width;
1317}
1318
1324int QTextStream::fieldWidth() const
1325{
1326 Q_D(const QTextStream);
1327 return d->params.fieldWidth;
1328}
1329
1338void QTextStream::setNumberFlags(NumberFlags flags)
1339{
1340 Q_D(QTextStream);
1341 d->params.numberFlags = flags;
1342}
1343
1349QTextStream::NumberFlags QTextStream::numberFlags() const
1350{
1351 Q_D(const QTextStream);
1352 return d->params.numberFlags;
1353}
1354
1365void QTextStream::setIntegerBase(int base)
1366{
1367 Q_D(QTextStream);
1368 d->params.integerBase = base;
1369}
1370
1377int QTextStream::integerBase() const
1378{
1379 Q_D(const QTextStream);
1380 return d->params.integerBase;
1381}
1382
1391void QTextStream::setRealNumberNotation(RealNumberNotation notation)
1392{
1393 Q_D(QTextStream);
1394 d->params.realNumberNotation = notation;
1395}
1396
1402QTextStream::RealNumberNotation QTextStream::realNumberNotation() const
1403{
1404 Q_D(const QTextStream);
1405 return d->params.realNumberNotation;
1406}
1407
1418void QTextStream::setRealNumberPrecision(int precision)
1419{
1420 Q_D(QTextStream);
1421 if (precision < 0) {
1422 qWarning("QTextStream::setRealNumberPrecision: Invalid precision (%d)", precision);
1423 d->params.realNumberPrecision = 6;
1424 return;
1425 }
1426 d->params.realNumberPrecision = precision;
1427}
1428
1437int QTextStream::realNumberPrecision() const
1438{
1439 Q_D(const QTextStream);
1440 return d->params.realNumberPrecision;
1441}
1442
1449QTextStream::Status QTextStream::status() const
1450{
1451 Q_D(const QTextStream);
1452 return d->status;
1453}
1454
1462void QTextStream::resetStatus()
1463{
1464 Q_D(QTextStream);
1465 d->status = Ok;
1466}
1467
1478void QTextStream::setStatus(Status status)
1479{
1480 Q_D(QTextStream);
1481 if (d->status == Ok)
1482 d->status = status;
1483}
1484
1491bool QTextStream::atEnd() const
1492{
1493 Q_D(const QTextStream);
1494 CHECK_VALID_STREAM(true);
1495
1496 if (d->string)
1497 return d->string->size() == d->stringOffset;
1498 return d->readBuffer.isEmpty() && d->device->atEnd();
1499}
1500
1511QString QTextStream::readAll()
1512{
1513 Q_D(QTextStream);
1515
1516 return d->read(INT_MAX);
1517}
1518
1536QString QTextStream::readLine(qint64 maxlen)
1537{
1538 QString line;
1539
1540 readLineInto(&line, maxlen);
1541 return line;
1542}
1543
1569bool QTextStream::readLineInto(QString *line, qint64 maxlen)
1570{
1571 Q_D(QTextStream);
1572 // keep in sync with CHECK_VALID_STREAM
1573 if (!d->string && !d->device) {
1574 qWarning("QTextStream: No device");
1575 if (line && !line->isNull())
1576 line->resize(0);
1577 return false;
1578 }
1579
1580 const QChar *readPtr;
1581 int length;
1582 if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) {
1583 if (line && !line->isNull())
1584 line->resize(0);
1585 return false;
1586 }
1587
1588 if (Q_LIKELY(line))
1589 line->setUnicode(readPtr, length);
1590 d->consumeLastToken();
1591 return true;
1592}
1593
1602QString QTextStream::read(qint64 maxlen)
1603{
1604 Q_D(QTextStream);
1606
1607 if (maxlen <= 0)
1608 return QString::fromLatin1(""); // empty, not null
1609
1610 return d->read(int(maxlen));
1611}
1612
1617{
1618 scan(nullptr, nullptr, 0, NotSpace);
1620
1621 // detect int encoding
1622 int base = params.integerBase;
1623 if (base == 0) {
1624 QChar ch;
1625 if (!getChar(&ch))
1626 return npsInvalidPrefix;
1627 if (ch == u'0') {
1628 QChar ch2;
1629 if (!getChar(&ch2)) {
1630 // Result is the number 0
1631 *ret = 0;
1632 return npsOk;
1633 }
1634 ch2 = ch2.toLower();
1635
1636 if (ch2 == u'x') {
1637 base = 16;
1638 } else if (ch2 == u'b') {
1639 base = 2;
1640 } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
1641 base = 8;
1642 } else {
1643 base = 10;
1644 }
1645 ungetChar(ch2);
1646 } else if (ch == locale.negativeSign() || ch == locale.positiveSign() || ch.isDigit()) {
1647 base = 10;
1648 } else {
1649 ungetChar(ch);
1650 return npsInvalidPrefix;
1651 }
1652 ungetChar(ch);
1653 // State of the stream is now the same as on entry
1654 // (cursor is at prefix),
1655 // and local variable 'base' has been set appropriately.
1656 }
1657
1658 qulonglong val=0;
1659 switch (base) {
1660 case 2: {
1661 QChar pf1, pf2, dig;
1662 // Parse prefix '0b'
1663 if (!getChar(&pf1) || pf1 != u'0')
1664 return npsInvalidPrefix;
1665 if (!getChar(&pf2) || pf2.toLower() != u'b')
1666 return npsInvalidPrefix;
1667 // Parse digits
1668 int ndigits = 0;
1669 while (getChar(&dig)) {
1670 int n = dig.toLower().unicode();
1671 if (n == '0' || n == '1') {
1672 val <<= 1;
1673 val += n - '0';
1674 } else {
1675 ungetChar(dig);
1676 break;
1677 }
1678 ndigits++;
1679 }
1680 if (ndigits == 0) {
1681 // Unwind the prefix and abort
1682 ungetChar(pf2);
1683 ungetChar(pf1);
1684 return npsMissingDigit;
1685 }
1686 break;
1687 }
1688 case 8: {
1689 QChar pf, dig;
1690 // Parse prefix '0'
1691 if (!getChar(&pf) || pf != u'0')
1692 return npsInvalidPrefix;
1693 // Parse digits
1694 int ndigits = 0;
1695 while (getChar(&dig)) {
1696 int n = dig.toLower().unicode();
1697 if (isOctalDigit(n)) {
1698 val *= 8;
1699 val += n - '0';
1700 } else {
1701 ungetChar(dig);
1702 break;
1703 }
1704 ndigits++;
1705 }
1706 if (ndigits == 0) {
1707 // Unwind the prefix and abort
1708 ungetChar(pf);
1709 return npsMissingDigit;
1710 }
1711 break;
1712 }
1713 case 10: {
1714 // Parse sign (or first digit)
1715 QChar sign;
1716 int ndigits = 0;
1717 if (!getChar(&sign))
1718 return npsMissingDigit;
1719 if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1720 if (!sign.isDigit()) {
1721 ungetChar(sign);
1722 return npsMissingDigit;
1723 }
1724 val += sign.digitValue();
1725 ndigits++;
1726 }
1727 // Parse digits
1728 QChar ch;
1729 while (getChar(&ch)) {
1730 if (ch.isDigit()) {
1731 val *= 10;
1732 val += ch.digitValue();
1733 } else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
1734 continue;
1735 } else {
1736 ungetChar(ch);
1737 break;
1738 }
1739 ndigits++;
1740 }
1741 if (ndigits == 0)
1742 return npsMissingDigit;
1743 if (sign == locale.negativeSign()) {
1744 qlonglong ival = qlonglong(val);
1745 if (ival > 0)
1746 ival = -ival;
1747 val = qulonglong(ival);
1748 }
1749 break;
1750 }
1751 case 16: {
1752 QChar pf1, pf2, dig;
1753 // Parse prefix ' 0x'
1754 if (!getChar(&pf1) || pf1 != u'0')
1755 return npsInvalidPrefix;
1756 if (!getChar(&pf2) || pf2.toLower() != u'x')
1757 return npsInvalidPrefix;
1758 // Parse digits
1759 int ndigits = 0;
1760 while (getChar(&dig)) {
1761 const int h = fromHex(dig.unicode());
1762 if (h != -1) {
1763 val <<= 4;
1764 val += h;
1765 } else {
1766 ungetChar(dig);
1767 break;
1768 }
1769 ndigits++;
1770 }
1771 if (ndigits == 0) {
1772 return npsMissingDigit;
1773 }
1774 break;
1775 }
1776 default:
1777 // Unsupported integerBase
1778 return npsInvalidPrefix;
1779 }
1780
1781 if (ret)
1782 *ret = val;
1783 return npsOk;
1784}
1785
1791{
1792 // We use a table-driven FSM to parse floating point numbers
1793 // strtod() cannot be used directly since we may be reading from a
1794 // QIODevice.
1795 enum ParserState {
1796 Init = 0,
1797 Sign = 1,
1798 Mantissa = 2,
1799 Dot = 3,
1800 Abscissa = 4,
1801 ExpMark = 5,
1802 ExpSign = 6,
1803 Exponent = 7,
1804 Nan1 = 8,
1805 Nan2 = 9,
1806 Inf1 = 10,
1807 Inf2 = 11,
1808 NanInf = 12,
1809 Done = 13
1810 };
1811 enum InputToken {
1812 None = 0,
1813 InputSign = 1,
1814 InputDigit = 2,
1815 InputDot = 3,
1816 InputExp = 4,
1817 InputI = 5,
1818 InputN = 6,
1819 InputF = 7,
1820 InputA = 8,
1821 InputT = 9
1822 };
1823
1824 static const uchar table[13][10] = {
1825 // None InputSign InputDigit InputDot InputExp InputI InputN InputF InputA InputT
1826 { 0, Sign, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 0 Init
1827 { 0, 0, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 1 Sign
1828 { Done, Done, Mantissa, Dot, ExpMark, 0, 0, 0, 0, 0 }, // 2 Mantissa
1829 { 0, 0, Abscissa, 0, 0, 0, 0, 0, 0, 0 }, // 3 Dot
1830 { Done, Done, Abscissa, Done, ExpMark, 0, 0, 0, 0, 0 }, // 4 Abscissa
1831 { 0, ExpSign, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 5 ExpMark
1832 { 0, 0, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 6 ExpSign
1833 { Done, Done, Exponent, Done, Done, 0, 0, 0, 0, 0 }, // 7 Exponent
1834 { 0, 0, 0, 0, 0, 0, 0, 0, Nan2, 0 }, // 8 Nan1
1835 { 0, 0, 0, 0, 0, 0, NanInf, 0, 0, 0 }, // 9 Nan2
1836 { 0, 0, 0, 0, 0, 0, Inf2, 0, 0, 0 }, // 10 Inf1
1837 { 0, 0, 0, 0, 0, 0, 0, NanInf, 0, 0 }, // 11 Inf2
1838 { Done, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 11 NanInf
1839 };
1840
1841 ParserState state = Init;
1842 InputToken input = None;
1843
1844 scan(nullptr, nullptr, 0, NotSpace);
1846
1847 const int BufferSize = 128;
1848 char buf[BufferSize];
1849 int i = 0;
1850
1851 QChar c;
1852 while (getChar(&c)) {
1853 switch (c.unicode()) {
1854 case '0': case '1': case '2': case '3': case '4':
1855 case '5': case '6': case '7': case '8': case '9':
1856 input = InputDigit;
1857 break;
1858 case 'i': case 'I':
1859 input = InputI;
1860 break;
1861 case 'n': case 'N':
1862 input = InputN;
1863 break;
1864 case 'f': case 'F':
1865 input = InputF;
1866 break;
1867 case 'a': case 'A':
1868 input = InputA;
1869 break;
1870 case 't': case 'T':
1871 input = InputT;
1872 break;
1873 default: {
1874 QChar lc = c.toLower();
1875 if (lc == locale.decimalPoint().toLower())
1876 input = InputDot;
1877 else if (lc == locale.exponential().toLower())
1878 input = InputExp;
1879 else if (lc == locale.negativeSign().toLower()
1880 || lc == locale.positiveSign().toLower())
1881 input = InputSign;
1882 else if (locale != QLocale::c() // backward-compatibility
1883 && lc == locale.groupSeparator().toLower())
1884 input = InputDigit; // well, it isn't a digit, but no one cares.
1885 else
1886 input = None;
1887 }
1888 break;
1889 }
1890
1891 state = ParserState(table[state][input]);
1892
1893 if (state == Init || state == Done || i > (BufferSize - 5)) {
1894 ungetChar(c);
1895 if (i > (BufferSize - 5)) { // ignore rest of digits
1896 while (getChar(&c)) {
1897 if (!c.isDigit()) {
1898 ungetChar(c);
1899 break;
1900 }
1901 }
1902 }
1903 break;
1904 }
1905
1906 buf[i++] = c.toLatin1();
1907 }
1908
1909 if (i == 0)
1910 return false;
1911 if (!f)
1912 return true;
1913 buf[i] = '\0';
1914
1915 // backward-compatibility. Old implementation supported +nan/-nan
1916 // for some reason. QLocale only checks for lower-case
1917 // nan/+inf/-inf, so here we also check for uppercase and mixed
1918 // case versions.
1919 if (!qstricmp(buf, "nan") || !qstricmp(buf, "+nan") || !qstricmp(buf, "-nan")) {
1920 *f = qt_qnan();
1921 return true;
1922 } else if (!qstricmp(buf, "+inf") || !qstricmp(buf, "inf")) {
1923 *f = qt_inf();
1924 return true;
1925 } else if (!qstricmp(buf, "-inf")) {
1926 *f = -qt_inf();
1927 return true;
1928 }
1929 bool ok;
1931 return ok;
1932}
1933
1944QTextStream &QTextStream::operator>>(QChar &c)
1945{
1946 Q_D(QTextStream);
1947 CHECK_VALID_STREAM(*this);
1948 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1949 if (!d->getChar(&c))
1950 setStatus(ReadPastEnd);
1951 return *this;
1952}
1953
1963QTextStream &QTextStream::operator>>(char &c)
1964{
1965 QChar ch;
1966 *this >> ch;
1967 c = ch.toLatin1();
1968 return *this;
1969}
1970
2003QTextStream &QTextStream::operator>>(signed short &i)
2004{
2006}
2007
2013QTextStream &QTextStream::operator>>(unsigned short &i)
2014{
2016}
2017
2023QTextStream &QTextStream::operator>>(signed int &i)
2024{
2026}
2027
2033QTextStream &QTextStream::operator>>(unsigned int &i)
2034{
2036}
2037
2043QTextStream &QTextStream::operator>>(signed long &i)
2044{
2046}
2047
2053QTextStream &QTextStream::operator>>(unsigned long &i)
2054{
2056}
2057
2063QTextStream &QTextStream::operator>>(qlonglong &i)
2064{
2066}
2067
2073QTextStream &QTextStream::operator>>(qulonglong &i)
2074{
2076}
2077
2089QTextStream &QTextStream::operator>>(float &f)
2090{
2092}
2093
2099QTextStream &QTextStream::operator>>(double &f)
2100{
2102}
2103
2111QTextStream &QTextStream::operator>>(QString &str)
2112{
2113 Q_D(QTextStream);
2114 CHECK_VALID_STREAM(*this);
2115
2116 str.clear();
2117 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2118 d->consumeLastToken();
2119
2120 const QChar *ptr;
2121 int length;
2122 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2123 setStatus(ReadPastEnd);
2124 return *this;
2125 }
2126
2127 str = QString(ptr, length);
2128 d->consumeLastToken();
2129 return *this;
2130}
2131
2139QTextStream &QTextStream::operator>>(QByteArray &array)
2140{
2141 Q_D(QTextStream);
2142 CHECK_VALID_STREAM(*this);
2143
2144 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2145 d->consumeLastToken();
2146
2147 const QChar *ptr;
2148 int length;
2149 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2150 setStatus(ReadPastEnd);
2151 array.clear();
2152 return *this;
2153 }
2154
2156
2157 d->consumeLastToken();
2158 return *this;
2159}
2160
2175QTextStream &QTextStream::operator>>(char *c)
2176{
2177 Q_D(QTextStream);
2178 *c = 0;
2179 CHECK_VALID_STREAM(*this);
2180 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2181 d->consumeLastToken();
2182
2183 const QChar *ptr;
2184 int length;
2185 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2186 setStatus(ReadPastEnd);
2187 return *this;
2188 }
2189
2191 char *e = encoder.appendToBuffer(c, QStringView(ptr, length));
2192 *e = '\0';
2193 d->consumeLastToken();
2194 return *this;
2195}
2196
2201{
2203
2204 unsigned flags = 0;
2205 const QTextStream::NumberFlags numberFlags = params.numberFlags;
2206 if (numberFlags & QTextStream::ShowBase)
2208 if (numberFlags & QTextStream::ForceSign)
2210 if (numberFlags & QTextStream::UppercaseBase)
2212 if (numberFlags & QTextStream::UppercaseDigits)
2214
2215 // add thousands group separators. For backward compatibility we
2216 // don't add a group separator for C locale.
2219
2220 const QLocaleData *dd = locale.d->m_data;
2221 int base = params.integerBase ? params.integerBase : 10;
2222 if (negative && base == 10) {
2223 result = dd->longLongToString(-static_cast<qlonglong>(number), -1,
2224 base, -1, flags);
2225 } else if (negative) {
2226 // Workaround for backward compatibility for writing negative
2227 // numbers in octal and hex:
2228 // QTextStream(result) << Qt::showbase << Qt::hex << -1 << oct << -1
2229 // should output: -0x1 -0b1
2230 result = dd->unsLongLongToString(number, -1, base, -1, flags);
2232 } else {
2233 result = dd->unsLongLongToString(number, -1, base, -1, flags);
2234 // workaround for backward compatibility - in octal form with
2235 // ShowBase flag set zero should be written as '00'
2236 if (number == 0 && base == 8 && params.numberFlags & QTextStream::ShowBase
2237 && result == "0"_L1) {
2238 result.prepend(u'0');
2239 }
2240 }
2241 putString(result, true);
2242}
2243
2250QTextStream &QTextStream::operator<<(QChar c)
2251{
2252 Q_D(QTextStream);
2253 CHECK_VALID_STREAM(*this);
2254 d->putChar(c);
2255 return *this;
2256}
2257
2263QTextStream &QTextStream::operator<<(char c)
2264{
2265 Q_D(QTextStream);
2266 CHECK_VALID_STREAM(*this);
2267 d->putChar(QChar::fromLatin1(c));
2268 return *this;
2269}
2270
2288QTextStream &QTextStream::operator<<(signed short i)
2289{
2290 Q_D(QTextStream);
2291 CHECK_VALID_STREAM(*this);
2292 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2293 return *this;
2294}
2295
2301QTextStream &QTextStream::operator<<(unsigned short i)
2302{
2303 Q_D(QTextStream);
2304 CHECK_VALID_STREAM(*this);
2305 d->putNumber((qulonglong)i, false);
2306 return *this;
2307}
2308
2314QTextStream &QTextStream::operator<<(signed int i)
2315{
2316 Q_D(QTextStream);
2317 CHECK_VALID_STREAM(*this);
2318 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2319 return *this;
2320}
2321
2327QTextStream &QTextStream::operator<<(unsigned int i)
2328{
2329 Q_D(QTextStream);
2330 CHECK_VALID_STREAM(*this);
2331 d->putNumber((qulonglong)i, false);
2332 return *this;
2333}
2334
2340QTextStream &QTextStream::operator<<(signed long i)
2341{
2342 Q_D(QTextStream);
2343 CHECK_VALID_STREAM(*this);
2344 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2345 return *this;
2346}
2347
2353QTextStream &QTextStream::operator<<(unsigned long i)
2354{
2355 Q_D(QTextStream);
2356 CHECK_VALID_STREAM(*this);
2357 d->putNumber((qulonglong)i, false);
2358 return *this;
2359}
2360
2366QTextStream &QTextStream::operator<<(qlonglong i)
2367{
2368 Q_D(QTextStream);
2369 CHECK_VALID_STREAM(*this);
2370 d->putNumber((qulonglong)qAbs(i), i < 0);
2371 return *this;
2372}
2373
2379QTextStream &QTextStream::operator<<(qulonglong i)
2380{
2381 Q_D(QTextStream);
2382 CHECK_VALID_STREAM(*this);
2383 d->putNumber(i, false);
2384 return *this;
2385}
2386
2398QTextStream &QTextStream::operator<<(float f)
2399{
2400 return *this << double(f);
2401}
2402
2408QTextStream &QTextStream::operator<<(double f)
2409{
2410 Q_D(QTextStream);
2411 CHECK_VALID_STREAM(*this);
2412
2414 switch (realNumberNotation()) {
2415 case FixedNotation:
2417 break;
2418 case ScientificNotation:
2420 break;
2421 case SmartNotation:
2423 break;
2424 }
2425
2426 uint flags = 0;
2427 const QLocale::NumberOptions numberOptions = locale().numberOptions();
2428 if (numberFlags() & ShowBase)
2430 if (numberFlags() & ForceSign)
2432 if (numberFlags() & UppercaseBase)
2434 if (numberFlags() & UppercaseDigits)
2436 if (numberFlags() & ForcePoint) {
2438
2439 // Only for backwards compatibility
2441 }
2442 if (locale() != QLocale::c() && !(numberOptions & QLocale::OmitGroupSeparator))
2444 if (!(numberOptions & QLocale::OmitLeadingZeroInExponent))
2446 if (numberOptions & QLocale::IncludeTrailingZeroesAfterDot)
2448
2449 const QLocaleData *dd = d->locale.d->m_data;
2450 QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
2451 d->putString(num, true);
2452 return *this;
2453}
2454
2462QTextStream &QTextStream::operator<<(const QString &string)
2463{
2464 Q_D(QTextStream);
2465 CHECK_VALID_STREAM(*this);
2466 d->putString(string);
2467 return *this;
2468}
2469
2477QTextStream &QTextStream::operator<<(QStringView string)
2478{
2479 Q_D(QTextStream);
2480 CHECK_VALID_STREAM(*this);
2481 d->putString(string.cbegin(), int(string.size()));
2482 return *this;
2483}
2484
2491QTextStream &QTextStream::operator<<(QLatin1StringView string)
2492{
2493 Q_D(QTextStream);
2494 CHECK_VALID_STREAM(*this);
2495 d->putString(string);
2496 return *this;
2497}
2498
2505QTextStream &QTextStream::operator<<(const QByteArray &array)
2506{
2507 Q_D(QTextStream);
2508 CHECK_VALID_STREAM(*this);
2509 d->putString(QString::fromUtf8(array.constData(), array.size()));
2510 return *this;
2511}
2512
2526QTextStream &QTextStream::operator<<(const char *string)
2527{
2528 Q_D(QTextStream);
2529 CHECK_VALID_STREAM(*this);
2530 d->putString(QUtf8StringView(string));
2531 return *this;
2532}
2533
2540QTextStream &QTextStream::operator<<(const void *ptr)
2541{
2542 Q_D(QTextStream);
2543 CHECK_VALID_STREAM(*this);
2544 const int oldBase = d->params.integerBase;
2545 const NumberFlags oldFlags = d->params.numberFlags;
2546 d->params.integerBase = 16;
2547 d->params.numberFlags |= ShowBase;
2548 d->putNumber(reinterpret_cast<quintptr>(ptr), false);
2549 d->params.integerBase = oldBase;
2550 d->params.numberFlags = oldFlags;
2551 return *this;
2552}
2553
2554namespace Qt {
2555
2565{
2566 stream.setIntegerBase(2);
2567 return stream;
2568}
2569
2579{
2580 stream.setIntegerBase(8);
2581 return stream;
2582}
2583
2593{
2594 stream.setIntegerBase(10);
2595 return stream;
2596}
2597
2608{
2609 stream.setIntegerBase(16);
2610 return stream;
2611}
2612
2622{
2623 stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase);
2624 return stream;
2625}
2626
2636{
2637 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign);
2638 return stream;
2639}
2640
2650{
2651 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForcePoint);
2652 return stream;
2653}
2654
2664{
2665 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ShowBase);
2666 return stream;
2667}
2668
2678{
2679 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForceSign);
2680 return stream;
2681}
2682
2692{
2693 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForcePoint);
2694 return stream;
2695}
2696
2706{
2707 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseBase);
2708 return stream;
2709}
2710
2720{
2721 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseDigits);
2722 return stream;
2723}
2724
2734{
2735 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseBase);
2736 return stream;
2737}
2738
2748{
2749 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseDigits);
2750 return stream;
2751}
2752
2762{
2763 stream.setRealNumberNotation(QTextStream::FixedNotation);
2764 return stream;
2765}
2766
2776{
2777 stream.setRealNumberNotation(QTextStream::ScientificNotation);
2778 return stream;
2779}
2780
2790{
2791 stream.setFieldAlignment(QTextStream::AlignLeft);
2792 return stream;
2793}
2794
2804{
2805 stream.setFieldAlignment(QTextStream::AlignRight);
2806 return stream;
2807}
2808
2818{
2819 stream.setFieldAlignment(QTextStream::AlignCenter);
2820 return stream;
2821}
2822
2838{
2839 return stream << '\n'_L1 << Qt::flush;
2840}
2841
2850{
2851 stream.flush();
2852 return stream;
2853}
2854
2863{
2864 stream.reset();
2865 return stream;
2866}
2867
2876{
2877 stream.skipWhiteSpace();
2878 return stream;
2879}
2880
2881} // namespace Qt
2882
2905namespace Qt {
2915{
2916 stream.setGenerateByteOrderMark(true);
2917 return stream;
2918}
2919
2920} // namespace Qt
2921
2922
2938void QTextStream::setEncoding(QStringConverter::Encoding encoding)
2939{
2940 Q_D(QTextStream);
2941 if (d->encoding == encoding)
2942 return;
2943
2944 qint64 seekPos = -1;
2945 if (!d->readBuffer.isEmpty()) {
2946 if (!d->device->isSequential()) {
2947 seekPos = pos();
2948 }
2949 }
2950
2951 d->encoding = encoding;
2952 d->toUtf16 = QStringDecoder(d->encoding);
2953 bool generateBOM = !d->hasWrittenData && d->generateBOM;
2954 d->fromUtf16 = QStringEncoder(d->encoding,
2956
2957 if (seekPos >=0 && !d->readBuffer.isEmpty())
2958 seek(seekPos);
2959}
2960
2966QStringConverter::Encoding QTextStream::encoding() const
2967{
2968 Q_D(const QTextStream);
2969 return d->encoding;
2970}
2971
2983void QTextStream::setAutoDetectUnicode(bool enabled)
2984{
2985 Q_D(QTextStream);
2986 d->autoDetectUnicode = enabled;
2987}
2988
2995bool QTextStream::autoDetectUnicode() const
2996{
2997 Q_D(const QTextStream);
2998 return d->autoDetectUnicode;
2999}
3000
3009void QTextStream::setGenerateByteOrderMark(bool generate)
3010{
3011 Q_D(QTextStream);
3012 if (d->hasWrittenData || d->generateBOM == generate)
3013 return;
3014
3015 d->generateBOM = generate;
3016 d->fromUtf16 = QStringEncoder(d->encoding, generate ? QStringConverter::Flag::WriteBom : QStringConverter::Flag::Default);
3017}
3018
3026bool QTextStream::generateByteOrderMark() const
3027{
3028 Q_D(const QTextStream);
3029 return d->generateBOM;
3030}
3031
3043void QTextStream::setLocale(const QLocale &locale)
3044{
3045 Q_D(QTextStream);
3046 d->locale = locale;
3047}
3048
3056QLocale QTextStream::locale() const
3057{
3058 Q_D(const QTextStream);
3059 return d->locale;
3060}
3061
3063
3064#ifndef QT_NO_QOBJECT
3065#include "moc_qtextstream_p.cpp"
3066#endif
IOBluetoothDevice * device
\inmodule QtCore \reentrant
Definition qbuffer.h:16
void setData(const QByteArray &data)
Sets the contents of the internal buffer to be data.
Definition qbuffer.cpp:259
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
\inmodule QtCore
Definition qfiledevice.h:32
bool flush()
Flushes any buffered data to the file.
int handle() const
Returns the file handle of the file.
\inmodule QtCore
Definition qfile.h:93
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:904
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
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,...
void setTextModeEnabled(bool enabled)
If enabled is true, this function sets the \l Text flag on the device; otherwise the \l Text flag is ...
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
bool isTextModeEnabled() const
Returns true if the \l Text flag is enabled; otherwise returns false.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
const QLocaleData *const m_data
Definition qlocale_p.h:529
QString decimalPoint() const
Definition qlocale.cpp:2655
double toDouble(const QString &s, bool *ok=nullptr) const
Returns the double represented by the localized string s.
Definition qlocale.h:969
QString negativeSign() const
Definition qlocale.cpp:2727
QString groupSeparator() const
Definition qlocale.cpp:2674
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition qlocale.h:1146
QString exponential() const
Definition qlocale.cpp:2762
QString positiveSign() const
Definition qlocale.cpp:2744
NumberOptions numberOptions() const
Definition qlocale.cpp:1193
@ OmitGroupSeparator
Definition qlocale.h:879
@ IncludeTrailingZeroesAfterDot
Definition qlocale.h:883
@ OmitLeadingZeroInExponent
Definition qlocale.h:881
bool blockSignals(bool b) noexcept
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke...
Definition qobject.cpp:1585
bool isValid() const noexcept
Returns true if this is a valid string converter that can be used for encoding or decoding text.
static Q_CORE_EXPORT const char * nameForEncoding(Encoding e)
Returns the canonical name for encoding e.
void resetState() noexcept
Resets the internal state of the converter, clearing potential errors or partial conversions.
Encoding
\value Utf8 Create a converter to or from UTF-8 \value Utf16 Create a converter to or from UTF-16.
static Q_CORE_EXPORT std::optional< Encoding > encodingForData(QByteArrayView data, char16_t expectedFirstCharacter=0) noexcept
Returns the encoding for the content of data if it can be determined.
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
QByteArray toUtf8() const
Returns a UTF-8 representation of the string view as a QByteArray.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:994
QString & setUnicode(const QChar *unicode, qsizetype size)
Resizes the string to size characters and copies unicode into the string.
Definition qstring.cpp:6100
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QString toLower() const &
Definition qstring.h:435
QString & prepend(QChar c)
Definition qstring.h:478
void resize(qsizetype size)
Sets the size of the string to size characters.
Definition qstring.cpp:2668
QTextStream::FieldAlignment fieldAlignment
QTextStream::RealNumberNotation realNumberNotation
QTextStream::NumberFlags numberFlags
void saveConverterState(qint64 newPos)
QTextStreamPrivate(QTextStream *q_ptr)
PaddingResult padding(qsizetype len) const
bool getChar(QChar *ch)
void putChar(QChar ch)
void ungetChar(QChar ch)
void restoreToSavedConverterState()
void write(QStringView data)
void writePadding(qsizetype len)
QString read(int maxlen)
QStringDecoder savedToUtf16
const QChar * readPtr() const
void putString(QStringView string, bool number=false)
bool scan(const QChar **ptr, int *tokenLength, int maxlen, TokenDelimiter delimiter)
qint64 readBufferStartDevicePos
bool fillReadBuffer(qint64 maxBytes=-1)
QTextStream * q_ptr
void consume(int nchars)
void putNumber(qulonglong number, bool negative)
QTextStream::Status status
QStringConverter::Encoding encoding
QStringDecoder toUtf16
QStringEncoder fromUtf16
NumberParsingStatus getNumber(qulonglong *l)
QIODevice::OpenMode stringOpenMode
bool getReal(double *f)
\inmodule QtCore
#define this
Definition dialogs.cpp:9
QString str
[2]
else opt state
[0]
Q_QML_EXPORT QV4::ReturnedValue locale(QV4::ExecutionEngine *engine, const QString &localeName)
Provides locale specific properties and formatted data.
Combined button and popup list for selecting options.
Q_CORE_EXPORT QByteArray toPrintable(const char *data, qint64 len, qsizetype maxSize)
Definition qdebug.cpp:24
constexpr bool isOctalDigit(char32_t c) noexcept
Definition qtools_p.h:57
constexpr int fromHex(char32_t c) noexcept
Definition qtools_p.h:44
Definition qcompare.h:63
QTextStream & flush(QTextStream &stream)
Calls QTextStream::flush() on stream and returns stream.
QTextStream & uppercasebase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::UppercaseBase) on stream ...
QTextStream & bin(QTextStream &stream)
Calls QTextStream::setIntegerBase(2) on stream and returns stream.
QTextStream & showbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ShowBase) on stream and r...
QTextStream & lowercasebase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::UppercaseBase) on stream...
QTextStream & noforcesign(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ForceSign) on stream and...
QTextStream & uppercasedigits(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::UppercaseDigits) on strea...
QTextStream & bom(QTextStream &stream)
Toggles insertion of the Byte Order Mark on stream when QTextStream is used with a UTF encoding.
QTextStream & oct(QTextStream &stream)
Calls QTextStream::setIntegerBase(8) on stream and returns stream.
QTextStream & lowercasedigits(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::UppercaseDigits) on stre...
QTextStream & noshowbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ShowBase) on stream and ...
QTextStream & noforcepoint(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ForcePoint) on stream an...
QTextStream & ws(QTextStream &stream)
Calls \l {QTextStream::}{skipWhiteSpace()} on stream and returns stream.
QTextStream & fixed(QTextStream &stream)
Calls QTextStream::setRealNumberNotation(QTextStream::FixedNotation) on stream and returns stream.
QTextStream & forcesign(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ForceSign) on stream and ...
QTextStream & center(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignCenter) on stream and returns stream.
QTextStream & forcepoint(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ForcePoint) on stream and...
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
QTextStream & scientific(QTextStream &stream)
Calls QTextStream::setRealNumberNotation(QTextStream::ScientificNotation) on stream and returns strea...
@ Ok
Definition qbezier.cpp:173
Q_CORE_EXPORT int qstricmp(const char *, const char *)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static constexpr int BufferSize
EGLStreamKHR stream
@ None
Definition qhash.cpp:531
#define Q_VOID
Definition qiodevice.cpp:45
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
return ret
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
Definition qnumeric_p.h:100
constexpr static Q_DECL_CONST_FUNCTION double qt_inf() noexcept
Definition qnumeric_p.h:83
GLenum GLsizei GLuint GLint * bytesWritten
GLenum mode
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLdouble GLdouble right
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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
GLfloat n
GLfloat GLfloat GLfloat GLfloat h
void ** params
GLboolean reset
const GLubyte * c
GLuint GLfloat * val
GLenum array
GLuint writeBuffer
GLuint64EXT * result
[6]
GLenum GLsizei len
GLuint num
GLenum GLenum GLenum input
GLenum GLenum GLsizei void * table
GLenum GLint GLint * precision
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
GLbitfield GLuint readBuffer
static const QLatin1Char Dot('.')
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE const uint Default
Definition qsplitter_p.h:27
QBasicUtf8StringView< false > QUtf8StringView
Definition qstringfwd.h:46
#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type)
#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type)
#define CHECK_VALID_STREAM(x)
static const int QTEXTSTREAM_BUFFERSIZE
#define Q_UNUSED(x)
unsigned char uchar
Definition qtypes.h:32
size_t quintptr
Definition qtypes.h:167
quint64 qulonglong
Definition qtypes.h:64
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
qint64 qlonglong
Definition qtypes.h:63
static const uint base
Definition qurlidna.cpp:20
#define enabled
static int sign(int x)
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3706
@ AddTrailingZeroes
Definition qlocale_p.h:259
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3945
@ DFSignificantDigits
Definition qlocale_p.h:253
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3960