10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
137
138
139
140
141
142
143
144
145
146
149
150
151
152
153
154
155
156
157
158
159
160
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
180
181
182
183
184
185
186
187
188
189
190
193#include "private/qtextstream_p.h"
198#include <private/qdebug_p.h>
199#include <private/qnumeric_p.h>
200#include <private/qtools_p.h>
203#include "private/qlocale_p.h"
204#include "private/qstringconverter_p.h"
212#define CHECK_VALID_STREAM(x) do {
213 if (!d->string && !d->device) {
214 qWarning("QTextStream: No device");
219#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type) do {
223 switch (d->getNumber(&tmp)) {
224 case QTextStreamPrivate::npsOk:
227 case QTextStreamPrivate::npsMissingDigit:
228 case QTextStreamPrivate::npsInvalidPrefix:
230 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData);
233 return *this; } while (0
)
235#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type) do {
239 if (d->getReal(&tmp)) {
243 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData);
245 return *this; } while (0
)
249using namespace Qt::StringLiterals;
250using namespace QtMiscUtils;
253QDeviceClosedNotifier::~QDeviceClosedNotifier()
260
261
262QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
263 : readConverterSavedStateOffset(0),
271
272
273QTextStreamPrivate::~QTextStreamPrivate()
277 device->blockSignals(
true);
283void QTextStreamPrivate::Params::reset()
285 realNumberPrecision = 6;
289 fieldAlignment = QTextStream::AlignRight;
290 realNumberNotation = QTextStream::SmartNotation;
295
296
297void QTextStreamPrivate::reset()
302 deleteDevice =
false;
305 stringOpenMode = QTextStream::NotOpen;
307 readBufferOffset = 0;
308 readBufferStartDevicePos = 0;
311 hasWrittenData =
false;
313 encoding = QStringConverter::Utf8;
314 toUtf16 = QStringDecoder(encoding);
315 fromUtf16 = QStringEncoder(encoding);
316 autoDetectUnicode =
true;
320
321
322bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
330 bool textModeEnabled = device->isTextModeEnabled();
332 device->setTextModeEnabled(
false);
335 char buf[QTEXTSTREAM_BUFFERSIZE];
336 qint64 bytesRead = 0;
343 if (device->isSequential()
344#if !defined(QT_NO_QOBJECT)
345 && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
349 bytesRead = device->readLine(buf, qMin<qint64>(
sizeof(buf), maxBytes));
351 bytesRead = device->readLine(buf,
sizeof(buf));
356 bytesRead = device->read(buf, qMin<qint64>(
sizeof(buf), maxBytes));
358 bytesRead = device->read(buf,
sizeof(buf));
363 device->setTextModeEnabled(
true);
368#ifndef QT_BOOTSTRAPPED
369 if (autoDetectUnicode) {
370 autoDetectUnicode =
false;
372 auto e = QStringConverter::encodingForData(QByteArrayView(buf, bytesRead));
376 toUtf16 = QStringDecoder(encoding);
377 fromUtf16 = QStringEncoder(encoding);
380#if defined (QTEXTSTREAM_DEBUG)
381 qDebug(
"QTextStreamPrivate::fillReadBuffer(), using %s encoding", QStringConverter::nameForEncoding(encoding));
385#if defined (QTEXTSTREAM_DEBUG)
386 qDebug(
"QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
387 QtDebugUtils::toPrintable(buf, bytesRead, 32).constData(),
int(
sizeof(buf)),
int(bytesRead));
390 int oldReadBufferSize = readBuffer.size();
391 readBuffer += toUtf16(QByteArrayView(buf, bytesRead));
394 if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
396 QChar *writePtr = readBuffer.data() + oldReadBufferSize;
397 QChar *readPtr = readBuffer.data() + oldReadBufferSize;
398 QChar *endPtr = readBuffer.data() + readBuffer.size();
400 int n = oldReadBufferSize;
401 if (readPtr < endPtr) {
403 while (*readPtr++ != CR) {
405 if (++writePtr == endPtr)
409 while (readPtr < endPtr) {
410 QChar ch = *readPtr++;
414 if (n < readBufferOffset)
420 readBuffer.resize(writePtr - readBuffer.data());
423#if defined (QTEXTSTREAM_DEBUG)
424 qDebug(
"QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]",
int(bytesRead),
425 QtDebugUtils::toPrintable(readBuffer.toLatin1(), readBuffer.size(), readBuffer.size()).constData());
431
432
433void QTextStreamPrivate::resetReadBuffer()
436 readBufferOffset = 0;
437 readBufferStartDevicePos = (device ? device->pos() : 0);
441
442
443void QTextStreamPrivate::flushWriteBuffer()
447 if (string || !device)
452 if (status != QTextStream::Ok)
455 if (writeBuffer.isEmpty())
458#if defined (Q_OS_WIN)
460 bool textModeEnabled = device->isTextModeEnabled();
461 if (textModeEnabled) {
462 device->setTextModeEnabled(
false);
463 writeBuffer.replace(u'\n',
"\r\n"_L1);
467 QByteArray data = fromUtf16(writeBuffer);
469 hasWrittenData =
true;
472 qint64 bytesWritten = device->write(data);
473#if defined (QTEXTSTREAM_DEBUG)
474 qDebug(
"QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
475 QtDebugUtils::toPrintable(data.constData(), data.size(), 32).constData(),
int(bytesWritten));
478#if defined (Q_OS_WIN)
481 device->setTextModeEnabled(
true);
484 if (bytesWritten <= 0) {
485 status = QTextStream::WriteFailed;
491 QFileDevice *file = qobject_cast<QFileDevice *>(device);
492 bool flushed = !file || file->flush();
497#if defined (QTEXTSTREAM_DEBUG)
498 qDebug(
"QTextStreamPrivate::flushWriteBuffer() wrote %d bytes",
501 if (!flushed || bytesWritten != qint64(data.size()))
502 status = QTextStream::WriteFailed;
505QString QTextStreamPrivate::read(
int maxlen)
509 lastTokenSize = qMin(maxlen, string->size() - stringOffset);
510 ret = string->mid(stringOffset, lastTokenSize);
512 while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) ;
513 lastTokenSize = qMin(maxlen, readBuffer.size() - readBufferOffset);
514 ret = readBuffer.mid(readBufferOffset, lastTokenSize);
518#if defined (QTEXTSTREAM_DEBUG)
519 qDebug(
"QTextStreamPrivate::read() maxlen = %d, token length = %d", maxlen, ret.length());
525
526
527
528
529
530
531bool QTextStreamPrivate::scan(
const QChar **ptr,
int *length,
int maxlen, TokenDelimiter delimiter)
535 bool consumeDelimiter =
false;
536 bool foundToken =
false;
537 int startOffset = device ? readBufferOffset : stringOffset;
544 chPtr = readBuffer.constData();
545 endOffset = readBuffer.size();
547 chPtr = string->constData();
548 endOffset = string->size();
550 chPtr += startOffset;
552 for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
553 const QChar ch = *chPtr++;
572 delimSize = (lastChar == u'\r') ? 2 : 1;
573 consumeDelimiter =
true;
580 && (!maxlen || totalSize < maxlen)
581 && device && fillReadBuffer());
583 if (totalSize == 0) {
584#if defined (QTEXTSTREAM_DEBUG)
585 qDebug(
"QTextStreamPrivate::scan() reached the end of input.");
592 if (delimiter == EndOfLine && totalSize > 0 && !foundToken) {
593 if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
594 && lastChar == u'\r') {
595 consumeDelimiter =
true;
602 *length = totalSize - delimSize;
608 lastTokenSize = totalSize;
609 if (!consumeDelimiter)
610 lastTokenSize -= delimSize;
612#if defined (QTEXTSTREAM_DEBUG)
613 qDebug(
"QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
614 ptr, length, maxlen, (
int)delimiter, totalSize - delimSize, delimSize);
620
621
622inline const QChar *QTextStreamPrivate::readPtr()
const
624 Q_ASSERT(readBufferOffset <= readBuffer.size());
626 return string->constData() + stringOffset;
627 return readBuffer.constData() + readBufferOffset;
631
632
633inline void QTextStreamPrivate::consumeLastToken()
636 consume(lastTokenSize);
641
642
643inline void QTextStreamPrivate::consume(
int size)
645#if defined (QTEXTSTREAM_DEBUG)
646 qDebug(
"QTextStreamPrivate::consume(%d)", size);
649 stringOffset += size;
650 if (stringOffset > string->size())
651 stringOffset = string->size();
653 readBufferOffset += size;
654 if (readBufferOffset >= readBuffer.size()) {
655 readBufferOffset = 0;
657 saveConverterState(device->pos());
658 }
else if (readBufferOffset > QTEXTSTREAM_BUFFERSIZE) {
659 readBuffer = readBuffer.remove(0,readBufferOffset);
660 readConverterSavedStateOffset += readBufferOffset;
661 readBufferOffset = 0;
667
668
669inline void QTextStreamPrivate::saveConverterState(qint64 newPos)
672 memcpy((
void *)&savedToUtf16, (
void *)&toUtf16,
sizeof(QStringDecoder));
673 readBufferStartDevicePos = newPos;
674 readConverterSavedStateOffset = 0;
678
679
680inline void QTextStreamPrivate::restoreToSavedConverterState()
682 if (savedToUtf16.isValid())
683 memcpy((
void *)&toUtf16, (
void *)&savedToUtf16,
sizeof(QStringDecoder));
685 toUtf16.resetState();
686 savedToUtf16 = QStringDecoder();
690
691
692void QTextStreamPrivate::write(
const QChar *data, qsizetype len)
696 string->append(data, len);
698 writeBuffer.append(data, len);
699 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
705
706
707inline void QTextStreamPrivate::write(QChar ch)
714 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
720
721
722void QTextStreamPrivate::write(QLatin1StringView data)
726 string->append(data);
729 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
735
736
737void QTextStreamPrivate::writePadding(qsizetype len)
741 string->resize(string->size() + len, params.padChar);
743 writeBuffer.resize(writeBuffer.size() + len, params.padChar);
744 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
750
751
752inline bool QTextStreamPrivate::getChar(QChar *ch)
754 if ((string && stringOffset == string->size())
755 || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
767
768
769inline void QTextStreamPrivate::ungetChar(QChar ch)
772 if (stringOffset == 0)
775 (*string)[--stringOffset] = ch;
779 if (readBufferOffset == 0) {
780 readBuffer.prepend(ch);
784 readBuffer[--readBufferOffset] = ch;
788
789
790inline void QTextStreamPrivate::putChar(QChar ch)
792 if (params.fieldWidth > 0)
800
801
802QTextStreamPrivate::PaddingResult QTextStreamPrivate::padding(qsizetype len)
const
804 Q_ASSERT(params.fieldWidth > len);
806 int left = 0, right = 0;
808 const int padSize = params.fieldWidth - len;
810 switch (params.fieldAlignment) {
811 case QTextStream::AlignLeft:
814 case QTextStream::AlignRight:
815 case QTextStream::AlignAccountingStyle:
818 case QTextStream::AlignCenter:
820 right = padSize - padSize/2;
823 return { left, right };
827
828
829void QTextStreamPrivate::putString(
const QChar *data, qsizetype len,
bool number)
831 if (Q_UNLIKELY(params.fieldWidth > len)) {
835 const PaddingResult pad = padding(len);
837 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
838 const QChar sign = len > 0 ? data[0] : QChar();
839 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
847 writePadding(pad.left);
849 writePadding(pad.right);
856
857
858void QTextStreamPrivate::putString(QLatin1StringView data,
bool number)
860 if (Q_UNLIKELY(params.fieldWidth > data.size())) {
864 const PaddingResult pad = padding(data.size());
866 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
867 const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
868 if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
871 data = QLatin1StringView(data.data() + 1, data.size() - 1);
875 writePadding(pad.left);
877 writePadding(pad.right);
883void QTextStreamPrivate::putString(QUtf8StringView data,
bool number)
885 putString(data.toString(), number);
889
890
891
892
893
894QTextStream::QTextStream()
895 : d_ptr(
new QTextStreamPrivate(
this))
897#if defined (QTEXTSTREAM_DEBUG)
898 qDebug(
"QTextStream::QTextStream()");
905
906
907QTextStream::QTextStream(QIODevice *device)
908 : d_ptr(
new QTextStreamPrivate(
this))
910#if defined (QTEXTSTREAM_DEBUG)
911 qDebug(
"QTextStream::QTextStream(QIODevice *device == *%p)",
917 d->deviceClosedNotifier.setupDevice(
this, d->device);
923
924
925
926QTextStream::QTextStream(QString *string, OpenMode openMode)
927 : d_ptr(
new QTextStreamPrivate(
this))
929#if defined (QTEXTSTREAM_DEBUG)
930 qDebug(
"QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
931 string,
int(openMode));
935 d->stringOpenMode = openMode;
939#ifndef QT_BOOTSTRAPPED
941
942
943
944
945QTextStream::QTextStream(QByteArray *array, OpenMode openMode)
946 : d_ptr(
new QTextStreamPrivate(
this))
948#if defined (QTEXTSTREAM_DEBUG)
949 qDebug(
"QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
950 array,
int(openMode));
953 d->device =
new QBuffer(array);
954 d->device->open(openMode);
955 d->deleteDevice =
true;
957 d->deviceClosedNotifier.setupDevice(
this, d->device);
963
964
965
966
967
968
969
970
971
972QTextStream::QTextStream(
const QByteArray &array, OpenMode openMode)
973 : d_ptr(
new QTextStreamPrivate(
this))
975#if defined (QTEXTSTREAM_DEBUG)
976 qDebug(
"QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
977 &array,
int(openMode));
979 QBuffer *buffer =
new QBuffer;
980 buffer->setData(array);
981 buffer->open(openMode);
985 d->deleteDevice =
true;
987 d->deviceClosedNotifier.setupDevice(
this, d->device);
994
995
996
997
998
999
1000
1001
1002
1004QTextStream::QTextStream(FILE *fileHandle, OpenMode openMode)
1005 : d_ptr(
new QTextStreamPrivate(
this))
1007#if defined (QTEXTSTREAM_DEBUG)
1008 qDebug(
"QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
1009 fileHandle,
int(openMode));
1011 QFile *file =
new QFile;
1015 (
void)file->open(fileHandle, openMode);
1019 d->deleteDevice =
true;
1020#ifndef QT_NO_QOBJECT
1021 d->deviceClosedNotifier.setupDevice(
this, d->device);
1027
1028
1029
1030
1031
1032QTextStream::~QTextStream()
1035#if defined (QTEXTSTREAM_DEBUG)
1036 qDebug(
"QTextStream::~QTextStream()");
1038 if (!d->writeBuffer.isEmpty())
1039 d->flushWriteBuffer();
1043
1044
1045
1046
1047void QTextStream::reset()
1055
1056
1057
1058
1059void QTextStream::flush()
1062 d->flushWriteBuffer();
1066
1067
1068
1069bool QTextStream::seek(qint64 pos)
1072 d->lastTokenSize = 0;
1076 d->flushWriteBuffer();
1077 if (!d->device->seek(pos))
1079 d->resetReadBuffer();
1081 d->toUtf16.resetState();
1082 d->fromUtf16.resetState();
1087 if (d->string && pos <= d->string->size()) {
1088 d->stringOffset =
int(pos);
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108qint64 QTextStream::pos()
const
1110 Q_D(
const QTextStream);
1113 if (d->readBuffer.isEmpty())
1114 return d->device->pos();
1115 if (d->device->isSequential())
1119 if (!d->device->seek(d->readBufferStartDevicePos))
1123 QTextStreamPrivate *thatd =
const_cast<QTextStreamPrivate *>(d);
1124 thatd->readBuffer.clear();
1126 thatd->restoreToSavedConverterState();
1127 if (d->readBufferStartDevicePos == 0)
1128 thatd->autoDetectUnicode =
true;
1132 int oldReadBufferOffset = d->readBufferOffset + d->readConverterSavedStateOffset;
1133 while (d->readBuffer.size() < oldReadBufferOffset) {
1134 if (!thatd->fillReadBuffer(1))
1137 thatd->readBufferOffset = oldReadBufferOffset;
1138 thatd->readConverterSavedStateOffset = 0;
1141 return d->device->pos();
1145 return d->stringOffset;
1147 qWarning(
"QTextStream::pos: no device");
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162void QTextStream::skipWhiteSpace()
1166 d->scan(
nullptr,
nullptr, 0, QTextStreamPrivate::NotSpace);
1167 d->consumeLastToken();
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180void QTextStream::setDevice(QIODevice *device)
1184 if (d->deleteDevice) {
1185#ifndef QT_NO_QOBJECT
1186 d->deviceClosedNotifier.disconnect();
1189 d->deleteDevice =
false;
1195 d->resetReadBuffer();
1196#ifndef QT_NO_QOBJECT
1197 d->deviceClosedNotifier.setupDevice(
this, d->device);
1202
1203
1204
1205
1206
1207QIODevice *QTextStream::device()
const
1209 Q_D(
const QTextStream);
1214
1215
1216
1217
1218
1219
1220void QTextStream::setString(QString *string, OpenMode openMode)
1224 if (d->deleteDevice) {
1225#ifndef QT_NO_QOBJECT
1226 d->deviceClosedNotifier.disconnect();
1227 d->device->blockSignals(
true);
1230 d->deleteDevice =
false;
1236 d->stringOpenMode = openMode;
1240
1241
1242
1243
1244
1245QString *QTextStream::string()
const
1247 Q_D(
const QTextStream);
1252
1253
1254
1255
1256
1257
1258
1259void QTextStream::setFieldAlignment(FieldAlignment mode)
1262 d->params.fieldAlignment = mode;
1266
1267
1268
1269
1270QTextStream::FieldAlignment QTextStream::fieldAlignment()
const
1272 Q_D(
const QTextStream);
1273 return d->params.fieldAlignment;
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291void QTextStream::setPadChar(QChar ch)
1294 d->params.padChar = ch;
1298
1299
1300
1301
1302QChar QTextStream::padChar()
const
1304 Q_D(
const QTextStream);
1305 return d->params.padChar;
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320void QTextStream::setFieldWidth(
int width)
1323 d->params.fieldWidth = width;
1327
1328
1329
1330
1331int QTextStream::fieldWidth()
const
1333 Q_D(
const QTextStream);
1334 return d->params.fieldWidth;
1338
1339
1340
1341
1342
1343
1344
1345void QTextStream::setNumberFlags(NumberFlags flags)
1348 d->params.numberFlags = flags;
1352
1353
1354
1355
1356QTextStream::NumberFlags QTextStream::numberFlags()
const
1358 Q_D(
const QTextStream);
1359 return d->params.numberFlags;
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372void QTextStream::setIntegerBase(
int base)
1375 d->params.integerBase = base;
1379
1380
1381
1382
1383
1384int QTextStream::integerBase()
const
1386 Q_D(
const QTextStream);
1387 return d->params.integerBase;
1391
1392
1393
1394
1395
1396
1397
1398void QTextStream::setRealNumberNotation(RealNumberNotation notation)
1401 d->params.realNumberNotation = notation;
1405
1406
1407
1408
1409QTextStream::RealNumberNotation QTextStream::realNumberNotation()
const
1411 Q_D(
const QTextStream);
1412 return d->params.realNumberNotation;
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425void QTextStream::setRealNumberPrecision(
int precision)
1428 if (precision < 0) {
1429 qWarning(
"QTextStream::setRealNumberPrecision: Invalid precision (%d)", precision);
1430 d->params.realNumberPrecision = 6;
1433 d->params.realNumberPrecision = precision;
1437
1438
1439
1440
1441
1442
1443
1444int QTextStream::realNumberPrecision()
const
1446 Q_D(
const QTextStream);
1447 return d->params.realNumberPrecision;
1451
1452
1453
1454
1456QTextStream::Status QTextStream::status()
const
1458 Q_D(
const QTextStream);
1463
1464
1465
1466
1467
1468
1469void QTextStream::resetStatus()
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485void QTextStream::setStatus(Status status)
1488 if (d->status == Ok)
1493
1494
1495
1496
1497
1498bool QTextStream::atEnd()
const
1500 Q_D(
const QTextStream);
1504 return d->string->size() == d->stringOffset;
1505 return d->readBuffer.isEmpty() && d->device->atEnd();
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518QString QTextStream::readAll()
1523 return d->read(INT_MAX);
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543QString QTextStream::readLine(qint64 maxlen)
1547 readLineInto(&line, maxlen);
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576bool QTextStream::readLineInto(QString *line, qint64 maxlen)
1580 if (!d->string && !d->device) {
1581 qWarning(
"QTextStream: No device");
1582 if (line && !line->isNull())
1587 const QChar *readPtr;
1589 if (!d->scan(&readPtr, &length,
int(maxlen), QTextStreamPrivate::EndOfLine)) {
1590 if (line && !line->isNull())
1596 line->setUnicode(readPtr, length);
1597 d->consumeLastToken();
1602
1603
1604
1605
1606
1607
1608
1609QString QTextStream::read(qint64 maxlen)
1615 return QString::fromLatin1(
"");
1617 return d->read(
int(maxlen));
1621
1622
1623QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret)
1625 scan(
nullptr,
nullptr, 0, NotSpace);
1629 int base = params.integerBase;
1633 return npsInvalidPrefix;
1636 if (!getChar(&ch2)) {
1641 ch2 = ch2.toLower();
1645 }
else if (ch2 == u'b') {
1647 }
else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
1653 }
else if (ch == locale.negativeSign() || ch == locale.positiveSign() || ch.isDigit()) {
1657 return npsInvalidPrefix;
1668 QChar pf1, pf2, dig;
1670 if (!getChar(&pf1) || pf1 != u'0')
1671 return npsInvalidPrefix;
1672 if (!getChar(&pf2) || pf2.toLower() != u'b')
1673 return npsInvalidPrefix;
1676 while (getChar(&dig)) {
1677 int n = dig.toLower().unicode();
1678 if (n ==
'0' || n ==
'1') {
1691 return npsMissingDigit;
1698 if (!getChar(&pf) || pf != u'0')
1699 return npsInvalidPrefix;
1702 while (getChar(&dig)) {
1703 int n = dig.toLower().unicode();
1704 if (isOctalDigit(n)) {
1716 return npsMissingDigit;
1724 if (!getChar(&sign))
1725 return npsMissingDigit;
1726 if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1727 if (!sign.isDigit()) {
1729 return npsMissingDigit;
1731 val += sign.digitValue();
1736 while (getChar(&ch)) {
1739 val += ch.digitValue();
1740 }
else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
1749 return npsMissingDigit;
1750 if (sign == locale.negativeSign()) {
1751 qlonglong ival = qlonglong(val);
1754 val = qulonglong(ival);
1759 QChar pf1, pf2, dig;
1761 if (!getChar(&pf1) || pf1 != u'0')
1762 return npsInvalidPrefix;
1763 if (!getChar(&pf2) || pf2.toLower() != u'x')
1764 return npsInvalidPrefix;
1767 while (getChar(&dig)) {
1768 const int h = fromHex(dig.unicode());
1779 return npsMissingDigit;
1785 return npsInvalidPrefix;
1794
1795
1796
1797bool QTextStreamPrivate::getReal(
double *f)
1831 static const uchar table[13][10] = {
1833 { 0, Sign, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 },
1834 { 0, 0, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 },
1835 { Done, Done, Mantissa, Dot, ExpMark, 0, 0, 0, 0, 0 },
1836 { 0, 0, Abscissa, 0, 0, 0, 0, 0, 0, 0 },
1837 { Done, Done, Abscissa, Done, ExpMark, 0, 0, 0, 0, 0 },
1838 { 0, ExpSign, Exponent, 0, 0, 0, 0, 0, 0, 0 },
1839 { 0, 0, Exponent, 0, 0, 0, 0, 0, 0, 0 },
1840 { Done, Done, Exponent, Done, Done, 0, 0, 0, 0, 0 },
1841 { 0, 0, 0, 0, 0, 0, 0, 0, Nan2, 0 },
1842 { 0, 0, 0, 0, 0, 0, NanInf, 0, 0, 0 },
1843 { 0, 0, 0, 0, 0, 0, Inf2, 0, 0, 0 },
1844 { 0, 0, 0, 0, 0, 0, 0, NanInf, 0, 0 },
1845 { Done, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1848 ParserState state = Init;
1849 InputToken input = None;
1851 scan(
nullptr,
nullptr, 0, NotSpace);
1854 const int BufferSize = 128;
1855 char buf[BufferSize];
1859 while (getChar(&c)) {
1860 switch (c.unicode()) {
1861 case '0':
case '1':
case '2':
case '3':
case '4':
1862 case '5':
case '6':
case '7':
case '8':
case '9':
1881 QChar lc = c.toLower();
1882 if (lc == locale.decimalPoint().toLower())
1884 else if (lc == locale.exponential().toLower())
1886 else if (lc == locale.negativeSign().toLower()
1887 || lc == locale.positiveSign().toLower())
1889 else if (locale != QLocale::c()
1890 && lc == locale.groupSeparator().toLower())
1898 state = ParserState(table[state][input]);
1900 if (state == Init || state == Done || i > (BufferSize - 5)) {
1902 if (i > (BufferSize - 5)) {
1903 while (getChar(&c)) {
1913 buf[i++] = c.toLatin1();
1926 if (!qstricmp(buf,
"nan") || !qstricmp(buf,
"+nan") || !qstricmp(buf,
"-nan")) {
1929 }
else if (!qstricmp(buf,
"+inf") || !qstricmp(buf,
"inf")) {
1932 }
else if (!qstricmp(buf,
"-inf")) {
1937 *f = locale.toDouble(QString::fromLatin1(buf), &ok);
1942
1943
1944
1945
1946
1947
1948
1949
1951QTextStream &QTextStream::operator>>(QChar &c)
1955 d->scan(
nullptr,
nullptr, 0, QTextStreamPrivate::NotSpace);
1956 if (!d->getChar(&c))
1957 setStatus(ReadPastEnd);
1962
1963
1964
1965
1966
1967
1968
1969
1970QTextStream &QTextStream::operator>>(
char &c)
1979
1980
1981
1982
1983
1984
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010QTextStream &QTextStream::operator>>(
signed short &i)
2016
2017
2018
2019
2020QTextStream &QTextStream::operator>>(
unsigned short &i)
2026
2027
2028
2029
2030QTextStream &QTextStream::operator>>(
signed int &i)
2036
2037
2038
2039
2040QTextStream &QTextStream::operator>>(
unsigned int &i)
2046
2047
2048
2049
2050QTextStream &QTextStream::operator>>(
signed long &i)
2056
2057
2058
2059
2060QTextStream &QTextStream::operator>>(
unsigned long &i)
2066
2067
2068
2069
2070QTextStream &QTextStream::operator>>(qlonglong &i)
2076
2077
2078
2079
2080QTextStream &QTextStream::operator>>(qulonglong &i)
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096QTextStream &QTextStream::operator>>(
float &f)
2102
2103
2104
2105
2106QTextStream &QTextStream::operator>>(
double &f)
2112
2113
2114
2115
2116
2117
2118QTextStream &QTextStream::operator>>(QString &str)
2124 d->scan(
nullptr,
nullptr, 0, QTextStreamPrivate::NotSpace);
2125 d->consumeLastToken();
2129 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2130 setStatus(ReadPastEnd);
2134 str = QString(ptr, length);
2135 d->consumeLastToken();
2140
2141
2142
2143
2144
2145
2146QTextStream &QTextStream::operator>>(QByteArray &array)
2151 d->scan(
nullptr,
nullptr, 0, QTextStreamPrivate::NotSpace);
2152 d->consumeLastToken();
2156 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2157 setStatus(ReadPastEnd);
2162 array = QStringView(ptr, length).toUtf8();
2164 d->consumeLastToken();
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182QTextStream &QTextStream::operator>>(
char *c)
2187 d->scan(
nullptr,
nullptr, 0, QTextStreamPrivate::NotSpace);
2188 d->consumeLastToken();
2192 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
2193 setStatus(ReadPastEnd);
2197 QStringEncoder encoder(QStringConverter::Utf8);
2198 char *e = encoder.appendToBuffer(c, QStringView(ptr, length));
2200 d->consumeLastToken();
2205
2206
2207void QTextStreamPrivate::putNumber(qulonglong number,
bool negative)
2210 const QTextStream::NumberFlags numberFlags = params.numberFlags;
2211 if (numberFlags & QTextStream::ShowBase)
2212 flags |= QLocaleData::ShowBase;
2214 if ((numberFlags & QTextStream::ForceSign) && !negative)
2215 flags |= QLocaleData::AlwaysShowSign;
2216 if (numberFlags & QTextStream::UppercaseBase)
2217 flags |= QLocaleData::UppercaseBase;
2218 if (numberFlags & QTextStream::UppercaseDigits)
2219 flags |= QLocaleData::CapitalEorX;
2222 if (locale != QLocale::c() && !locale.numberOptions().testFlag(QLocale::OmitGroupSeparator))
2223 flags |= QLocaleData::GroupDigits;
2225 const QLocaleData *dd = locale.d->m_data;
2226 int base = params.integerBase ? params.integerBase : 10;
2227 QString result = dd->unsLongLongToString(number, -1, base, -1, flags);
2229 result.prepend(locale.negativeSign());
2230 }
else if (number == 0 && base == 8 && params.numberFlags & QTextStream::ShowBase
2231 && result ==
"0"_L1) {
2236 result.prepend(u'0');
2238 putString(result,
true);
2242
2243
2244
2245
2246
2247QTextStream &QTextStream::operator<<(QChar c)
2256
2257
2258
2259
2260QTextStream &QTextStream::operator<<(
char c)
2264 d->putChar(QChar::fromLatin1(c));
2269
2270
2271
2272
2273
2274
2275
2278
2279
2280
2281
2282
2283
2284
2285QTextStream &QTextStream::operator<<(
signed short i)
2289 d->putNumber(QtPrivate::qUnsignedAbs(i), i < 0);
2294
2295
2296
2297
2298QTextStream &QTextStream::operator<<(
unsigned short i)
2302 d->putNumber((qulonglong)i,
false);
2307
2308
2309
2310
2311QTextStream &QTextStream::operator<<(
signed int i)
2315 d->putNumber(QtPrivate::qUnsignedAbs(i), i < 0);
2320
2321
2322
2323
2324QTextStream &QTextStream::operator<<(
unsigned int i)
2328 d->putNumber((qulonglong)i,
false);
2333
2334
2335
2336
2337QTextStream &QTextStream::operator<<(
signed long i)
2341 d->putNumber(QtPrivate::qUnsignedAbs(i), i < 0);
2346
2347
2348
2349
2350QTextStream &QTextStream::operator<<(
unsigned long i)
2354 d->putNumber((qulonglong)i,
false);
2359
2360
2361
2362
2363QTextStream &QTextStream::operator<<(qlonglong i)
2367 d->putNumber(QtPrivate::qUnsignedAbs(i), i < 0);
2372
2373
2374
2375
2376QTextStream &QTextStream::operator<<(qulonglong i)
2380 d->putNumber(i,
false);
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395QTextStream &QTextStream::operator<<(
float f)
2397 return *
this <<
double(f);
2401
2402
2403
2404
2405QTextStream &QTextStream::operator<<(
double f)
2410 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
2411 switch (realNumberNotation()) {
2413 form = QLocaleData::DFDecimal;
2415 case ScientificNotation:
2416 form = QLocaleData::DFExponent;
2419 form = QLocaleData::DFSignificantDigits;
2424 const QLocale::NumberOptions numberOptions = locale().numberOptions();
2425 if (numberFlags() & ShowBase)
2426 flags |= QLocaleData::ShowBase;
2427 if (numberFlags() & ForceSign)
2428 flags |= QLocaleData::AlwaysShowSign;
2429 if (numberFlags() & UppercaseBase)
2430 flags |= QLocaleData::UppercaseBase;
2431 if (numberFlags() & UppercaseDigits)
2432 flags |= QLocaleData::CapitalEorX;
2433 if (numberFlags() & ForcePoint) {
2434 flags |= QLocaleData::ForcePoint;
2437 flags |= QLocaleData::AddTrailingZeroes | QLocaleData::ShowBase;
2439 if (locale() != QLocale::c() && !(numberOptions & QLocale::OmitGroupSeparator))
2440 flags |= QLocaleData::GroupDigits;
2441 if (!(numberOptions & QLocale::OmitLeadingZeroInExponent))
2442 flags |= QLocaleData::ZeroPadExponent;
2443 if (numberOptions & QLocale::IncludeTrailingZeroesAfterDot)
2444 flags |= QLocaleData::AddTrailingZeroes;
2446 const QLocaleData *dd = d->locale.d->m_data;
2447 QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
2448 d->putString(num,
true);
2453
2454
2455
2456
2457
2458
2459QTextStream &QTextStream::operator<<(
const QString &string)
2463 d->putString(string);
2468
2469
2470
2471
2472
2473
2474QTextStream &QTextStream::operator<<(QStringView string)
2478 d->putString(string.cbegin(),
int(string.size()));
2483
2484
2485
2486
2487
2488QTextStream &QTextStream::operator<<(QLatin1StringView string)
2492 d->putString(string);
2497
2498
2499
2500
2501
2502QTextStream &QTextStream::operator<<(
const QByteArray &array)
2506 d->putString(QString::fromUtf8(array.constData(), array.size()));
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523QTextStream &QTextStream::operator<<(
const char *string)
2527 d->putString(QUtf8StringView(string));
2532
2533
2534
2535
2537QTextStream &QTextStream::operator<<(
const void *ptr)
2541 const int oldBase = d->params.integerBase;
2542 const NumberFlags oldFlags = d->params.numberFlags;
2543 d->params.integerBase = 16;
2544 d->params.numberFlags |= ShowBase;
2545 d->putNumber(
reinterpret_cast<quintptr>(ptr),
false);
2546 d->params.integerBase = oldBase;
2547 d->params.numberFlags = oldFlags;
2552
2553
2554
2555
2556
2561
2562
2563
2564
2565
2566
2567
2575
2576
2577
2578
2579
2580
2581
2589
2590
2591
2592
2593
2594
2595
2603
2604
2605
2606
2607
2608
2609
2610
2618
2619
2620
2621
2622
2623
2624
2632
2633
2634
2635
2636
2637
2638
2646
2647
2648
2649
2650
2651
2652
2660
2661
2662
2663
2664
2665
2666
2674
2675
2676
2677
2678
2679
2680
2688
2689
2690
2691
2692
2693
2694
2702
2703
2704
2705
2706
2707
2708
2716
2717
2718
2719
2720
2721
2722
2730
2731
2732
2733
2734
2735
2736
2744
2745
2746
2747
2748
2749
2750
2758
2759
2760
2761
2762
2763
2764
2772
2773
2774
2775
2776
2777
2778
2786
2787
2788
2789
2790
2791
2792
2800
2801
2802
2803
2804
2805
2806
2814
2815
2816
2817
2818
2819
2820
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2847
2848
2849
2850
2851
2852
2860
2861
2862
2863
2864
2865
2873
2874
2875
2876
2877
2878
2888
2889
2890
2891
2892
2895
2896
2897
2898
2899
2902
2903
2904
2905
2906
2911
2912
2913
2914
2915
2916
2917
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942void QTextStream::setEncoding(QStringConverter::Encoding encoding)
2945 if (d->encoding == encoding)
2948 qint64 seekPos = -1;
2949 if (!d->readBuffer.isEmpty()) {
2950 if (!d->device->isSequential()) {
2955 d->encoding = encoding;
2956 d->toUtf16 = QStringDecoder(d->encoding);
2957 bool generateBOM = !d->hasWrittenData && d->generateBOM;
2958 d->fromUtf16 = QStringEncoder(d->encoding,
2959 generateBOM ? QStringEncoder::Flag::WriteBom : QStringEncoder::Flag::Default);
2961 if (seekPos >=0 && !d->readBuffer.isEmpty())
2966
2967
2968
2969
2970QStringConverter::Encoding QTextStream::encoding()
const
2972 Q_D(
const QTextStream);
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987void QTextStream::setAutoDetectUnicode(
bool enabled)
2990 d->autoDetectUnicode = enabled;
2994
2995
2996
2997
2998
2999bool QTextStream::autoDetectUnicode()
const
3001 Q_D(
const QTextStream);
3002 return d->autoDetectUnicode;
3006
3007
3008
3009
3010
3011
3012
3013void QTextStream::setGenerateByteOrderMark(
bool generate)
3016 if (d->hasWrittenData || d->generateBOM == generate)
3019 d->generateBOM = generate;
3020 d->fromUtf16 = QStringEncoder(d->encoding, generate ? QStringConverter::Flag::WriteBom : QStringConverter::Flag::Default);
3024
3025
3026
3027
3028
3029
3030bool QTextStream::generateByteOrderMark()
const
3032 Q_D(
const QTextStream);
3033 return d->generateBOM;
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047void QTextStream::setLocale(
const QLocale &locale)
3054
3055
3056
3057
3058
3059
3060QLocale QTextStream::locale()
const
3062 Q_D(
const QTextStream);
3068#ifndef QT_NO_QOBJECT
3069#include "moc_qtextstream_p.cpp"
Combined button and popup list for selecting options.
#define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type)
static const int QTEXTSTREAM_BUFFERSIZE
#define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type)
#define CHECK_VALID_STREAM(x)