Qt 6.x
The Qt SDK
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/qtools_p.h>
200
201#include <locale.h>
202#include "private/qlocale_p.h"
203#include "private/qstringconverter_p.h"
204
205#include <stdlib.h>
206#include <limits.h>
207#include <new>
208
209// A precondition macro
210#define Q_VOID
211#define CHECK_VALID_STREAM(x) do { \
212 if (!d->string && !d->device) { \
213 qWarning("QTextStream: No device"); \
214 return x; \
215 } } while (0)
216
217// Base implementations of operator>> for ints and reals
218#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type) do { \
219 Q_D(QTextStream); \
220 CHECK_VALID_STREAM(*this); \
221 qulonglong tmp; \
222 switch (d->getNumber(&tmp)) { \
223 case QTextStreamPrivate::npsOk: \
224 i = (type)tmp; \
225 break; \
226 case QTextStreamPrivate::npsMissingDigit: \
227 case QTextStreamPrivate::npsInvalidPrefix: \
228 i = (type)0; \
229 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
230 break; \
231 } \
232 return *this; } while (0)
233
234#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type) do { \
235 Q_D(QTextStream); \
236 CHECK_VALID_STREAM(*this); \
237 double tmp; \
238 if (d->getReal(&tmp)) { \
239 f = (type)tmp; \
240 } else { \
241 f = (type)0; \
242 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
243 } \
244 return *this; } while (0)
245
247
248using namespace Qt::StringLiterals;
249using namespace QtMiscUtils;
250
251//-------------------------------------------------------------------
252
257 : readConverterSavedStateOffset(0),
258 locale(QLocale::c())
259{
260 this->q_ptr = q_ptr;
261 reset();
262}
263
268{
269 if (deleteDevice) {
270#ifndef QT_NO_QOBJECT
271 device->blockSignals(true);
272#endif
273 delete device;
274 }
275}
276
278{
280 integerBase = 0;
281 fieldWidth = 0;
282 padChar = u' ';
283 fieldAlignment = QTextStream::AlignRight;
284 realNumberNotation = QTextStream::SmartNotation;
285 numberFlags = { };
286}
287
292{
293 params.reset();
294
295 device = nullptr;
296 deleteDevice = false;
297 string = nullptr;
298 stringOffset = 0;
299 stringOpenMode = QTextStream::NotOpen;
300
303 lastTokenSize = 0;
304
305 hasWrittenData = false;
306 generateBOM = false;
310 autoDetectUnicode = true;
311}
312
317{
318 // no buffer next to the QString itself; this function should only
319 // be called internally, for devices.
320 Q_ASSERT(!string);
322
323 // handle text translation and bypass the Text flag in the device.
324 bool textModeEnabled = device->isTextModeEnabled();
325 if (textModeEnabled)
327
328 // read raw data into a temporary buffer
330 qint64 bytesRead = 0;
331#if defined(Q_OS_WIN)
332 // On Windows, there is no non-blocking stdin - so we fall back to reading
333 // lines instead. If there is no QOBJECT, we read lines for all sequential
334 // devices; otherwise, we read lines only for stdin.
335 QFile *file = 0;
336 Q_UNUSED(file);
337 if (device->isSequential()
338#if !defined(QT_NO_QOBJECT)
339 && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
340#endif
341 ) {
342 if (maxBytes != -1)
343 bytesRead = device->readLine(buf, qMin<qint64>(sizeof(buf), maxBytes));
344 else
345 bytesRead = device->readLine(buf, sizeof(buf));
346 } else
347#endif
348 {
349 if (maxBytes != -1)
350 bytesRead = device->read(buf, qMin<qint64>(sizeof(buf), maxBytes));
351 else
352 bytesRead = device->read(buf, sizeof(buf));
353 }
354
355 // reset the Text flag.
356 if (textModeEnabled)
358
359 if (bytesRead <= 0)
360 return false;
361
362 if (autoDetectUnicode) {
363 autoDetectUnicode = false;
364
366 // QStringConverter::Locale implies unknown, so keep the current encoding
367 if (e) {
368 encoding = *e;
371 }
372 }
373#if defined (QTEXTSTREAM_DEBUG)
374 qDebug("QTextStreamPrivate::fillReadBuffer(), using %s encoding", QStringConverter::nameForEncoding(encoding));
375#endif
376
377#if defined (QTEXTSTREAM_DEBUG)
378 qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
379 QtDebugUtils::toPrintable(buf, bytesRead, 32).constData(), int(sizeof(buf)), int(bytesRead));
380#endif
381
382 int oldReadBufferSize = readBuffer.size();
383 readBuffer += toUtf16(QByteArrayView(buf, bytesRead));
384
385 // remove all '\r\n' in the string.
386 if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
387 QChar CR = u'\r';
388 QChar *writePtr = readBuffer.data() + oldReadBufferSize;
389 QChar *readPtr = readBuffer.data() + oldReadBufferSize;
390 QChar *endPtr = readBuffer.data() + readBuffer.size();
391
392 int n = oldReadBufferSize;
393 if (readPtr < endPtr) {
394 // Cut-off to avoid unnecessary self-copying.
395 while (*readPtr++ != CR) {
396 ++n;
397 if (++writePtr == endPtr)
398 break;
399 }
400 }
401 while (readPtr < endPtr) {
402 QChar ch = *readPtr++;
403 if (ch != CR) {
404 *writePtr++ = ch;
405 } else {
406 if (n < readBufferOffset)
408 --bytesRead;
409 }
410 ++n;
411 }
412 readBuffer.resize(writePtr - readBuffer.data());
413 }
414
415#if defined (QTEXTSTREAM_DEBUG)
416 qDebug("QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]", int(bytesRead),
418#endif
419 return true;
420}
421
426{
427 readBuffer.clear();
430}
431
436{
437 // no buffer next to the QString itself; this function should only
438 // be called internally, for devices.
439 if (string || !device)
440 return;
441
442 // Stream went bye-bye already. Appending further data may succeed again,
443 // but would create a corrupted stream anyway.
444 if (status != QTextStream::Ok)
445 return;
446
447 if (writeBuffer.isEmpty())
448 return;
449
450#if defined (Q_OS_WIN)
451 // handle text translation and bypass the Text flag in the device.
452 bool textModeEnabled = device->isTextModeEnabled();
453 if (textModeEnabled) {
455 writeBuffer.replace(u'\n', "\r\n"_L1);
456 }
457#endif
458
460 writeBuffer.clear();
461 hasWrittenData = true;
462
463 // write raw data to the device
465#if defined (QTEXTSTREAM_DEBUG)
466 qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
467 QtDebugUtils::toPrintable(data.constData(), data.size(), 32).constData(), int(bytesWritten));
468#endif
469
470#if defined (Q_OS_WIN)
471 // reset the text flag
472 if (textModeEnabled)
474#endif
475
476 if (bytesWritten <= 0) {
477 status = QTextStream::WriteFailed;
478 return;
479 }
480
481 // flush the file
482#ifndef QT_NO_QOBJECT
483 QFileDevice *file = qobject_cast<QFileDevice *>(device);
484 bool flushed = !file || file->flush();
485#else
486 bool flushed = true;
487#endif
488
489#if defined (QTEXTSTREAM_DEBUG)
490 qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes",
491 int(bytesWritten));
492#endif
493 if (!flushed || bytesWritten != qint64(data.size()))
494 status = QTextStream::WriteFailed;
495}
496
498{
499 QString ret;
500 if (string) {
501 lastTokenSize = qMin(maxlen, string->size() - stringOffset);
502 ret = string->mid(stringOffset, lastTokenSize);
503 } else {
504 while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) ;
505 lastTokenSize = qMin(maxlen, readBuffer.size() - readBufferOffset);
507 }
509
510#if defined (QTEXTSTREAM_DEBUG)
511 qDebug("QTextStreamPrivate::read() maxlen = %d, token length = %d", maxlen, ret.length());
512#endif
513 return ret;
514}
515
523bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenDelimiter delimiter)
524{
525 int totalSize = 0;
526 int delimSize = 0;
527 bool consumeDelimiter = false;
528 bool foundToken = false;
529 int startOffset = device ? readBufferOffset : stringOffset;
530 QChar lastChar;
531
532 do {
533 int endOffset;
534 const QChar *chPtr;
535 if (device) {
536 chPtr = readBuffer.constData();
537 endOffset = readBuffer.size();
538 } else {
539 chPtr = string->constData();
540 endOffset = string->size();
541 }
542 chPtr += startOffset;
543
544 for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
545 const QChar ch = *chPtr++;
546 ++totalSize;
547
548 switch (delimiter) {
549 case Space:
550 if (ch.isSpace()) {
551 foundToken = true;
552 delimSize = 1;
553 }
554 break;
555 case NotSpace:
556 if (!ch.isSpace()) {
557 foundToken = true;
558 delimSize = 1;
559 }
560 break;
561 case EndOfLine:
562 if (ch == u'\n') {
563 foundToken = true;
564 delimSize = (lastChar == u'\r') ? 2 : 1;
565 consumeDelimiter = true;
566 }
567 lastChar = ch;
568 break;
569 }
570 }
571 } while (!foundToken
572 && (!maxlen || totalSize < maxlen)
573 && device && fillReadBuffer());
574
575 if (totalSize == 0) {
576#if defined (QTEXTSTREAM_DEBUG)
577 qDebug("QTextStreamPrivate::scan() reached the end of input.");
578#endif
579 return false;
580 }
581
582 // if we find a '\r' at the end of the data when reading lines,
583 // don't make it part of the line.
584 if (delimiter == EndOfLine && totalSize > 0 && !foundToken) {
585 if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
586 && lastChar == u'\r') {
587 consumeDelimiter = true;
588 ++delimSize;
589 }
590 }
591
592 // set the read offset and length of the token
593 if (length)
594 *length = totalSize - delimSize;
595 if (ptr)
596 *ptr = readPtr();
597
598 // update last token size. the callee will call consumeLastToken() when
599 // done.
600 lastTokenSize = totalSize;
601 if (!consumeDelimiter)
602 lastTokenSize -= delimSize;
603
604#if defined (QTEXTSTREAM_DEBUG)
605 qDebug("QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
606 ptr, length, maxlen, (int)delimiter, totalSize - delimSize, delimSize);
607#endif
608 return true;
609}
610
615{
617 if (string)
618 return string->constData() + stringOffset;
619 return readBuffer.constData() + readBufferOffset;
620}
621
626{
627 if (lastTokenSize)
629 lastTokenSize = 0;
630}
631
636{
637#if defined (QTEXTSTREAM_DEBUG)
638 qDebug("QTextStreamPrivate::consume(%d)", size);
639#endif
640 if (string) {
642 if (stringOffset > string->size())
643 stringOffset = string->size();
644 } else {
646 if (readBufferOffset >= readBuffer.size()) {
648 readBuffer.clear();
654 }
655 }
656}
657
662{
663 // ### Hack, FIXME
664 memcpy((void *)&savedToUtf16, (void *)&toUtf16, sizeof(QStringDecoder));
667}
668
673{
674 if (savedToUtf16.isValid())
675 memcpy((void *)&toUtf16, (void *)&savedToUtf16, sizeof(QStringDecoder));
676 else
679}
680
685{
686 if (string) {
687 // ### What about seek()??
688 string->append(data, len);
689 } else {
690 writeBuffer.append(data, len);
693 }
694}
695
700{
701 if (string) {
702 // ### What about seek()??
703 string->append(ch);
704 } else {
705 writeBuffer += ch;
708 }
709}
710
715{
716 if (string) {
717 // ### What about seek()??
718 string->append(data);
719 } else {
720 writeBuffer += data;
723 }
724}
725
730{
731 if (string) {
732 // ### What about seek()??
733 string->resize(string->size() + len, params.padChar);
734 } else {
735 writeBuffer.resize(writeBuffer.size() + len, params.padChar);
738 }
739}
740
745{
746 if ((string && stringOffset == string->size())
747 || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
748 if (ch)
749 *ch = QChar();
750 return false;
751 }
752 if (ch)
753 *ch = *readPtr();
754 consume(1);
755 return true;
756}
757
762{
763 if (string) {
764 if (stringOffset == 0)
765 string->prepend(ch);
766 else
767 (*string)[--stringOffset] = ch;
768 return;
769 }
770
771 if (readBufferOffset == 0) {
772 readBuffer.prepend(ch);
773 return;
774 }
775
777}
778
783{
784 if (params.fieldWidth > 0)
785 putString(&ch, 1);
786 else
787 write(ch);
788}
789
790
795{
796 Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
797
798 int left = 0, right = 0;
799
800 const int padSize = params.fieldWidth - len;
801
802 switch (params.fieldAlignment) {
803 case QTextStream::AlignLeft:
804 right = padSize;
805 break;
806 case QTextStream::AlignRight:
807 case QTextStream::AlignAccountingStyle:
808 left = padSize;
809 break;
810 case QTextStream::AlignCenter:
811 left = padSize/2;
812 right = padSize - padSize/2;
813 break;
814 }
815 return { left, right };
816}
817
822{
823 if (Q_UNLIKELY(params.fieldWidth > len)) {
824
825 // handle padding:
826
827 const PaddingResult pad = padding(len);
828
829 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
830 const QChar sign = len > 0 ? data[0] : QChar();
831 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
832 // write the sign before the padding, then skip it later
833 write(&sign, 1);
834 ++data;
835 --len;
836 }
837 }
838
839 writePadding(pad.left);
840 write(data, len);
841 writePadding(pad.right);
842 } else {
843 write(data, len);
844 }
845}
846
851{
852 if (Q_UNLIKELY(params.fieldWidth > data.size())) {
853
854 // handle padding
855
856 const PaddingResult pad = padding(data.size());
857
858 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
859 const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
860 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
861 // write the sign before the padding, then skip it later
862 write(&sign, 1);
863 data = QLatin1StringView(data.data() + 1, data.size() - 1);
864 }
865 }
866
867 writePadding(pad.left);
868 write(data);
869 writePadding(pad.right);
870 } else {
871 write(data);
872 }
873}
874
876{
877 putString(data.toString(), number);
878}
879
886QTextStream::QTextStream()
887 : d_ptr(new QTextStreamPrivate(this))
888{
889#if defined (QTEXTSTREAM_DEBUG)
890 qDebug("QTextStream::QTextStream()");
891#endif
892 Q_D(QTextStream);
893 d->status = Ok;
894}
895
899QTextStream::QTextStream(QIODevice *device)
900 : d_ptr(new QTextStreamPrivate(this))
901{
902#if defined (QTEXTSTREAM_DEBUG)
903 qDebug("QTextStream::QTextStream(QIODevice *device == *%p)",
904 device);
905#endif
906 Q_D(QTextStream);
907 d->device = device;
908#ifndef QT_NO_QOBJECT
909 d->deviceClosedNotifier.setupDevice(this, d->device);
910#endif
911 d->status = Ok;
912}
913
918QTextStream::QTextStream(QString *string, OpenMode openMode)
919 : d_ptr(new QTextStreamPrivate(this))
920{
921#if defined (QTEXTSTREAM_DEBUG)
922 qDebug("QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
923 string, int(openMode));
924#endif
925 Q_D(QTextStream);
926 d->string = string;
927 d->stringOpenMode = openMode;
928 d->status = Ok;
929}
930
936QTextStream::QTextStream(QByteArray *array, OpenMode openMode)
937 : d_ptr(new QTextStreamPrivate(this))
938{
939#if defined (QTEXTSTREAM_DEBUG)
940 qDebug("QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
941 array, int(openMode));
942#endif
943 Q_D(QTextStream);
944 d->device = new QBuffer(array);
945 d->device->open(openMode);
946 d->deleteDevice = true;
947#ifndef QT_NO_QOBJECT
948 d->deviceClosedNotifier.setupDevice(this, d->device);
949#endif
950 d->status = Ok;
951}
952
963QTextStream::QTextStream(const QByteArray &array, OpenMode openMode)
964 : d_ptr(new QTextStreamPrivate(this))
965{
966#if defined (QTEXTSTREAM_DEBUG)
967 qDebug("QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
968 &array, int(openMode));
969#endif
970 QBuffer *buffer = new QBuffer;
972 buffer->open(openMode);
973
974 Q_D(QTextStream);
975 d->device = buffer;
976 d->deleteDevice = true;
977#ifndef QT_NO_QOBJECT
978 d->deviceClosedNotifier.setupDevice(this, d->device);
979#endif
980 d->status = Ok;
981}
982
994QTextStream::QTextStream(FILE *fileHandle, OpenMode openMode)
995 : d_ptr(new QTextStreamPrivate(this))
996{
997#if defined (QTEXTSTREAM_DEBUG)
998 qDebug("QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
999 fileHandle, int(openMode));
1000#endif
1001 QFile *file = new QFile;
1002 file->open(fileHandle, openMode);
1003
1004 Q_D(QTextStream);
1005 d->device = file;
1006 d->deleteDevice = true;
1007#ifndef QT_NO_QOBJECT
1008 d->deviceClosedNotifier.setupDevice(this, d->device);
1009#endif
1010 d->status = Ok;
1011}
1012
1019QTextStream::~QTextStream()
1020{
1021 Q_D(QTextStream);
1022#if defined (QTEXTSTREAM_DEBUG)
1023 qDebug("QTextStream::~QTextStream()");
1024#endif
1025 if (!d->writeBuffer.isEmpty())
1026 d->flushWriteBuffer();
1027}
1028
1034void QTextStream::reset()
1035{
1036 Q_D(QTextStream);
1037
1038 d->params.reset();
1039}
1040
1046void QTextStream::flush()
1047{
1048 Q_D(QTextStream);
1049 d->flushWriteBuffer();
1050}
1051
1056bool QTextStream::seek(qint64 pos)
1057{
1058 Q_D(QTextStream);
1059 d->lastTokenSize = 0;
1060
1061 if (d->device) {
1062 // Empty the write buffer
1063 d->flushWriteBuffer();
1064 if (!d->device->seek(pos))
1065 return false;
1066 d->resetReadBuffer();
1067
1068 d->toUtf16.resetState();
1069 d->fromUtf16.resetState();
1070 return true;
1071 }
1072
1073 // string
1074 if (d->string && pos <= d->string->size()) {
1075 d->stringOffset = int(pos);
1076 return true;
1077 }
1078 return false;
1079}
1080
1095qint64 QTextStream::pos() const
1096{
1097 Q_D(const QTextStream);
1098 if (d->device) {
1099 // Cutoff
1100 if (d->readBuffer.isEmpty())
1101 return d->device->pos();
1102 if (d->device->isSequential())
1103 return 0;
1104
1105 // Seek the device
1106 if (!d->device->seek(d->readBufferStartDevicePos))
1107 return qint64(-1);
1108
1109 // Reset the read buffer
1110 QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
1111 thatd->readBuffer.clear();
1112
1114 if (d->readBufferStartDevicePos == 0)
1115 thatd->autoDetectUnicode = true;
1116
1117 // Rewind the device to get to the current position Ensure that
1118 // readBufferOffset is unaffected by fillReadBuffer()
1119 int oldReadBufferOffset = d->readBufferOffset + d->readConverterSavedStateOffset;
1120 while (d->readBuffer.size() < oldReadBufferOffset) {
1121 if (!thatd->fillReadBuffer(1))
1122 return qint64(-1);
1123 }
1124 thatd->readBufferOffset = oldReadBufferOffset;
1126
1127 // Return the device position.
1128 return d->device->pos();
1129 }
1130
1131 if (d->string)
1132 return d->stringOffset;
1133
1134 qWarning("QTextStream::pos: no device");
1135 return qint64(-1);
1136}
1137
1149void QTextStream::skipWhiteSpace()
1150{
1151 Q_D(QTextStream);
1153 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1154 d->consumeLastToken();
1155}
1156
1167void QTextStream::setDevice(QIODevice *device)
1168{
1169 Q_D(QTextStream);
1170 flush();
1171 if (d->deleteDevice) {
1172#ifndef QT_NO_QOBJECT
1173 d->deviceClosedNotifier.disconnect();
1174#endif
1175 delete d->device;
1176 d->deleteDevice = false;
1177 }
1178
1179 d->reset();
1180 d->status = Ok;
1181 d->device = device;
1182 d->resetReadBuffer();
1183#ifndef QT_NO_QOBJECT
1184 d->deviceClosedNotifier.setupDevice(this, d->device);
1185#endif
1186}
1187
1194QIODevice *QTextStream::device() const
1195{
1196 Q_D(const QTextStream);
1197 return d->device;
1198}
1199
1207void QTextStream::setString(QString *string, OpenMode openMode)
1208{
1209 Q_D(QTextStream);
1210 flush();
1211 if (d->deleteDevice) {
1212#ifndef QT_NO_QOBJECT
1213 d->deviceClosedNotifier.disconnect();
1214 d->device->blockSignals(true);
1215#endif
1216 delete d->device;
1217 d->deleteDevice = false;
1218 }
1219
1220 d->reset();
1221 d->status = Ok;
1222 d->string = string;
1223 d->stringOpenMode = openMode;
1224}
1225
1232QString *QTextStream::string() const
1233{
1234 Q_D(const QTextStream);
1235 return d->string;
1236}
1237
1246void QTextStream::setFieldAlignment(FieldAlignment mode)
1247{
1248 Q_D(QTextStream);
1249 d->params.fieldAlignment = mode;
1250}
1251
1257QTextStream::FieldAlignment QTextStream::fieldAlignment() const
1258{
1259 Q_D(const QTextStream);
1260 return d->params.fieldAlignment;
1261}
1262
1278void QTextStream::setPadChar(QChar ch)
1279{
1280 Q_D(QTextStream);
1281 d->params.padChar = ch;
1282}
1283
1289QChar QTextStream::padChar() const
1290{
1291 Q_D(const QTextStream);
1292 return d->params.padChar;
1293}
1294
1307void QTextStream::setFieldWidth(int width)
1308{
1309 Q_D(QTextStream);
1310 d->params.fieldWidth = width;
1311}
1312
1318int QTextStream::fieldWidth() const
1319{
1320 Q_D(const QTextStream);
1321 return d->params.fieldWidth;
1322}
1323
1332void QTextStream::setNumberFlags(NumberFlags flags)
1333{
1334 Q_D(QTextStream);
1335 d->params.numberFlags = flags;
1336}
1337
1343QTextStream::NumberFlags QTextStream::numberFlags() const
1344{
1345 Q_D(const QTextStream);
1346 return d->params.numberFlags;
1347}
1348
1359void QTextStream::setIntegerBase(int base)
1360{
1361 Q_D(QTextStream);
1362 d->params.integerBase = base;
1363}
1364
1371int QTextStream::integerBase() const
1372{
1373 Q_D(const QTextStream);
1374 return d->params.integerBase;
1375}
1376
1385void QTextStream::setRealNumberNotation(RealNumberNotation notation)
1386{
1387 Q_D(QTextStream);
1388 d->params.realNumberNotation = notation;
1389}
1390
1396QTextStream::RealNumberNotation QTextStream::realNumberNotation() const
1397{
1398 Q_D(const QTextStream);
1399 return d->params.realNumberNotation;
1400}
1401
1412void QTextStream::setRealNumberPrecision(int precision)
1413{
1414 Q_D(QTextStream);
1415 if (precision < 0) {
1416 qWarning("QTextStream::setRealNumberPrecision: Invalid precision (%d)", precision);
1417 d->params.realNumberPrecision = 6;
1418 return;
1419 }
1420 d->params.realNumberPrecision = precision;
1421}
1422
1431int QTextStream::realNumberPrecision() const
1432{
1433 Q_D(const QTextStream);
1434 return d->params.realNumberPrecision;
1435}
1436
1443QTextStream::Status QTextStream::status() const
1444{
1445 Q_D(const QTextStream);
1446 return d->status;
1447}
1448
1456void QTextStream::resetStatus()
1457{
1458 Q_D(QTextStream);
1459 d->status = Ok;
1460}
1461
1472void QTextStream::setStatus(Status status)
1473{
1474 Q_D(QTextStream);
1475 if (d->status == Ok)
1476 d->status = status;
1477}
1478
1485bool QTextStream::atEnd() const
1486{
1487 Q_D(const QTextStream);
1488 CHECK_VALID_STREAM(true);
1489
1490 if (d->string)
1491 return d->string->size() == d->stringOffset;
1492 return d->readBuffer.isEmpty() && d->device->atEnd();
1493}
1494
1505QString QTextStream::readAll()
1506{
1507 Q_D(QTextStream);
1509
1510 return d->read(INT_MAX);
1511}
1512
1530QString QTextStream::readLine(qint64 maxlen)
1531{
1532 QString line;
1533
1534 readLineInto(&line, maxlen);
1535 return line;
1536}
1537
1563bool QTextStream::readLineInto(QString *line, qint64 maxlen)
1564{
1565 Q_D(QTextStream);
1566 // keep in sync with CHECK_VALID_STREAM
1567 if (!d->string && !d->device) {
1568 qWarning("QTextStream: No device");
1569 if (line && !line->isNull())
1570 line->resize(0);
1571 return false;
1572 }
1573
1574 const QChar *readPtr;
1575 int length;
1576 if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) {
1577 if (line && !line->isNull())
1578 line->resize(0);
1579 return false;
1580 }
1581
1582 if (Q_LIKELY(line))
1583 line->setUnicode(readPtr, length);
1584 d->consumeLastToken();
1585 return true;
1586}
1587
1596QString QTextStream::read(qint64 maxlen)
1597{
1598 Q_D(QTextStream);
1600
1601 if (maxlen <= 0)
1602 return QString::fromLatin1(""); // empty, not null
1603
1604 return d->read(int(maxlen));
1605}
1606
1611{
1612 scan(nullptr, nullptr, 0, NotSpace);
1614
1615 // detect int encoding
1616 int base = params.integerBase;
1617 if (base == 0) {
1618 QChar ch;
1619 if (!getChar(&ch))
1620 return npsInvalidPrefix;
1621 if (ch == u'0') {
1622 QChar ch2;
1623 if (!getChar(&ch2)) {
1624 // Result is the number 0
1625 *ret = 0;
1626 return npsOk;
1627 }
1628 ch2 = ch2.toLower();
1629
1630 if (ch2 == u'x') {
1631 base = 16;
1632 } else if (ch2 == u'b') {
1633 base = 2;
1634 } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
1635 base = 8;
1636 } else {
1637 base = 10;
1638 }
1639 ungetChar(ch2);
1640 } else if (ch == locale.negativeSign() || ch == locale.positiveSign() || ch.isDigit()) {
1641 base = 10;
1642 } else {
1643 ungetChar(ch);
1644 return npsInvalidPrefix;
1645 }
1646 ungetChar(ch);
1647 // State of the stream is now the same as on entry
1648 // (cursor is at prefix),
1649 // and local variable 'base' has been set appropriately.
1650 }
1651
1652 qulonglong val=0;
1653 switch (base) {
1654 case 2: {
1655 QChar pf1, pf2, dig;
1656 // Parse prefix '0b'
1657 if (!getChar(&pf1) || pf1 != u'0')
1658 return npsInvalidPrefix;
1659 if (!getChar(&pf2) || pf2.toLower() != u'b')
1660 return npsInvalidPrefix;
1661 // Parse digits
1662 int ndigits = 0;
1663 while (getChar(&dig)) {
1664 int n = dig.toLower().unicode();
1665 if (n == '0' || n == '1') {
1666 val <<= 1;
1667 val += n - '0';
1668 } else {
1669 ungetChar(dig);
1670 break;
1671 }
1672 ndigits++;
1673 }
1674 if (ndigits == 0) {
1675 // Unwind the prefix and abort
1676 ungetChar(pf2);
1677 ungetChar(pf1);
1678 return npsMissingDigit;
1679 }
1680 break;
1681 }
1682 case 8: {
1683 QChar pf, dig;
1684 // Parse prefix '0'
1685 if (!getChar(&pf) || pf != u'0')
1686 return npsInvalidPrefix;
1687 // Parse digits
1688 int ndigits = 0;
1689 while (getChar(&dig)) {
1690 int n = dig.toLower().unicode();
1691 if (isOctalDigit(n)) {
1692 val *= 8;
1693 val += n - '0';
1694 } else {
1695 ungetChar(dig);
1696 break;
1697 }
1698 ndigits++;
1699 }
1700 if (ndigits == 0) {
1701 // Unwind the prefix and abort
1702 ungetChar(pf);
1703 return npsMissingDigit;
1704 }
1705 break;
1706 }
1707 case 10: {
1708 // Parse sign (or first digit)
1709 QChar sign;
1710 int ndigits = 0;
1711 if (!getChar(&sign))
1712 return npsMissingDigit;
1713 if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1714 if (!sign.isDigit()) {
1715 ungetChar(sign);
1716 return npsMissingDigit;
1717 }
1718 val += sign.digitValue();
1719 ndigits++;
1720 }
1721 // Parse digits
1722 QChar ch;
1723 while (getChar(&ch)) {
1724 if (ch.isDigit()) {
1725 val *= 10;
1726 val += ch.digitValue();
1727 } else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
1728 continue;
1729 } else {
1730 ungetChar(ch);
1731 break;
1732 }
1733 ndigits++;
1734 }
1735 if (ndigits == 0)
1736 return npsMissingDigit;
1737 if (sign == locale.negativeSign()) {
1738 qlonglong ival = qlonglong(val);
1739 if (ival > 0)
1740 ival = -ival;
1741 val = qulonglong(ival);
1742 }
1743 break;
1744 }
1745 case 16: {
1746 QChar pf1, pf2, dig;
1747 // Parse prefix ' 0x'
1748 if (!getChar(&pf1) || pf1 != u'0')
1749 return npsInvalidPrefix;
1750 if (!getChar(&pf2) || pf2.toLower() != u'x')
1751 return npsInvalidPrefix;
1752 // Parse digits
1753 int ndigits = 0;
1754 while (getChar(&dig)) {
1755 const int h = fromHex(dig.unicode());
1756 if (h != -1) {
1757 val <<= 4;
1758 val += h;
1759 } else {
1760 ungetChar(dig);
1761 break;
1762 }
1763 ndigits++;
1764 }
1765 if (ndigits == 0) {
1766 return npsMissingDigit;
1767 }
1768 break;
1769 }
1770 default:
1771 // Unsupported integerBase
1772 return npsInvalidPrefix;
1773 }
1774
1775 if (ret)
1776 *ret = val;
1777 return npsOk;
1778}
1779
1785{
1786 // We use a table-driven FSM to parse floating point numbers
1787 // strtod() cannot be used directly since we may be reading from a
1788 // QIODevice.
1789 enum ParserState {
1790 Init = 0,
1791 Sign = 1,
1792 Mantissa = 2,
1793 Dot = 3,
1794 Abscissa = 4,
1795 ExpMark = 5,
1796 ExpSign = 6,
1797 Exponent = 7,
1798 Nan1 = 8,
1799 Nan2 = 9,
1800 Inf1 = 10,
1801 Inf2 = 11,
1802 NanInf = 12,
1803 Done = 13
1804 };
1805 enum InputToken {
1806 None = 0,
1807 InputSign = 1,
1808 InputDigit = 2,
1809 InputDot = 3,
1810 InputExp = 4,
1811 InputI = 5,
1812 InputN = 6,
1813 InputF = 7,
1814 InputA = 8,
1815 InputT = 9
1816 };
1817
1818 static const uchar table[13][10] = {
1819 // None InputSign InputDigit InputDot InputExp InputI InputN InputF InputA InputT
1820 { 0, Sign, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 0 Init
1821 { 0, 0, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 1 Sign
1822 { Done, Done, Mantissa, Dot, ExpMark, 0, 0, 0, 0, 0 }, // 2 Mantissa
1823 { 0, 0, Abscissa, 0, 0, 0, 0, 0, 0, 0 }, // 3 Dot
1824 { Done, Done, Abscissa, Done, ExpMark, 0, 0, 0, 0, 0 }, // 4 Abscissa
1825 { 0, ExpSign, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 5 ExpMark
1826 { 0, 0, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 6 ExpSign
1827 { Done, Done, Exponent, Done, Done, 0, 0, 0, 0, 0 }, // 7 Exponent
1828 { 0, 0, 0, 0, 0, 0, 0, 0, Nan2, 0 }, // 8 Nan1
1829 { 0, 0, 0, 0, 0, 0, NanInf, 0, 0, 0 }, // 9 Nan2
1830 { 0, 0, 0, 0, 0, 0, Inf2, 0, 0, 0 }, // 10 Inf1
1831 { 0, 0, 0, 0, 0, 0, 0, NanInf, 0, 0 }, // 11 Inf2
1832 { Done, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 11 NanInf
1833 };
1834
1835 ParserState state = Init;
1836 InputToken input = None;
1837
1838 scan(nullptr, nullptr, 0, NotSpace);
1840
1841 const int BufferSize = 128;
1842 char buf[BufferSize];
1843 int i = 0;
1844
1845 QChar c;
1846 while (getChar(&c)) {
1847 switch (c.unicode()) {
1848 case '0': case '1': case '2': case '3': case '4':
1849 case '5': case '6': case '7': case '8': case '9':
1850 input = InputDigit;
1851 break;
1852 case 'i': case 'I':
1853 input = InputI;
1854 break;
1855 case 'n': case 'N':
1856 input = InputN;
1857 break;
1858 case 'f': case 'F':
1859 input = InputF;
1860 break;
1861 case 'a': case 'A':
1862 input = InputA;
1863 break;
1864 case 't': case 'T':
1865 input = InputT;
1866 break;
1867 default: {
1868 QChar lc = c.toLower();
1869 if (lc == locale.decimalPoint().toLower())
1870 input = InputDot;
1871 else if (lc == locale.exponential().toLower())
1872 input = InputExp;
1873 else if (lc == locale.negativeSign().toLower()
1874 || lc == locale.positiveSign().toLower())
1875 input = InputSign;
1876 else if (locale != QLocale::c() // backward-compatibility
1877 && lc == locale.groupSeparator().toLower())
1878 input = InputDigit; // well, it isn't a digit, but no one cares.
1879 else
1880 input = None;
1881 }
1882 break;
1883 }
1884
1885 state = ParserState(table[state][input]);
1886
1887 if (state == Init || state == Done || i > (BufferSize - 5)) {
1888 ungetChar(c);
1889 if (i > (BufferSize - 5)) { // ignore rest of digits
1890 while (getChar(&c)) {
1891 if (!c.isDigit()) {
1892 ungetChar(c);
1893 break;
1894 }
1895 }
1896 }
1897 break;
1898 }
1899
1900 buf[i++] = c.toLatin1();
1901 }
1902
1903 if (i == 0)
1904 return false;
1905 if (!f)
1906 return true;
1907 buf[i] = '\0';
1908
1909 // backward-compatibility. Old implementation supported +nan/-nan
1910 // for some reason. QLocale only checks for lower-case
1911 // nan/+inf/-inf, so here we also check for uppercase and mixed
1912 // case versions.
1913 if (!qstricmp(buf, "nan") || !qstricmp(buf, "+nan") || !qstricmp(buf, "-nan")) {
1914 *f = qQNaN();
1915 return true;
1916 } else if (!qstricmp(buf, "+inf") || !qstricmp(buf, "inf")) {
1917 *f = qInf();
1918 return true;
1919 } else if (!qstricmp(buf, "-inf")) {
1920 *f = -qInf();
1921 return true;
1922 }
1923 bool ok;
1925 return ok;
1926}
1927
1938QTextStream &QTextStream::operator>>(QChar &c)
1939{
1940 Q_D(QTextStream);
1941 CHECK_VALID_STREAM(*this);
1942 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
1943 if (!d->getChar(&c))
1944 setStatus(ReadPastEnd);
1945 return *this;
1946}
1947
1957QTextStream &QTextStream::operator>>(char &c)
1958{
1959 QChar ch;
1960 *this >> ch;
1961 c = ch.toLatin1();
1962 return *this;
1963}
1964
1997QTextStream &QTextStream::operator>>(signed short &i)
1998{
2000}
2001
2007QTextStream &QTextStream::operator>>(unsigned short &i)
2008{
2010}
2011
2017QTextStream &QTextStream::operator>>(signed int &i)
2018{
2020}
2021
2027QTextStream &QTextStream::operator>>(unsigned int &i)
2028{
2030}
2031
2037QTextStream &QTextStream::operator>>(signed long &i)
2038{
2040}
2041
2047QTextStream &QTextStream::operator>>(unsigned long &i)
2048{
2050}
2051
2057QTextStream &QTextStream::operator>>(qlonglong &i)
2058{
2060}
2061
2067QTextStream &QTextStream::operator>>(qulonglong &i)
2068{
2070}
2071
2083QTextStream &QTextStream::operator>>(float &f)
2084{
2086}
2087
2093QTextStream &QTextStream::operator>>(double &f)
2094{
2096}
2097
2105QTextStream &QTextStream::operator>>(QString &str)
2106{
2107 Q_D(QTextStream);
2108 CHECK_VALID_STREAM(*this);
2109
2110 str.clear();
2111 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2112 d->consumeLastToken();
2113
2114 const QChar *ptr;
2115 int length;
2116 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2117 setStatus(ReadPastEnd);
2118 return *this;
2119 }
2120
2121 str = QString(ptr, length);
2122 d->consumeLastToken();
2123 return *this;
2124}
2125
2133QTextStream &QTextStream::operator>>(QByteArray &array)
2134{
2135 Q_D(QTextStream);
2136 CHECK_VALID_STREAM(*this);
2137
2138 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2139 d->consumeLastToken();
2140
2141 const QChar *ptr;
2142 int length;
2143 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2144 setStatus(ReadPastEnd);
2145 array.clear();
2146 return *this;
2147 }
2148
2150
2151 d->consumeLastToken();
2152 return *this;
2153}
2154
2169QTextStream &QTextStream::operator>>(char *c)
2170{
2171 Q_D(QTextStream);
2172 *c = 0;
2173 CHECK_VALID_STREAM(*this);
2174 d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
2175 d->consumeLastToken();
2176
2177 const QChar *ptr;
2178 int length;
2179 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2180 setStatus(ReadPastEnd);
2181 return *this;
2182 }
2183
2185 char *e = encoder.appendToBuffer(c, QStringView(ptr, length));
2186 *e = '\0';
2187 d->consumeLastToken();
2188 return *this;
2189}
2190
2195{
2197
2198 unsigned flags = 0;
2199 const QTextStream::NumberFlags numberFlags = params.numberFlags;
2200 if (numberFlags & QTextStream::ShowBase)
2202 if (numberFlags & QTextStream::ForceSign)
2204 if (numberFlags & QTextStream::UppercaseBase)
2206 if (numberFlags & QTextStream::UppercaseDigits)
2208
2209 // add thousands group separators. For backward compatibility we
2210 // don't add a group separator for C locale.
2213
2214 const QLocaleData *dd = locale.d->m_data;
2215 int base = params.integerBase ? params.integerBase : 10;
2216 if (negative && base == 10) {
2217 result = dd->longLongToString(-static_cast<qlonglong>(number), -1,
2218 base, -1, flags);
2219 } else if (negative) {
2220 // Workaround for backward compatibility for writing negative
2221 // numbers in octal and hex:
2222 // QTextStream(result) << Qt::showbase << Qt::hex << -1 << oct << -1
2223 // should output: -0x1 -0b1
2224 result = dd->unsLongLongToString(number, -1, base, -1, flags);
2226 } else {
2227 result = dd->unsLongLongToString(number, -1, base, -1, flags);
2228 // workaround for backward compatibility - in octal form with
2229 // ShowBase flag set zero should be written as '00'
2230 if (number == 0 && base == 8 && params.numberFlags & QTextStream::ShowBase
2231 && result == "0"_L1) {
2232 result.prepend(u'0');
2233 }
2234 }
2235 putString(result, true);
2236}
2237
2244QTextStream &QTextStream::operator<<(QChar c)
2245{
2246 Q_D(QTextStream);
2247 CHECK_VALID_STREAM(*this);
2248 d->putChar(c);
2249 return *this;
2250}
2251
2257QTextStream &QTextStream::operator<<(char c)
2258{
2259 Q_D(QTextStream);
2260 CHECK_VALID_STREAM(*this);
2261 d->putChar(QChar::fromLatin1(c));
2262 return *this;
2263}
2264
2282QTextStream &QTextStream::operator<<(signed short i)
2283{
2284 Q_D(QTextStream);
2285 CHECK_VALID_STREAM(*this);
2286 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2287 return *this;
2288}
2289
2295QTextStream &QTextStream::operator<<(unsigned short i)
2296{
2297 Q_D(QTextStream);
2298 CHECK_VALID_STREAM(*this);
2299 d->putNumber((qulonglong)i, false);
2300 return *this;
2301}
2302
2308QTextStream &QTextStream::operator<<(signed int i)
2309{
2310 Q_D(QTextStream);
2311 CHECK_VALID_STREAM(*this);
2312 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2313 return *this;
2314}
2315
2321QTextStream &QTextStream::operator<<(unsigned int i)
2322{
2323 Q_D(QTextStream);
2324 CHECK_VALID_STREAM(*this);
2325 d->putNumber((qulonglong)i, false);
2326 return *this;
2327}
2328
2334QTextStream &QTextStream::operator<<(signed long i)
2335{
2336 Q_D(QTextStream);
2337 CHECK_VALID_STREAM(*this);
2338 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
2339 return *this;
2340}
2341
2347QTextStream &QTextStream::operator<<(unsigned long i)
2348{
2349 Q_D(QTextStream);
2350 CHECK_VALID_STREAM(*this);
2351 d->putNumber((qulonglong)i, false);
2352 return *this;
2353}
2354
2360QTextStream &QTextStream::operator<<(qlonglong i)
2361{
2362 Q_D(QTextStream);
2363 CHECK_VALID_STREAM(*this);
2364 d->putNumber((qulonglong)qAbs(i), i < 0);
2365 return *this;
2366}
2367
2373QTextStream &QTextStream::operator<<(qulonglong i)
2374{
2375 Q_D(QTextStream);
2376 CHECK_VALID_STREAM(*this);
2377 d->putNumber(i, false);
2378 return *this;
2379}
2380
2392QTextStream &QTextStream::operator<<(float f)
2393{
2394 return *this << double(f);
2395}
2396
2402QTextStream &QTextStream::operator<<(double f)
2403{
2404 Q_D(QTextStream);
2405 CHECK_VALID_STREAM(*this);
2406
2408 switch (realNumberNotation()) {
2409 case FixedNotation:
2411 break;
2412 case ScientificNotation:
2414 break;
2415 case SmartNotation:
2417 break;
2418 }
2419
2420 uint flags = 0;
2421 const QLocale::NumberOptions numberOptions = locale().numberOptions();
2422 if (numberFlags() & ShowBase)
2424 if (numberFlags() & ForceSign)
2426 if (numberFlags() & UppercaseBase)
2428 if (numberFlags() & UppercaseDigits)
2430 if (numberFlags() & ForcePoint) {
2432
2433 // Only for backwards compatibility
2435 }
2436 if (locale() != QLocale::c() && !(numberOptions & QLocale::OmitGroupSeparator))
2438 if (!(numberOptions & QLocale::OmitLeadingZeroInExponent))
2440 if (numberOptions & QLocale::IncludeTrailingZeroesAfterDot)
2442
2443 const QLocaleData *dd = d->locale.d->m_data;
2444 QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
2445 d->putString(num, true);
2446 return *this;
2447}
2448
2456QTextStream &QTextStream::operator<<(const QString &string)
2457{
2458 Q_D(QTextStream);
2459 CHECK_VALID_STREAM(*this);
2460 d->putString(string);
2461 return *this;
2462}
2463
2471QTextStream &QTextStream::operator<<(QStringView string)
2472{
2473 Q_D(QTextStream);
2474 CHECK_VALID_STREAM(*this);
2475 d->putString(string.cbegin(), int(string.size()));
2476 return *this;
2477}
2478
2485QTextStream &QTextStream::operator<<(QLatin1StringView string)
2486{
2487 Q_D(QTextStream);
2488 CHECK_VALID_STREAM(*this);
2489 d->putString(string);
2490 return *this;
2491}
2492
2499QTextStream &QTextStream::operator<<(const QByteArray &array)
2500{
2501 Q_D(QTextStream);
2502 CHECK_VALID_STREAM(*this);
2503 d->putString(QString::fromUtf8(array.constData(), array.size()));
2504 return *this;
2505}
2506
2520QTextStream &QTextStream::operator<<(const char *string)
2521{
2522 Q_D(QTextStream);
2523 CHECK_VALID_STREAM(*this);
2524 d->putString(QUtf8StringView(string));
2525 return *this;
2526}
2527
2534QTextStream &QTextStream::operator<<(const void *ptr)
2535{
2536 Q_D(QTextStream);
2537 CHECK_VALID_STREAM(*this);
2538 const int oldBase = d->params.integerBase;
2539 const NumberFlags oldFlags = d->params.numberFlags;
2540 d->params.integerBase = 16;
2541 d->params.numberFlags |= ShowBase;
2542 d->putNumber(reinterpret_cast<quintptr>(ptr), false);
2543 d->params.integerBase = oldBase;
2544 d->params.numberFlags = oldFlags;
2545 return *this;
2546}
2547
2548namespace Qt {
2549
2559{
2560 stream.setIntegerBase(2);
2561 return stream;
2562}
2563
2573{
2574 stream.setIntegerBase(8);
2575 return stream;
2576}
2577
2587{
2588 stream.setIntegerBase(10);
2589 return stream;
2590}
2591
2602{
2603 stream.setIntegerBase(16);
2604 return stream;
2605}
2606
2616{
2617 stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase);
2618 return stream;
2619}
2620
2630{
2631 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign);
2632 return stream;
2633}
2634
2644{
2645 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForcePoint);
2646 return stream;
2647}
2648
2658{
2659 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ShowBase);
2660 return stream;
2661}
2662
2672{
2673 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForceSign);
2674 return stream;
2675}
2676
2686{
2687 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForcePoint);
2688 return stream;
2689}
2690
2700{
2701 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseBase);
2702 return stream;
2703}
2704
2714{
2715 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseDigits);
2716 return stream;
2717}
2718
2728{
2729 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseBase);
2730 return stream;
2731}
2732
2742{
2743 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseDigits);
2744 return stream;
2745}
2746
2756{
2757 stream.setRealNumberNotation(QTextStream::FixedNotation);
2758 return stream;
2759}
2760
2770{
2771 stream.setRealNumberNotation(QTextStream::ScientificNotation);
2772 return stream;
2773}
2774
2784{
2785 stream.setFieldAlignment(QTextStream::AlignLeft);
2786 return stream;
2787}
2788
2798{
2799 stream.setFieldAlignment(QTextStream::AlignRight);
2800 return stream;
2801}
2802
2812{
2813 stream.setFieldAlignment(QTextStream::AlignCenter);
2814 return stream;
2815}
2816
2832{
2833 return stream << '\n'_L1 << Qt::flush;
2834}
2835
2844{
2845 stream.flush();
2846 return stream;
2847}
2848
2857{
2858 stream.reset();
2859 return stream;
2860}
2861
2870{
2871 stream.skipWhiteSpace();
2872 return stream;
2873}
2874
2875} // namespace Qt
2876
2899namespace Qt {
2909{
2910 stream.setGenerateByteOrderMark(true);
2911 return stream;
2912}
2913
2914} // namespace Qt
2915
2916
2932void QTextStream::setEncoding(QStringConverter::Encoding encoding)
2933{
2934 Q_D(QTextStream);
2935 if (d->encoding == encoding)
2936 return;
2937
2938 qint64 seekPos = -1;
2939 if (!d->readBuffer.isEmpty()) {
2940 if (!d->device->isSequential()) {
2941 seekPos = pos();
2942 }
2943 }
2944
2945 d->encoding = encoding;
2946 d->toUtf16 = QStringDecoder(d->encoding);
2947 bool generateBOM = !d->hasWrittenData && d->generateBOM;
2948 d->fromUtf16 = QStringEncoder(d->encoding,
2950
2951 if (seekPos >=0 && !d->readBuffer.isEmpty())
2952 seek(seekPos);
2953}
2954
2960QStringConverter::Encoding QTextStream::encoding() const
2961{
2962 Q_D(const QTextStream);
2963 return d->encoding;
2964}
2965
2977void QTextStream::setAutoDetectUnicode(bool enabled)
2978{
2979 Q_D(QTextStream);
2980 d->autoDetectUnicode = enabled;
2981}
2982
2989bool QTextStream::autoDetectUnicode() const
2990{
2991 Q_D(const QTextStream);
2992 return d->autoDetectUnicode;
2993}
2994
3003void QTextStream::setGenerateByteOrderMark(bool generate)
3004{
3005 Q_D(QTextStream);
3006 if (d->hasWrittenData || d->generateBOM == generate)
3007 return;
3008
3009 d->generateBOM = generate;
3010 d->fromUtf16 = QStringEncoder(d->encoding, generate ? QStringConverter::Flag::WriteBom : QStringConverter::Flag::Default);
3011}
3012
3020bool QTextStream::generateByteOrderMark() const
3021{
3022 Q_D(const QTextStream);
3023 return d->generateBOM;
3024}
3025
3037void QTextStream::setLocale(const QLocale &locale)
3038{
3039 Q_D(QTextStream);
3040 d->locale = locale;
3041}
3042
3050QLocale QTextStream::locale() const
3051{
3052 Q_D(const QTextStream);
3053 return d->locale;
3054}
3055
3057
3058#ifndef QT_NO_QOBJECT
3059#include "moc_qtextstream_p.cpp"
3060#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
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
\inmodule QtCore
Definition qchar.h:48
constexpr bool isDigit() const noexcept
Returns true if the character is a decimal digit (Number_DecimalDigit); otherwise returns false.
Definition qchar.h:473
QChar toLower() const noexcept
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition qchar.h:448
int digitValue() const noexcept
Returns the numeric value of the digit, or -1 if the character is not a digit.
Definition qchar.h:447
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
Definition qchar.h:458
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
Definition qchar.h:461
\inmodule QtCore
Definition qfiledevice.h:16
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
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:881
\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:512
QString decimalPoint() const
Definition qlocale.cpp:2535
double toDouble(const QString &s, bool *ok=nullptr) const
Returns the double represented by the localized string s.
Definition qlocale.h:950
QString negativeSign() const
Definition qlocale.cpp:2607
QString groupSeparator() const
Definition qlocale.cpp:2554
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition qlocale.h:1103
QString exponential() const
Definition qlocale.cpp:2642
QString positiveSign() const
Definition qlocale.cpp:2624
NumberOptions numberOptions() const
Definition qlocale.cpp:1155
@ OmitGroupSeparator
Definition qlocale.h:869
@ IncludeTrailingZeroesAfterDot
Definition qlocale.h:873
@ OmitLeadingZeroInExponent
Definition qlocale.h:871
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:1548
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:76
QByteArray toUtf8() const
Returns a UTF-8 representation of the string view as a QByteArray.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
QString & setUnicode(const QChar *unicode, qsizetype size)
Resizes the string to size characters and copies unicode into the string.
Definition qstring.cpp:5938
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QString toLower() const &
Definition qstring.h:368
QString & prepend(QChar c)
Definition qstring.h:411
void resize(qsizetype size)
Sets the size of the string to size characters.
Definition qstring.cpp:2654
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]
double e
else opt state
[0]
Q_QML_PRIVATE_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:29
constexpr bool isOctalDigit(char32_t c) noexcept
Definition qtools_p.h:57
constexpr int fromHex(char32_t c) noexcept
Definition qtools_p.h:44
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:275
Q_CORE_EXPORT int qstricmp(const char *, const char *)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
static constexpr int BufferSize
EGLStreamKHR stream
#define Q_VOID
Definition qiodevice.cpp:46
#define qDebug
[1]
Definition qlogging.h:160
#define qWarning
Definition qlogging.h:162
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
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
GLenum GLsizei GLuint GLint * bytesWritten
GLenum mode
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
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
GLfloat GLfloat GLfloat GLfloat h
void ** params
GLboolean reset
const GLubyte * c
GLuint GLfloat * val
GLenum array
GLenum GLsizei len
GLuint writeBuffer
GLuint64EXT * result
[6]
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:25
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:27
size_t quintptr
Definition qtypes.h:72
quint64 qulonglong
Definition qtypes.h:59
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
qint64 qlonglong
Definition qtypes.h:58
#define enabled
static int sign(int x)
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:17
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3546
@ AddTrailingZeroes
Definition qlocale_p.h:234
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3785
@ DFSignificantDigits
Definition qlocale_p.h:228
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3800