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// Qt-Security score:critical reason:data-parser
5
6//#define QTEXTSTREAM_DEBUG
7
8/*!
9 \class QTextStream
10 \inmodule QtCore
11
12 \brief The QTextStream class provides a convenient interface for
13 reading and writing text.
14
15 \ingroup io
16 \ingroup string-processing
17 \ingroup qtserialization
18 \reentrant
19
20 QTextStream can operate on a QIODevice, a QByteArray or a
21 QString. Using QTextStream's streaming operators, you can
22 conveniently read and write words, lines and numbers. For
23 generating text, QTextStream supports formatting options for field
24 padding and alignment, and formatting of numbers. Example:
25
26 \snippet code/src_corelib_io_qtextstream.cpp 0
27
28 It's also common to use QTextStream to read console input and write
29 console output. QTextStream is locale aware, and will automatically decode
30 standard input using the correct encoding. Example:
31
32 \snippet code/src_corelib_io_qtextstream.cpp 1
33
34 Besides using QTextStream's constructors, you can also set the
35 device or string QTextStream operates on by calling setDevice() or
36 setString(). You can seek to a position by calling seek(), and
37 atEnd() will return true when there is no data left to be read. If
38 you call flush(), QTextStream will empty all data from its write
39 buffer into the device and call flush() on the device.
40
41 Internally, QTextStream uses a Unicode based buffer, and
42 QStringConverter is used by QTextStream to automatically support
43 different encodings. By default, UTF-8
44 is used for reading and writing, but you can also set the encoding by
45 calling setEncoding(). Automatic Unicode detection is also
46 supported. When this feature is enabled (the default behavior),
47 QTextStream will detect the UTF-8, UTF-16 or the UTF-32 BOM (Byte Order Mark) and
48 switch to the appropriate UTF encoding when reading. QTextStream
49 does not write a BOM by default, but you can enable this by calling
50 setGenerateByteOrderMark(true). When QTextStream operates on a QString
51 directly, the encoding is disabled.
52
53 There are three general ways to use QTextStream when reading text
54 files:
55
56 \list
57
58 \li Chunk by chunk, by calling readLine() or readAll().
59
60 \li Word by word. QTextStream supports streaming into \l {QString}s,
61 \l {QByteArray}s and char* buffers. Words are delimited by space, and
62 leading white space is automatically skipped.
63
64 \li Character by character, by streaming into QChar or char types.
65 This method is often used for convenient input handling when
66 parsing files, independent of character encoding and end-of-line
67 semantics. To skip white space, call skipWhiteSpace().
68
69 \endlist
70
71 Since the text stream uses a buffer, you should not read from
72 the stream using the implementation of a superclass. For instance,
73 if you have a QFile and read from it directly using
74 QFile::readLine() instead of using the stream, the text stream's
75 internal position will be out of sync with the file's position.
76
77 By default, when reading numbers from a stream of text,
78 QTextStream will automatically detect the number's base
79 representation. For example, if the number starts with "0x", it is
80 assumed to be in hexadecimal form. If it starts with the digits
81 1-9, it is assumed to be in decimal form, and so on. You can set
82 the integer base, thereby disabling the automatic detection, by
83 calling setIntegerBase(). Example:
84
85 \snippet code/src_corelib_io_qtextstream.cpp 2
86
87 QTextStream supports many formatting options for generating text.
88 You can set the field width and pad character by calling
89 setFieldWidth() and setPadChar(). Use setFieldAlignment() to set
90 the alignment within each field. For real numbers, call
91 setRealNumberNotation() and setRealNumberPrecision() to set the
92 notation (SmartNotation, ScientificNotation, FixedNotation) and precision in
93 digits of the generated number. Some extra number formatting
94 options are also available through setNumberFlags().
95
96 \target QTextStream manipulators
97
98 Like \c <iostream> in the standard C++ library, QTextStream also
99 defines several global manipulator functions:
100
101 \table
102 \header \li Manipulator \li Description
103 \row \li Qt::bin \li Same as setIntegerBase(2).
104 \row \li Qt::oct \li Same as setIntegerBase(8).
105 \row \li Qt::dec \li Same as setIntegerBase(10).
106 \row \li Qt::hex \li Same as setIntegerBase(16).
107 \row \li Qt::showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
108 \row \li Qt::forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
109 \row \li Qt::forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
110 \row \li Qt::noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
111 \row \li Qt::noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
112 \row \li Qt::noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
113 \row \li Qt::uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
114 \row \li Qt::uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
115 \row \li Qt::lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
116 \row \li Qt::lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
117 \row \li Qt::fixed \li Same as setRealNumberNotation(FixedNotation).
118 \row \li Qt::scientific \li Same as setRealNumberNotation(ScientificNotation).
119 \row \li Qt::left \li Same as setFieldAlignment(AlignLeft).
120 \row \li Qt::right \li Same as setFieldAlignment(AlignRight).
121 \row \li Qt::center \li Same as setFieldAlignment(AlignCenter).
122 \row \li Qt::endl \li Same as operator<<('\\n') and flush().
123 \row \li Qt::flush \li Same as flush().
124 \row \li Qt::reset \li Same as reset().
125 \row \li Qt::ws \li Same as skipWhiteSpace().
126 \row \li Qt::bom \li Same as setGenerateByteOrderMark(true).
127 \endtable
128
129 In addition, Qt provides three global manipulators that take a
130 parameter: qSetFieldWidth(), qSetPadChar(), and
131 qSetRealNumberPrecision().
132
133 \sa QDataStream, QIODevice, QFile, QBuffer, QTcpSocket
134*/
135
136/*! \enum QTextStream::RealNumberNotation
137
138 This enum specifies which notations to use for expressing \c
139 float and \c double as strings.
140
141 \value ScientificNotation Scientific notation (\c{printf()}'s \c %e flag).
142 \value FixedNotation Fixed-point notation (\c{printf()}'s \c %f flag).
143 \value SmartNotation Scientific or fixed-point notation, depending on which makes most sense (\c{printf()}'s \c %g flag).
144
145 \sa setRealNumberNotation()
146*/
147
148/*! \enum QTextStream::FieldAlignment
149
150 This enum specifies how to align text in fields when the field is
151 wider than the text that occupies it.
152
153 \value AlignLeft Pad on the right side of fields.
154 \value AlignRight Pad on the left side of fields.
155 \value AlignCenter Pad on both sides of field.
156 \value AlignAccountingStyle Same as AlignRight, except that the
157 sign of a number is flush left.
158
159 \sa setFieldAlignment()
160*/
161
162/*! \enum QTextStream::NumberFlag
163
164 This enum specifies various flags that can be set to affect the
165 output of integers, \c{float}s, and \c{double}s.
166
167 \value ShowBase Show the base as a prefix if the base
168 is 16 ("0x"), 8 ("0"), or 2 ("0b").
169 \value ForcePoint Always put the decimal separator in numbers, even if
170 there are no decimals.
171 \value ForceSign Always put the sign in numbers, even for positive numbers.
172 \value UppercaseBase Use uppercase versions of base prefixes ("0X", "0B").
173 \value UppercaseDigits Use uppercase letters for expressing
174 digits 10 to 35 instead of lowercase.
175
176 \sa setNumberFlags()
177*/
178
179/*! \enum QTextStream::Status
180
181 This enum describes the current status of the text stream.
182
183 \value Ok The text stream is operating normally.
184 \value ReadPastEnd The text stream has read past the end of the
185 data in the underlying device.
186 \value ReadCorruptData The text stream has read corrupt data.
187 \value WriteFailed The text stream cannot write to the underlying device.
188
189 \sa status()
190*/
191
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
247QT_BEGIN_NAMESPACE
248
249using namespace Qt::StringLiterals;
250using namespace QtMiscUtils;
251
252static const qsizetype QTEXTSTREAM_BUFFERSIZE = 16384;
253
254//-------------------------------------------------------------------
255
256/*!
257 \internal
258*/
259QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
260 : readConverterSavedStateOffset(0),
261 locale(QLocale::c())
262{
263 this->q_ptr = q_ptr;
264 reset();
265}
266
267/*!
268 \internal
269*/
270QTextStreamPrivate::~QTextStreamPrivate()
271{
272 disconnectFromDevice();
273 if (deleteDevice) {
274#ifndef QT_NO_QOBJECT
275 device->blockSignals(b: true);
276#endif
277 delete device;
278 }
279}
280
281void QTextStreamPrivate::Params::reset()
282{
283 realNumberPrecision = 6;
284 integerBase = 0;
285 fieldWidth = 0;
286 padChar = u' ';
287 fieldAlignment = QTextStream::AlignRight;
288 realNumberNotation = QTextStream::SmartNotation;
289 numberFlags = { };
290}
291
292/*!
293 \internal
294*/
295void QTextStreamPrivate::reset()
296{
297 params.reset();
298
299 device = nullptr;
300 deleteDevice = false;
301 string = nullptr;
302 stringOffset = 0;
303 stringOpenMode = QTextStream::NotOpen;
304
305 readBufferOffset = 0;
306 readBufferStartDevicePos = 0;
307 lastTokenSize = 0;
308
309 hasWrittenData = false;
310 generateBOM = false;
311 encoding = QStringConverter::Utf8;
312 toUtf16 = QStringDecoder(encoding);
313 fromUtf16 = QStringEncoder(encoding);
314 autoDetectUnicode = true;
315}
316
317void QTextStreamPrivate::setupDevice(QIODevice *device)
318{
319 disconnectFromDevice();
320
321#ifndef QT_NO_QOBJECT
322 // Explicitly set a direct connection (though it would have been so
323 // anyway) so that QTextStream can be used from multiple threads when the
324 // application code is handling synchronization (see also QTBUG-12055).
325 aboutToCloseConnection =
326 QObject::connect(sender: device, signal: &QIODevice::aboutToClose, context: device,
327 slot: [this] { flushWriteBuffer(); }, type: Qt::DirectConnection);
328#else
329 Q_UNUSED(device);
330#endif
331}
332
333void QTextStreamPrivate::disconnectFromDevice()
334{
335#ifndef QT_NO_QOBJECT
336 QObject::disconnect(aboutToCloseConnection);
337 aboutToCloseConnection = {};
338#endif
339}
340
341/*!
342 \internal
343*/
344bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
345{
346 // no buffer next to the QString itself; this function should only
347 // be called internally, for devices.
348 Q_ASSERT(!string);
349 Q_ASSERT(device);
350
351 // handle text translation and bypass the Text flag in the device.
352 bool textModeEnabled = device->isTextModeEnabled();
353 if (textModeEnabled)
354 device->setTextModeEnabled(false);
355
356 // read raw data into a temporary buffer
357 char buf[QTEXTSTREAM_BUFFERSIZE];
358 qint64 bytesRead = 0;
359#if defined(Q_OS_WIN)
360 // On Windows, there is no non-blocking stdin - so we fall back to reading
361 // lines instead. If there is no QOBJECT, we read lines for all sequential
362 // devices; otherwise, we read lines only for stdin.
363 QFile *file = 0;
364 Q_UNUSED(file);
365 if (device->isSequential()
366#if !defined(QT_NO_QOBJECT)
367 && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
368#endif
369 ) {
370 if (maxBytes != -1)
371 bytesRead = device->readLine(buf, qMin<qint64>(sizeof(buf), maxBytes));
372 else
373 bytesRead = device->readLine(buf, sizeof(buf));
374 } else
375#endif
376 {
377 if (maxBytes != -1)
378 bytesRead = device->read(data: buf, maxlen: qMin<qint64>(a: sizeof(buf), b: maxBytes));
379 else
380 bytesRead = device->read(data: buf, maxlen: sizeof(buf));
381 }
382
383 // reset the Text flag.
384 if (textModeEnabled)
385 device->setTextModeEnabled(true);
386
387 if (bytesRead <= 0)
388 return false;
389
390#ifndef QT_BOOTSTRAPPED
391 if (autoDetectUnicode) {
392 autoDetectUnicode = false;
393
394 auto e = QStringConverter::encodingForData(data: QByteArrayView(buf, bytesRead));
395 // QStringConverter::Locale implies unknown, so keep the current encoding
396 if (e) {
397 encoding = *e;
398 toUtf16 = QStringDecoder(encoding);
399 fromUtf16 = QStringEncoder(encoding);
400 }
401 }
402#if defined (QTEXTSTREAM_DEBUG)
403 qDebug("QTextStreamPrivate::fillReadBuffer(), using %s encoding", QStringConverter::nameForEncoding(encoding));
404#endif
405#endif
406
407#if defined (QTEXTSTREAM_DEBUG)
408 qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
409 QtDebugUtils::toPrintable(buf, bytesRead, 32).constData(),
410 int(sizeof(buf)), int(bytesRead));
411#endif
412
413 qsizetype oldReadBufferSize = readBuffer.size();
414 readBuffer += toUtf16(QByteArrayView(buf, bytesRead));
415
416 // remove all '\r\n' in the string.
417 if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
418 QChar CR = u'\r';
419 QChar *writePtr = readBuffer.data() + oldReadBufferSize;
420 QChar *readPtr = readBuffer.data() + oldReadBufferSize;
421 QChar *endPtr = readBuffer.data() + readBuffer.size();
422
423 qsizetype n = oldReadBufferSize;
424 if (readPtr < endPtr) {
425 // Cut-off to avoid unnecessary self-copying.
426 while (*readPtr++ != CR) {
427 ++n;
428 if (++writePtr == endPtr)
429 break;
430 }
431 }
432 while (readPtr < endPtr) {
433 QChar ch = *readPtr++;
434 if (ch != CR) {
435 *writePtr++ = ch;
436 } else {
437 if (n < readBufferOffset)
438 --readBufferOffset;
439 --bytesRead;
440 }
441 ++n;
442 }
443 readBuffer.resize(size: writePtr - readBuffer.data());
444 }
445
446#if defined (QTEXTSTREAM_DEBUG)
447 qDebug("QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]",
448 int(bytesRead),
449 QtDebugUtils::toPrintable(readBuffer.toLatin1(), readBuffer.size(),
450 readBuffer.size()).constData());
451#endif
452 return true;
453}
454
455/*!
456 \internal
457*/
458void QTextStreamPrivate::resetReadBuffer()
459{
460 readBuffer.clear();
461 readBufferOffset = 0;
462 readBufferStartDevicePos = (device ? device->pos() : 0);
463}
464
465/*!
466 \internal
467*/
468void QTextStreamPrivate::flushWriteBuffer()
469{
470 // no buffer next to the QString itself; this function should only
471 // be called internally, for devices.
472 if (string || !device)
473 return;
474
475 // Stream went bye-bye already. Appending further data may succeed again,
476 // but would create a corrupted stream anyway.
477 if (status != QTextStream::Ok)
478 return;
479
480 if (writeBuffer.isEmpty())
481 return;
482
483#if defined (Q_OS_WIN)
484 // handle text translation and bypass the Text flag in the device.
485 bool textModeEnabled = device->isTextModeEnabled();
486 if (textModeEnabled) {
487 device->setTextModeEnabled(false);
488 writeBuffer.replace(u'\n', "\r\n"_L1);
489 }
490#endif
491
492 QByteArray data = fromUtf16(writeBuffer);
493 writeBuffer.clear();
494 hasWrittenData = true;
495
496 // write raw data to the device
497 qint64 bytesWritten = device->write(data);
498#if defined (QTEXTSTREAM_DEBUG)
499 qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
500 QtDebugUtils::toPrintable(data.constData(), data.size(), 32).constData(),
501 int(bytesWritten));
502#endif
503
504#if defined (Q_OS_WIN)
505 // reset the text flag
506 if (textModeEnabled)
507 device->setTextModeEnabled(true);
508#endif
509
510 if (bytesWritten <= 0) {
511 status = QTextStream::WriteFailed;
512 return;
513 }
514
515 // flush the file
516#ifndef QT_NO_QOBJECT
517 QFileDevice *file = qobject_cast<QFileDevice *>(object: device);
518 bool flushed = !file || file->flush();
519#else
520 bool flushed = true;
521#endif
522
523#if defined (QTEXTSTREAM_DEBUG)
524 qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes", int(bytesWritten));
525#endif
526 if (!flushed || bytesWritten != qint64(data.size()))
527 status = QTextStream::WriteFailed;
528}
529
530QString QTextStreamPrivate::read(qsizetype maxlen)
531{
532 QString ret;
533 if (string) {
534 lastTokenSize = qMin(a: maxlen, b: string->size() - stringOffset);
535 ret = string->mid(position: stringOffset, n: lastTokenSize);
536 } else {
537 while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) {}
538 lastTokenSize = qMin(a: maxlen, b: readBuffer.size() - readBufferOffset);
539 ret = readBuffer.mid(position: readBufferOffset, n: lastTokenSize);
540 }
541 consumeLastToken();
542
543#if defined (QTEXTSTREAM_DEBUG)
544 qDebug("QTextStreamPrivate::read() maxlen = %d, token length = %d",
545 int(maxlen), int(ret.length()));
546#endif
547 return ret;
548}
549
550/*!
551 \internal
552
553 Scans no more than \a maxlen QChars in the current buffer for the
554 first \a delimiter. Stores a pointer to the start offset of the
555 token in \a ptr, and the length in QChars in \a length.
556*/
557bool QTextStreamPrivate::scan(const QChar **ptr, qsizetype *length, qsizetype maxlen,
558 TokenDelimiter delimiter)
559{
560 qsizetype totalSize = 0;
561 qsizetype delimSize = 0;
562 bool consumeDelimiter = false;
563 bool foundToken = false;
564 qsizetype startOffset = device ? readBufferOffset : stringOffset;
565 QChar lastChar;
566
567 do {
568 qsizetype endOffset;
569 const QChar *chPtr;
570 if (device) {
571 chPtr = readBuffer.constData();
572 endOffset = readBuffer.size();
573 } else {
574 chPtr = string->constData();
575 endOffset = string->size();
576 }
577 chPtr += startOffset;
578
579 for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
580 const QChar ch = *chPtr++;
581 ++totalSize;
582
583 switch (delimiter) {
584 case Space:
585 if (ch.isSpace()) {
586 foundToken = true;
587 delimSize = 1;
588 }
589 break;
590 case NotSpace:
591 if (!ch.isSpace()) {
592 foundToken = true;
593 delimSize = 1;
594 }
595 break;
596 case EndOfLine:
597 if (ch == u'\n') {
598 foundToken = true;
599 delimSize = (lastChar == u'\r') ? 2 : 1;
600 consumeDelimiter = true;
601 }
602 lastChar = ch;
603 break;
604 }
605 }
606 } while (!foundToken
607 && (!maxlen || totalSize < maxlen)
608 && device && fillReadBuffer());
609
610 if (totalSize == 0) {
611#if defined (QTEXTSTREAM_DEBUG)
612 qDebug("QTextStreamPrivate::scan() reached the end of input.");
613#endif
614 return false;
615 }
616
617 // if we find a '\r' at the end of the data when reading lines,
618 // don't make it part of the line.
619 if (delimiter == EndOfLine && totalSize > 0 && !foundToken) {
620 if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
621 && lastChar == u'\r') {
622 consumeDelimiter = true;
623 ++delimSize;
624 }
625 }
626
627 // set the read offset and length of the token
628 if (length)
629 *length = totalSize - delimSize;
630 if (ptr)
631 *ptr = readPtr();
632
633 // update last token size. the callee will call consumeLastToken() when
634 // done.
635 lastTokenSize = totalSize;
636 if (!consumeDelimiter)
637 lastTokenSize -= delimSize;
638
639#if defined (QTEXTSTREAM_DEBUG)
640 qDebug("QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
641 ptr, length, int(maxlen), uint(delimiter), int(totalSize - delimSize), int(delimSize));
642#endif
643 return true;
644}
645
646/*!
647 \internal
648*/
649inline const QChar *QTextStreamPrivate::readPtr() const
650{
651 Q_ASSERT(readBufferOffset <= readBuffer.size());
652 if (string)
653 return string->constData() + stringOffset;
654 return readBuffer.constData() + readBufferOffset;
655}
656
657/*!
658 \internal
659*/
660inline void QTextStreamPrivate::consumeLastToken()
661{
662 if (lastTokenSize)
663 consume(nchars: lastTokenSize);
664 lastTokenSize = 0;
665}
666
667/*!
668 \internal
669*/
670inline void QTextStreamPrivate::consume(qsizetype size)
671{
672#if defined (QTEXTSTREAM_DEBUG)
673 qDebug("QTextStreamPrivate::consume(%d)", int(size));
674#endif
675 if (string) {
676 stringOffset += size;
677 if (stringOffset > string->size())
678 stringOffset = string->size();
679 } else {
680 readBufferOffset += size;
681 if (readBufferOffset >= readBuffer.size()) {
682 readBufferOffset = 0;
683 readBuffer.clear();
684 saveConverterState(newPos: device->pos());
685 } else if (readBufferOffset > QTEXTSTREAM_BUFFERSIZE) {
686 readBuffer = readBuffer.remove(i: 0,len: readBufferOffset);
687 readConverterSavedStateOffset += readBufferOffset;
688 readBufferOffset = 0;
689 }
690 }
691}
692
693/*!
694 \internal
695*/
696inline void QTextStreamPrivate::saveConverterState(qint64 newPos)
697{
698 // ### Hack, FIXME
699 memcpy(dest: (void *)&savedToUtf16, src: (void *)&toUtf16, n: sizeof(QStringDecoder));
700 readBufferStartDevicePos = newPos;
701 readConverterSavedStateOffset = 0;
702}
703
704/*!
705 \internal
706*/
707inline void QTextStreamPrivate::restoreToSavedConverterState()
708{
709 if (savedToUtf16.isValid())
710 memcpy(dest: (void *)&toUtf16, src: (void *)&savedToUtf16, n: sizeof(QStringDecoder));
711 else
712 toUtf16.resetState();
713 savedToUtf16 = QStringDecoder();
714}
715
716/*!
717 \internal
718*/
719template <typename Appendable>
720void QTextStreamPrivate::writeImpl(Appendable s)
721{
722 if (string) {
723 // ### What about seek()??
724 string->append(s);
725 } else {
726 writeBuffer.append(s);
727 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
728 flushWriteBuffer();
729 }
730}
731
732/*!
733 \internal
734*/
735void QTextStreamPrivate::write(QStringView s)
736{
737 writeImpl(s);
738}
739
740/*!
741 \internal
742*/
743void QTextStreamPrivate::write(QChar ch)
744{
745 writeImpl(s: ch);
746}
747
748/*!
749 \internal
750*/
751void QTextStreamPrivate::write(QLatin1StringView data)
752{
753 writeImpl(s: data);
754}
755
756/*!
757 \internal
758*/
759void QTextStreamPrivate::writePadding(qsizetype len)
760{
761 if (string) {
762 // ### What about seek()??
763 string->resize(size: string->size() + len, fillChar: params.padChar);
764 } else {
765 writeBuffer.resize(size: writeBuffer.size() + len, fillChar: params.padChar);
766 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
767 flushWriteBuffer();
768 }
769}
770
771/*!
772 \internal
773*/
774inline bool QTextStreamPrivate::getChar(QChar *ch)
775{
776 if ((string && stringOffset == string->size())
777 || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
778 if (ch)
779 *ch = QChar();
780 return false;
781 }
782 if (ch)
783 *ch = *readPtr();
784 consume(size: 1);
785 return true;
786}
787
788/*!
789 \internal
790*/
791inline void QTextStreamPrivate::ungetChar(QChar ch)
792{
793 if (string) {
794 if (stringOffset == 0)
795 string->prepend(c: ch);
796 else
797 (*string)[--stringOffset] = ch;
798 return;
799 }
800
801 if (readBufferOffset == 0) {
802 readBuffer.prepend(c: ch);
803 return;
804 }
805
806 readBuffer[--readBufferOffset] = ch;
807}
808
809/*!
810 \internal
811*/
812inline void QTextStreamPrivate::putChar(QChar ch)
813{
814 if (params.fieldWidth > 0)
815 putString(string: QStringView{&ch, 1});
816 else
817 write(ch);
818}
819
820
821/*!
822 \internal
823*/
824QTextStreamPrivate::PaddingResult QTextStreamPrivate::padding(qsizetype len) const
825{
826 Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
827
828 qsizetype left = 0, right = 0;
829
830 const qsizetype padSize = params.fieldWidth - len;
831
832 switch (params.fieldAlignment) {
833 case QTextStream::AlignLeft:
834 right = padSize;
835 break;
836 case QTextStream::AlignRight:
837 case QTextStream::AlignAccountingStyle:
838 left = padSize;
839 break;
840 case QTextStream::AlignCenter:
841 left = padSize/2;
842 right = padSize - padSize/2;
843 break;
844 }
845 return { .left: left, .right: right };
846}
847
848namespace {
849template <typename StringView>
850auto parseSign(StringView data, const QLocale &loc)
851{
852 struct R {
853 StringView sign, rest;
854 explicit operator bool() const noexcept { return !sign.isEmpty(); }
855 };
856 // This assumes that the size in UTF-16 (return value of QLocale functions)
857 // and StringView is the same; in particular, it doesn't work for UTF-8!
858 if (const QString sign = loc.negativeSign(); data.startsWith(sign))
859 return R{data.first(sign.size()), data.sliced(sign.size())};
860 if (const QString sign = loc.positiveSign(); data.startsWith(sign))
861 return R{data.first(sign.size()), data.sliced(sign.size())};
862 return R{nullptr, data};
863}
864} // unnamed namespace
865
866/*!
867 \internal
868*/
869template <typename StringView>
870void QTextStreamPrivate::putStringImpl(StringView data, PutStringMode mode)
871{
872 const bool number = mode == PutStringMode::Number;
873 if (Q_UNLIKELY(params.fieldWidth > data.size())) {
874
875 // handle padding:
876
877 const PaddingResult pad = padding(len: data.size());
878
879 if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
880 if (const auto r = parseSign(data, locale)) {
881 // write the sign before the padding, then skip it later
882 write(r.sign);
883 data = r.rest;
884 }
885 }
886
887 writePadding(len: pad.left);
888 write(data);
889 writePadding(len: pad.right);
890 } else {
891 write(data);
892 }
893}
894
895/*!
896 \internal
897*/
898void QTextStreamPrivate::putString(QLatin1StringView data, PutStringMode mode)
899{
900 putStringImpl(data, mode);
901}
902
903/*!
904 \internal
905*/
906void QTextStreamPrivate::putString(QStringView data, PutStringMode mode)
907{
908 putStringImpl(data, mode);
909}
910
911/*!
912 \internal
913*/
914void QTextStreamPrivate::putString(QUtf8StringView data, PutStringMode mode)
915{
916 putString(data: data.toString(), mode);
917}
918
919/*!
920 Constructs a QTextStream. Before you can use it for reading or
921 writing, you must assign a device or a string.
922
923 \sa setDevice(), setString()
924*/
925QTextStream::QTextStream()
926 : d_ptr(new QTextStreamPrivate(this))
927{
928#if defined (QTEXTSTREAM_DEBUG)
929 qDebug("QTextStream::QTextStream()");
930#endif
931 Q_D(QTextStream);
932 d->status = Ok;
933}
934
935/*!
936 Constructs a QTextStream that operates on \a device.
937*/
938QTextStream::QTextStream(QIODevice *device)
939 : d_ptr(new QTextStreamPrivate(this))
940{
941#if defined (QTEXTSTREAM_DEBUG)
942 qDebug("QTextStream::QTextStream(QIODevice *device == *%p)",
943 device);
944#endif
945 Q_D(QTextStream);
946 d->device = device;
947 d->setupDevice(device);
948 d->status = Ok;
949}
950
951/*!
952 Constructs a QTextStream that operates on \a string, using \a
953 openMode to define the open mode.
954*/
955QTextStream::QTextStream(QString *string, OpenMode openMode)
956 : d_ptr(new QTextStreamPrivate(this))
957{
958#if defined (QTEXTSTREAM_DEBUG)
959 qDebug("QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
960 string, int(openMode.toInt()));
961#endif
962 Q_D(QTextStream);
963 d->string = string;
964 d->stringOpenMode = openMode;
965 d->status = Ok;
966}
967
968#ifndef QT_BOOTSTRAPPED
969/*!
970 Constructs a QTextStream that operates on \a array, using \a
971 openMode to define the open mode. Internally, the array is wrapped
972 by a QBuffer.
973*/
974QTextStream::QTextStream(QByteArray *array, OpenMode openMode)
975 : d_ptr(new QTextStreamPrivate(this))
976{
977#if defined (QTEXTSTREAM_DEBUG)
978 qDebug("QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
979 array, int(openMode.toInt()));
980#endif
981 Q_D(QTextStream);
982 d->device = new QBuffer(array);
983 d->device->open(mode: openMode);
984 d->deleteDevice = true;
985 d->setupDevice(d->device);
986 d->status = Ok;
987}
988
989/*!
990 Constructs a QTextStream that operates on \a array, using \a
991 openMode to define the open mode. The array is accessed as
992 read-only, regardless of the values in \a openMode.
993
994 This constructor is convenient for working on constant
995 strings. Example:
996
997 \snippet code/src_corelib_io_qtextstream.cpp 3
998*/
999QTextStream::QTextStream(const QByteArray &array, OpenMode openMode)
1000 : d_ptr(new QTextStreamPrivate(this))
1001{
1002#if defined (QTEXTSTREAM_DEBUG)
1003 qDebug("QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
1004 &array, int(openMode.toInt()));
1005#endif
1006 QBuffer *buffer = new QBuffer;
1007 buffer->setData(array);
1008 buffer->open(openMode);
1009
1010 Q_D(QTextStream);
1011 d->device = buffer;
1012 d->deleteDevice = true;
1013 d->setupDevice(d->device);
1014 d->status = Ok;
1015}
1016#endif
1017
1018/*!
1019 Constructs a QTextStream that operates on \a fileHandle, using \a
1020 openMode to define the open mode. Internally, a QFile is created
1021 to handle the FILE pointer.
1022
1023 This constructor is useful for working directly with the common
1024 FILE based input and output streams: stdin, stdout and stderr. Example:
1025
1026 \snippet code/src_corelib_io_qtextstream.cpp 4
1027*/
1028
1029QTextStream::QTextStream(FILE *fileHandle, OpenMode openMode)
1030 : d_ptr(new QTextStreamPrivate(this))
1031{
1032#if defined (QTEXTSTREAM_DEBUG)
1033 qDebug("QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
1034 fileHandle, int(openMode.toInt()));
1035#endif
1036 QFile *file = new QFile;
1037 // Discarding the return value of open; even if it failed
1038 // (and the file is not open), QTextStream still reports `Ok`
1039 // for closed QIODevices, so there's nothing really to do here.
1040 (void)file->open(f: fileHandle, ioFlags: openMode);
1041
1042 Q_D(QTextStream);
1043 d->device = file;
1044 d->deleteDevice = true;
1045 d->setupDevice(d->device);
1046 d->status = Ok;
1047}
1048
1049/*!
1050 Destroys the QTextStream.
1051
1052 If the stream operates on a device, flush() will be called
1053 implicitly. Otherwise, the device is unaffected.
1054*/
1055QTextStream::~QTextStream()
1056{
1057 Q_D(QTextStream);
1058#if defined (QTEXTSTREAM_DEBUG)
1059 qDebug("QTextStream::~QTextStream()");
1060#endif
1061 if (!d->writeBuffer.isEmpty())
1062 d->flushWriteBuffer();
1063}
1064
1065/*!
1066 Resets QTextStream's formatting options, bringing it back to its
1067 original constructed state. The device, string and any buffered
1068 data is left untouched.
1069*/
1070void QTextStream::reset()
1071{
1072 Q_D(QTextStream);
1073
1074 d->params.reset();
1075}
1076
1077/*!
1078 Flushes any buffered data waiting to be written to the device.
1079
1080 If QTextStream operates on a string, this function does nothing.
1081*/
1082void QTextStream::flush()
1083{
1084 Q_D(QTextStream);
1085 d->flushWriteBuffer();
1086}
1087
1088/*!
1089 Seeks to the position \a pos in the device. Returns \c true on
1090 success; otherwise returns \c false.
1091*/
1092bool QTextStream::seek(qint64 pos)
1093{
1094 Q_D(QTextStream);
1095 d->lastTokenSize = 0;
1096
1097 if (d->device) {
1098 // Empty the write buffer
1099 d->flushWriteBuffer();
1100 if (!d->device->seek(pos))
1101 return false;
1102 d->resetReadBuffer();
1103
1104 d->toUtf16.resetState();
1105 d->fromUtf16.resetState();
1106 return true;
1107 }
1108
1109 // string
1110 if (d->string && pos <= d->string->size()) {
1111 d->stringOffset = pos;
1112 return true;
1113 }
1114 return false;
1115}
1116
1117/*!
1118 \since 4.2
1119
1120 Returns the device position corresponding to the current position of the
1121 stream, or -1 if an error occurs (e.g., if there is no device or string,
1122 or if there's a device error).
1123
1124 Because QTextStream is buffered, this function may have to
1125 seek the device to reconstruct a valid device position. This
1126 operation can be expensive, so you may want to avoid calling this
1127 function in a tight loop.
1128
1129 \sa seek()
1130*/
1131qint64 QTextStream::pos() const
1132{
1133 Q_D(const QTextStream);
1134 if (d->device) {
1135 // Cutoff
1136 if (d->readBuffer.isEmpty())
1137 return d->device->pos();
1138 if (d->device->isSequential())
1139 return 0;
1140
1141 // Seek the device
1142 if (!d->device->seek(pos: d->readBufferStartDevicePos))
1143 return qint64(-1);
1144
1145 // Reset the read buffer
1146 QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
1147 thatd->readBuffer.clear();
1148
1149 thatd->restoreToSavedConverterState();
1150 if (d->readBufferStartDevicePos == 0)
1151 thatd->autoDetectUnicode = true;
1152
1153 // Rewind the device to get to the current position Ensure that
1154 // readBufferOffset is unaffected by fillReadBuffer()
1155 qsizetype oldReadBufferOffset = d->readBufferOffset + d->readConverterSavedStateOffset;
1156 while (d->readBuffer.size() < oldReadBufferOffset) {
1157 if (!thatd->fillReadBuffer(maxBytes: 1))
1158 return qint64(-1);
1159 }
1160 thatd->readBufferOffset = oldReadBufferOffset;
1161 thatd->readConverterSavedStateOffset = 0;
1162
1163 // Return the device position.
1164 return d->device->pos();
1165 }
1166
1167 if (d->string)
1168 return d->stringOffset;
1169
1170 qWarning(msg: "QTextStream::pos: no device");
1171 return qint64(-1);
1172}
1173
1174/*!
1175 Reads and discards whitespace from the stream until either a
1176 non-space character is detected, or until atEnd() returns
1177 true. This function is useful when reading a stream character by
1178 character.
1179
1180 Whitespace characters are all characters for which
1181 QChar::isSpace() returns \c true.
1182
1183 \sa operator>>()
1184*/
1185void QTextStream::skipWhiteSpace()
1186{
1187 Q_D(QTextStream);
1188 CHECK_VALID_STREAM(Q_VOID);
1189 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
1190 d->consumeLastToken();
1191}
1192
1193/*!
1194 Sets the current device to \a device. If a device has already been
1195 assigned, QTextStream will call flush() before the old device is
1196 replaced.
1197
1198 \note This function resets locale to the default locale ('C')
1199 and encoding to the default encoding, UTF-8.
1200
1201 \sa device(), setString()
1202*/
1203void QTextStream::setDevice(QIODevice *device)
1204{
1205 Q_D(QTextStream);
1206 flush();
1207 if (d->deleteDevice) {
1208 d->disconnectFromDevice();
1209 delete d->device;
1210 d->deleteDevice = false;
1211 }
1212
1213 d->reset();
1214 d->status = Ok;
1215 d->device = device;
1216 d->resetReadBuffer();
1217 d->setupDevice(d->device);
1218}
1219
1220/*!
1221 Returns the current device associated with the QTextStream,
1222 or \nullptr if no device has been assigned.
1223
1224 \sa setDevice(), string()
1225*/
1226QIODevice *QTextStream::device() const
1227{
1228 Q_D(const QTextStream);
1229 return d->device;
1230}
1231
1232/*!
1233 Sets the current string to \a string, using the given \a
1234 openMode. If a device has already been assigned, QTextStream will
1235 call flush() before replacing it.
1236
1237 \sa string(), setDevice()
1238*/
1239void QTextStream::setString(QString *string, OpenMode openMode)
1240{
1241 Q_D(QTextStream);
1242 flush();
1243 if (d->deleteDevice) {
1244#ifndef QT_NO_QOBJECT
1245 d->setupDevice(d->device);
1246 d->device->blockSignals(b: true);
1247#endif
1248 delete d->device;
1249 d->deleteDevice = false;
1250 }
1251
1252 d->reset();
1253 d->status = Ok;
1254 d->string = string;
1255 d->stringOpenMode = openMode;
1256}
1257
1258/*!
1259 Returns the current string assigned to the QTextStream, or
1260 \nullptr if no string has been assigned.
1261
1262 \sa setString(), device()
1263*/
1264QString *QTextStream::string() const
1265{
1266 Q_D(const QTextStream);
1267 return d->string;
1268}
1269
1270/*!
1271 Sets the field alignment to \a mode. When used together with
1272 setFieldWidth(), this function allows you to generate formatted
1273 output with text aligned to the left, to the right or center
1274 aligned.
1275
1276 \sa fieldAlignment(), setFieldWidth()
1277*/
1278void QTextStream::setFieldAlignment(FieldAlignment mode)
1279{
1280 Q_D(QTextStream);
1281 d->params.fieldAlignment = mode;
1282}
1283
1284/*!
1285 Returns the current field alignment.
1286
1287 \sa setFieldAlignment(), fieldWidth()
1288*/
1289QTextStream::FieldAlignment QTextStream::fieldAlignment() const
1290{
1291 Q_D(const QTextStream);
1292 return d->params.fieldAlignment;
1293}
1294
1295/*!
1296 Sets the pad character to \a ch. The default value is the ASCII
1297 space character (' '), or QChar(0x20). This character is used to
1298 fill in the space in fields when generating text.
1299
1300 Example:
1301
1302 \snippet code/src_corelib_io_qtextstream.cpp 5
1303
1304 The string \c s contains:
1305
1306 \snippet code/src_corelib_io_qtextstream.cpp 6
1307
1308 \sa padChar(), setFieldWidth()
1309*/
1310void QTextStream::setPadChar(QChar ch)
1311{
1312 Q_D(QTextStream);
1313 d->params.padChar = ch;
1314}
1315
1316/*!
1317 Returns the current pad character.
1318
1319 \sa setPadChar(), setFieldWidth()
1320*/
1321QChar QTextStream::padChar() const
1322{
1323 Q_D(const QTextStream);
1324 return d->params.padChar;
1325}
1326
1327/*!
1328 Sets the current field width to \a width. If \a width is 0 (the
1329 default), the field width is equal to the length of the generated
1330 text.
1331
1332 \note The field width applies to every element appended to this
1333 stream after this function has been called (e.g., it also pads
1334 endl). This behavior is different from similar classes in the STL,
1335 where the field width only applies to the next element.
1336
1337 \sa fieldWidth(), setPadChar()
1338*/
1339void QTextStream::setFieldWidth(int width)
1340{
1341 Q_D(QTextStream);
1342 d->params.fieldWidth = width;
1343}
1344
1345/*!
1346 Returns the current field width.
1347
1348 \sa setFieldWidth()
1349*/
1350int QTextStream::fieldWidth() const
1351{
1352 Q_D(const QTextStream);
1353 return d->params.fieldWidth;
1354}
1355
1356/*!
1357 Sets the current number flags to \a flags. \a flags is a set of
1358 flags from the NumberFlag enum, and describes options for
1359 formatting generated code (e.g., whether or not to always write
1360 the base or sign of a number).
1361
1362 \sa numberFlags(), setIntegerBase(), setRealNumberNotation()
1363*/
1364void QTextStream::setNumberFlags(NumberFlags flags)
1365{
1366 Q_D(QTextStream);
1367 d->params.numberFlags = flags;
1368}
1369
1370/*!
1371 Returns the current number flags.
1372
1373 \sa setNumberFlags(), integerBase(), realNumberNotation()
1374*/
1375QTextStream::NumberFlags QTextStream::numberFlags() const
1376{
1377 Q_D(const QTextStream);
1378 return d->params.numberFlags;
1379}
1380
1381/*!
1382 Sets the base of integers to \a base, both for reading and for
1383 generating numbers. \a base can be either 2 (binary), 8 (octal),
1384 10 (decimal) or 16 (hexadecimal). If \a base is 0, QTextStream
1385 will attempt to detect the base by inspecting the data on the
1386 stream. When generating numbers, QTextStream assumes base is 10
1387 unless the base has been set explicitly.
1388
1389 \sa integerBase(), QString::number(), setNumberFlags()
1390*/
1391void QTextStream::setIntegerBase(int base)
1392{
1393 Q_D(QTextStream);
1394 d->params.integerBase = base;
1395}
1396
1397/*!
1398 Returns the current base of integers. 0 means that the base is
1399 detected when reading, or 10 (decimal) when generating numbers.
1400
1401 \sa setIntegerBase(), QString::number(), numberFlags()
1402*/
1403int QTextStream::integerBase() const
1404{
1405 Q_D(const QTextStream);
1406 return d->params.integerBase;
1407}
1408
1409/*!
1410 Sets the real number notation to \a notation (SmartNotation,
1411 FixedNotation, ScientificNotation). When reading and generating
1412 numbers, QTextStream uses this value to detect the formatting of
1413 real numbers.
1414
1415 \sa realNumberNotation(), setRealNumberPrecision(), setNumberFlags(), setIntegerBase()
1416*/
1417void QTextStream::setRealNumberNotation(RealNumberNotation notation)
1418{
1419 Q_D(QTextStream);
1420 d->params.realNumberNotation = notation;
1421}
1422
1423/*!
1424 Returns the current real number notation.
1425
1426 \sa setRealNumberNotation(), realNumberPrecision(), numberFlags(), integerBase()
1427*/
1428QTextStream::RealNumberNotation QTextStream::realNumberNotation() const
1429{
1430 Q_D(const QTextStream);
1431 return d->params.realNumberNotation;
1432}
1433
1434/*!
1435 Sets the precision of real numbers to \a precision. This value
1436 describes the number of fraction digits QTextStream should
1437 write when generating real numbers (FixedNotation, ScientificNotation), or
1438 the maximum number of significant digits (SmartNotation).
1439
1440 The precision cannot be a negative value. The default value is 6.
1441
1442 \sa realNumberPrecision(), setRealNumberNotation()
1443*/
1444void QTextStream::setRealNumberPrecision(int precision)
1445{
1446 Q_D(QTextStream);
1447 if (precision < 0) {
1448 qWarning(msg: "QTextStream::setRealNumberPrecision: Invalid precision (%d)", precision);
1449 d->params.realNumberPrecision = 6;
1450 return;
1451 }
1452 d->params.realNumberPrecision = precision;
1453}
1454
1455/*!
1456 Returns the current real number precision, or the number of fraction
1457 digits QTextStream will write when generating real numbers
1458 (FixedNotation, ScientificNotation), or the maximum number of significant
1459 digits (SmartNotation).
1460
1461 \sa setRealNumberNotation(), realNumberNotation(), numberFlags(), integerBase()
1462*/
1463int QTextStream::realNumberPrecision() const
1464{
1465 Q_D(const QTextStream);
1466 return d->params.realNumberPrecision;
1467}
1468
1469/*!
1470 Returns the status of the text stream.
1471
1472 \sa QTextStream::Status, setStatus(), resetStatus()
1473*/
1474
1475QTextStream::Status QTextStream::status() const
1476{
1477 Q_D(const QTextStream);
1478 return d->status;
1479}
1480
1481/*!
1482 \since 4.1
1483
1484 Resets the status of the text stream.
1485
1486 \sa QTextStream::Status, status(), setStatus()
1487*/
1488void QTextStream::resetStatus()
1489{
1490 Q_D(QTextStream);
1491 d->status = Ok;
1492}
1493
1494/*!
1495 \since 4.1
1496
1497 Sets the status of the text stream to the \a status given.
1498
1499 Subsequent calls to setStatus() are ignored until resetStatus()
1500 is called.
1501
1502 \sa Status, status(), resetStatus()
1503*/
1504void QTextStream::setStatus(Status status)
1505{
1506 Q_D(QTextStream);
1507 if (d->status == Ok)
1508 d->status = status;
1509}
1510
1511/*!
1512 Returns \c true if there is no more data to be read from the
1513 QTextStream; otherwise returns \c false. This is similar to, but not
1514 the same as calling QIODevice::atEnd(), as QTextStream also takes
1515 into account its internal Unicode buffer.
1516*/
1517bool QTextStream::atEnd() const
1518{
1519 Q_D(const QTextStream);
1520 CHECK_VALID_STREAM(true);
1521
1522 if (d->string)
1523 return d->string->size() == d->stringOffset;
1524 return d->readBuffer.isEmpty() && d->device->atEnd();
1525}
1526
1527/*!
1528 Reads the entire content of the stream, and returns it as a
1529 QString. Avoid this function when working on large files, as it
1530 will consume a significant amount of memory.
1531
1532 Calling \l {QTextStream::readLine()}{readLine()} is better if you do not know how much data is
1533 available.
1534
1535 \sa readLine()
1536*/
1537QString QTextStream::readAll()
1538{
1539 Q_D(QTextStream);
1540 CHECK_VALID_STREAM(QString());
1541
1542 return d->read(maxlen: std::numeric_limits<qsizetype>::max());
1543}
1544
1545/*!
1546 Reads one line of text from the stream, and returns it as a
1547 QString. The maximum allowed line length is set to \a maxlen. If
1548 the stream contains lines longer than this, then the lines will be
1549 split after \a maxlen characters and returned in parts.
1550
1551 If \a maxlen is 0, the lines can be of any length.
1552
1553 The returned line has no trailing end-of-line characters ("\\n"
1554 or "\\r\\n"), so calling QString::trimmed() can be unnecessary.
1555
1556 If the stream has read to the end of the file, \l {QTextStream::readLine()}{readLine()}
1557 will return a null QString. For strings, or for devices that support it,
1558 you can explicitly test for the end of the stream using atEnd().
1559
1560 \sa readAll(), QIODevice::readLine()
1561*/
1562QString QTextStream::readLine(qint64 maxlen)
1563{
1564 QString line;
1565
1566 readLineInto(line: &line, maxlen);
1567 return line;
1568}
1569
1570/*!
1571 \since 5.5
1572
1573 Reads one line of text from the stream into \a line.
1574 If \a line is \nullptr, the read line is not stored.
1575
1576 The maximum allowed line length is set to \a maxlen. If
1577 the stream contains lines longer than this, then the lines will be
1578 split after \a maxlen characters and returned in parts.
1579
1580 If \a maxlen is 0, the lines can be of any length.
1581
1582 The resulting line has no trailing end-of-line characters ("\\n"
1583 or "\\r\\n"), so calling QString::trimmed() can be unnecessary.
1584
1585 If \a line has sufficient capacity for the data that is about to be
1586 read, this function may not need to allocate new memory. Because of
1587 this, it can be faster than readLine().
1588
1589 Returns \c false if the stream has read to the end of the file or
1590 an error has occurred; otherwise returns \c true. The contents in
1591 \a line before the call are discarded in any case.
1592
1593 \sa readAll(), QIODevice::readLine(), QIODevice::readLineInto()
1594*/
1595bool QTextStream::readLineInto(QString *line, qint64 maxlen)
1596{
1597 Q_D(QTextStream);
1598 // keep in sync with CHECK_VALID_STREAM
1599 if (!d->string && !d->device) {
1600 qWarning(msg: "QTextStream: No device");
1601 if (line && !line->isNull())
1602 line->resize(size: 0);
1603 return false;
1604 }
1605
1606 const QChar *readPtr;
1607 qsizetype length;
1608 if (!d->scan(ptr: &readPtr, length: &length, maxlen: qsizetype(maxlen), delimiter: QTextStreamPrivate::EndOfLine)) {
1609 if (line && !line->isNull())
1610 line->resize(size: 0);
1611 return false;
1612 }
1613
1614 if (Q_LIKELY(line))
1615 line->setUnicode(unicode: readPtr, size: length);
1616 d->consumeLastToken();
1617 return true;
1618}
1619
1620/*!
1621 \since 4.1
1622
1623 Reads at most \a maxlen characters from the stream, and returns the data
1624 read as a QString.
1625
1626 \sa readAll(), readLine(), QIODevice::read()
1627*/
1628QString QTextStream::read(qint64 maxlen)
1629{
1630 Q_D(QTextStream);
1631 CHECK_VALID_STREAM(QString());
1632
1633 if (maxlen <= 0)
1634 return QString::fromLatin1(ba: ""); // empty, not null
1635
1636 return d->read(maxlen: q26::saturate_cast<qsizetype>(x: maxlen));
1637}
1638
1639/*!
1640 \internal
1641*/
1642QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret)
1643{
1644 scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: NotSpace);
1645 consumeLastToken();
1646
1647 // detect integer encoding
1648 int base = params.integerBase;
1649 if (base == 0) {
1650 QChar ch;
1651 if (!getChar(ch: &ch))
1652 return npsInvalidPrefix;
1653 if (ch == u'0') {
1654 QChar ch2;
1655 if (!getChar(ch: &ch2)) {
1656 // Result is the number 0
1657 *ret = 0;
1658 return npsOk;
1659 }
1660 ch2 = ch2.toLower();
1661
1662 if (ch2 == u'x') {
1663 base = 16;
1664 } else if (ch2 == u'b') {
1665 base = 2;
1666 } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
1667 base = 8;
1668 } else {
1669 base = 10;
1670 }
1671 ungetChar(ch: ch2);
1672 } else if (ch == locale.negativeSign() || ch == locale.positiveSign() || ch.isDigit()) {
1673 base = 10;
1674 } else {
1675 ungetChar(ch);
1676 return npsInvalidPrefix;
1677 }
1678 ungetChar(ch);
1679 // State of the stream is now the same as on entry
1680 // (cursor is at prefix),
1681 // and local variable 'base' has been set appropriately.
1682 }
1683
1684 qulonglong val=0;
1685 switch (base) {
1686 case 2: {
1687 QChar pf1, pf2, dig;
1688 // Parse prefix '0b'
1689 if (!getChar(ch: &pf1) || pf1 != u'0')
1690 return npsInvalidPrefix;
1691 if (!getChar(ch: &pf2) || pf2.toLower() != u'b')
1692 return npsInvalidPrefix;
1693 // Parse digits
1694 qsizetype ndigits = 0;
1695 while (getChar(ch: &dig)) {
1696 char16_t n = dig.toLower().unicode();
1697 if (n == u'0' || n == u'1') {
1698 val <<= 1;
1699 val += n - u'0';
1700 } else {
1701 ungetChar(ch: dig);
1702 break;
1703 }
1704 ndigits++;
1705 }
1706 if (ndigits == 0) {
1707 // Unwind the prefix and abort
1708 ungetChar(ch: pf2);
1709 ungetChar(ch: pf1);
1710 return npsMissingDigit;
1711 }
1712 break;
1713 }
1714 case 8: {
1715 QChar pf, dig;
1716 // Parse prefix u'0'
1717 if (!getChar(ch: &pf) || pf != u'0')
1718 return npsInvalidPrefix;
1719 // Parse digits
1720 qsizetype ndigits = 0;
1721 while (getChar(ch: &dig)) {
1722 char16_t n = dig.toLower().unicode();
1723 if (isOctalDigit(c: n)) {
1724 val *= 8;
1725 val += n - u'0';
1726 } else {
1727 ungetChar(ch: dig);
1728 break;
1729 }
1730 ndigits++;
1731 }
1732 if (ndigits == 0) {
1733 // Unwind the prefix and abort
1734 ungetChar(ch: pf);
1735 return npsMissingDigit;
1736 }
1737 break;
1738 }
1739 case 10: {
1740 // Parse sign (or first digit)
1741 QChar sign;
1742 qsizetype ndigits = 0;
1743 if (!getChar(ch: &sign))
1744 return npsMissingDigit;
1745 if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1746 if (!sign.isDigit()) {
1747 ungetChar(ch: sign);
1748 return npsMissingDigit;
1749 }
1750 val += sign.digitValue();
1751 ndigits++;
1752 }
1753 // Parse digits
1754 QChar ch;
1755 while (getChar(ch: &ch)) {
1756 if (ch.isDigit()) {
1757 val *= 10;
1758 val += ch.digitValue();
1759 } else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
1760 continue;
1761 } else {
1762 ungetChar(ch);
1763 break;
1764 }
1765 ndigits++;
1766 }
1767 if (ndigits == 0)
1768 return npsMissingDigit;
1769 if (sign == locale.negativeSign()) {
1770 qlonglong ival = qlonglong(val);
1771 if (ival > 0)
1772 ival = -ival;
1773 val = qulonglong(ival);
1774 }
1775 break;
1776 }
1777 case 16: {
1778 QChar pf1, pf2, dig;
1779 // Parse prefix ' 0x'
1780 if (!getChar(ch: &pf1) || pf1 != u'0')
1781 return npsInvalidPrefix;
1782 if (!getChar(ch: &pf2) || pf2.toLower() != u'x')
1783 return npsInvalidPrefix;
1784 // Parse digits
1785 qsizetype ndigits = 0;
1786 while (getChar(ch: &dig)) {
1787 const int h = fromHex(c: dig.unicode());
1788 if (h != -1) {
1789 val <<= 4;
1790 val += h;
1791 } else {
1792 ungetChar(ch: dig);
1793 break;
1794 }
1795 ndigits++;
1796 }
1797 if (ndigits == 0) {
1798 return npsMissingDigit;
1799 }
1800 break;
1801 }
1802 default:
1803 // Unsupported integerBase
1804 return npsInvalidPrefix;
1805 }
1806
1807 if (ret)
1808 *ret = val;
1809 return npsOk;
1810}
1811
1812/*!
1813 \internal
1814 (hihi)
1815*/
1816bool QTextStreamPrivate::getReal(double *f)
1817{
1818 // We use a table-driven FSM to parse floating point numbers
1819 // strtod() cannot be used directly since we may be reading from a
1820 // QIODevice.
1821 enum ParserState {
1822 Init = 0,
1823 Sign = 1,
1824 Mantissa = 2,
1825 Dot = 3,
1826 Abscissa = 4,
1827 ExpMark = 5,
1828 ExpSign = 6,
1829 Exponent = 7,
1830 Nan1 = 8,
1831 Nan2 = 9,
1832 Inf1 = 10,
1833 Inf2 = 11,
1834 NanInf = 12,
1835 Done = 13
1836 };
1837 enum InputToken {
1838 None = 0,
1839 InputSign = 1,
1840 InputDigit = 2,
1841 InputDot = 3,
1842 InputExp = 4,
1843 InputI = 5,
1844 InputN = 6,
1845 InputF = 7,
1846 InputA = 8,
1847 InputT = 9
1848 };
1849
1850 static const uchar table[13][10] = {
1851 // None InputSign InputDigit InputDot InputExp InputI InputN InputF InputA InputT
1852 { 0, Sign, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 0 Init
1853 { 0, 0, Mantissa, Dot, 0, Inf1, Nan1, 0, 0, 0 }, // 1 Sign
1854 { Done, Done, Mantissa, Dot, ExpMark, 0, 0, 0, 0, 0 }, // 2 Mantissa
1855 { 0, 0, Abscissa, 0, 0, 0, 0, 0, 0, 0 }, // 3 Dot
1856 { Done, Done, Abscissa, Done, ExpMark, 0, 0, 0, 0, 0 }, // 4 Abscissa
1857 { 0, ExpSign, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 5 ExpMark
1858 { 0, 0, Exponent, 0, 0, 0, 0, 0, 0, 0 }, // 6 ExpSign
1859 { Done, Done, Exponent, Done, Done, 0, 0, 0, 0, 0 }, // 7 Exponent
1860 { 0, 0, 0, 0, 0, 0, 0, 0, Nan2, 0 }, // 8 Nan1
1861 { 0, 0, 0, 0, 0, 0, NanInf, 0, 0, 0 }, // 9 Nan2
1862 { 0, 0, 0, 0, 0, 0, Inf2, 0, 0, 0 }, // 10 Inf1
1863 { 0, 0, 0, 0, 0, 0, 0, NanInf, 0, 0 }, // 11 Inf2
1864 { Done, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 11 NanInf
1865 };
1866
1867 ParserState state = Init;
1868 InputToken input = None;
1869
1870 scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: NotSpace);
1871 consumeLastToken();
1872
1873 const qsizetype BufferSize = 128;
1874 char buf[BufferSize];
1875 qsizetype i = 0;
1876
1877 QChar c;
1878 while (getChar(ch: &c)) {
1879 switch (c.unicode()) {
1880 case u'0': case u'1': case u'2': case u'3': case u'4':
1881 case u'5': case u'6': case u'7': case u'8': case u'9':
1882 input = InputDigit;
1883 break;
1884 case u'i': case u'I':
1885 input = InputI;
1886 break;
1887 case u'n': case u'N':
1888 input = InputN;
1889 break;
1890 case u'f': case u'F':
1891 input = InputF;
1892 break;
1893 case u'a': case u'A':
1894 input = InputA;
1895 break;
1896 case u't': case u'T':
1897 input = InputT;
1898 break;
1899 default: {
1900 QChar lc = c.toLower();
1901 if (lc == locale.decimalPoint().toLower())
1902 input = InputDot;
1903 else if (lc == locale.exponential().toLower())
1904 input = InputExp;
1905 else if (lc == locale.negativeSign().toLower()
1906 || lc == locale.positiveSign().toLower())
1907 input = InputSign;
1908 else if (locale != QLocale::c() // backward-compatibility
1909 && lc == locale.groupSeparator().toLower())
1910 input = InputDigit; // well, it isn't a digit, but no one cares.
1911 else
1912 input = None;
1913 }
1914 break;
1915 }
1916
1917 state = ParserState(table[state][input]);
1918
1919 if (state == Init || state == Done || i > (BufferSize - 5)) {
1920 ungetChar(ch: c);
1921 if (i > (BufferSize - 5)) { // ignore rest of digits
1922 while (getChar(ch: &c)) {
1923 if (!c.isDigit()) {
1924 ungetChar(ch: c);
1925 break;
1926 }
1927 }
1928 }
1929 break;
1930 }
1931
1932 buf[i++] = c.toLatin1();
1933 }
1934
1935 if (i == 0)
1936 return false;
1937 if (!f)
1938 return true;
1939 buf[i] = '\0';
1940
1941 // backward-compatibility. Old implementation supported +nan/-nan
1942 // for some reason. QLocale only checks for lower-case
1943 // nan/+inf/-inf, so here we also check for uppercase and mixed
1944 // case versions.
1945 if (!qstricmp(buf, "nan") || !qstricmp(buf, "+nan") || !qstricmp(buf, "-nan")) {
1946 *f = qt_qnan();
1947 return true;
1948 } else if (!qstricmp(buf, "+inf") || !qstricmp(buf, "inf")) {
1949 *f = qt_inf();
1950 return true;
1951 } else if (!qstricmp(buf, "-inf")) {
1952 *f = -qt_inf();
1953 return true;
1954 }
1955 bool ok;
1956 *f = locale.toDouble(s: QString::fromLatin1(ba: buf), ok: &ok);
1957 return ok;
1958}
1959
1960/*!
1961 Reads a character from the stream and stores it in \a c. Returns a
1962 reference to the QTextStream, so several operators can be
1963 nested. Example:
1964
1965 \snippet code/src_corelib_io_qtextstream.cpp 7
1966
1967 Whitespace is \e not skipped.
1968*/
1969
1970QTextStream &QTextStream::operator>>(QChar &c)
1971{
1972 Q_D(QTextStream);
1973 CHECK_VALID_STREAM(*this);
1974 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
1975 if (!d->getChar(ch: &c))
1976 setStatus(ReadPastEnd);
1977 return *this;
1978}
1979
1980/*!
1981 \overload
1982
1983 Reads a character from the stream and stores it in \a c. The
1984 character from the stream is converted to ISO-8859-1 before it is
1985 stored.
1986
1987 \sa QChar::toLatin1()
1988*/
1989QTextStream &QTextStream::operator>>(char &c)
1990{
1991 QChar ch;
1992 *this >> ch;
1993 c = ch.toLatin1();
1994 return *this;
1995}
1996
1997/*!
1998 \fn QTextStream &QTextStream::operator>>(char16_t &c)
1999 \overload
2000 \since 6.4
2001
2002 Reads a character from the stream and stores it in \a c.
2003*/
2004
2005/*!
2006 Reads an integer from the stream and stores it in \a i, then
2007 returns a reference to the QTextStream. The number is cast to
2008 the correct type before it is stored. If no number was detected on
2009 the stream, \a i is set to 0.
2010
2011 By default, QTextStream will attempt to detect the base of the
2012 number using the following rules:
2013
2014 \table
2015 \header \li Prefix \li Base
2016 \row \li "0b" or "0B" \li 2 (binary)
2017 \row \li "0" followed by "0-7" \li 8 (octal)
2018 \row \li "0" otherwise \li 10 (decimal)
2019 \row \li "0x" or "0X" \li 16 (hexadecimal)
2020 \row \li "1" to "9" \li 10 (decimal)
2021 \endtable
2022
2023 By calling setIntegerBase(), you can specify the integer base
2024 explicitly. This will disable the auto-detection, and speed up
2025 QTextStream slightly.
2026
2027 Leading whitespace is skipped.
2028*/
2029QTextStream &QTextStream::operator>>(signed short &i)
2030{
2031 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed short);
2032}
2033
2034/*!
2035 \overload
2036
2037 Stores the integer in the unsigned short \a i.
2038*/
2039QTextStream &QTextStream::operator>>(unsigned short &i)
2040{
2041 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned short);
2042}
2043
2044/*!
2045 \overload
2046
2047 Stores the integer in the signed int \a i.
2048*/
2049QTextStream &QTextStream::operator>>(signed int &i)
2050{
2051 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed int);
2052}
2053
2054/*!
2055 \overload
2056
2057 Stores the integer in the unsigned int \a i.
2058*/
2059QTextStream &QTextStream::operator>>(unsigned int &i)
2060{
2061 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned int);
2062}
2063
2064/*!
2065 \overload
2066
2067 Stores the integer in the signed long \a i.
2068*/
2069QTextStream &QTextStream::operator>>(signed long &i)
2070{
2071 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed long);
2072}
2073
2074/*!
2075 \overload
2076
2077 Stores the integer in the unsigned long \a i.
2078*/
2079QTextStream &QTextStream::operator>>(unsigned long &i)
2080{
2081 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned long);
2082}
2083
2084/*!
2085 \overload
2086
2087 Stores the integer in the qlonglong \a i.
2088*/
2089QTextStream &QTextStream::operator>>(qlonglong &i)
2090{
2091 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(qlonglong);
2092}
2093
2094/*!
2095 \overload
2096
2097 Stores the integer in the qulonglong \a i.
2098*/
2099QTextStream &QTextStream::operator>>(qulonglong &i)
2100{
2101 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(qulonglong);
2102}
2103
2104/*!
2105 Reads a real number from the stream and stores it in \a f, then
2106 returns a reference to the QTextStream. The number is cast to
2107 the correct type. If no real number is detect on the stream, \a f
2108 is set to 0.0.
2109
2110 As a special exception, QTextStream allows the strings "nan" and "inf" to
2111 represent NAN and INF floats or doubles.
2112
2113 Leading whitespace is skipped.
2114*/
2115QTextStream &QTextStream::operator>>(float &f)
2116{
2117 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(float);
2118}
2119
2120/*!
2121 \overload
2122
2123 Stores the real number in the double \a f.
2124*/
2125QTextStream &QTextStream::operator>>(double &f)
2126{
2127 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(double);
2128}
2129
2130/*!
2131 Reads a word from the stream and stores it in \a str, then returns
2132 a reference to the stream. Words are separated by whitespace
2133 (i.e., all characters for which QChar::isSpace() returns \c true).
2134
2135 Leading whitespace is skipped.
2136*/
2137QTextStream &QTextStream::operator>>(QString &str)
2138{
2139 Q_D(QTextStream);
2140 CHECK_VALID_STREAM(*this);
2141
2142 str.clear();
2143 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2144 d->consumeLastToken();
2145
2146 const QChar *ptr;
2147 qsizetype length;
2148 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: QTextStreamPrivate::Space)) {
2149 setStatus(ReadPastEnd);
2150 return *this;
2151 }
2152
2153 str = QString(ptr, length);
2154 d->consumeLastToken();
2155 return *this;
2156}
2157
2158/*!
2159 \overload
2160
2161 Converts the word to UTF-8, then stores it in \a array.
2162
2163 \sa QString::toLatin1()
2164*/
2165QTextStream &QTextStream::operator>>(QByteArray &array)
2166{
2167 Q_D(QTextStream);
2168 CHECK_VALID_STREAM(*this);
2169
2170 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2171 d->consumeLastToken();
2172
2173 const QChar *ptr;
2174 qsizetype length;
2175 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: QTextStreamPrivate::Space)) {
2176 setStatus(ReadPastEnd);
2177 array.clear();
2178 return *this;
2179 }
2180
2181 array = QStringView(ptr, length).toUtf8();
2182
2183 d->consumeLastToken();
2184 return *this;
2185}
2186
2187/*!
2188 \overload
2189
2190 Converts the word to UTF-8 and stores it in \a c, terminated by a '\\0'
2191 character. If no word is available, only the '\\0' character is stored.
2192
2193 Warning: Although convenient, this operator is dangerous and must
2194 be used with care. QTextStream assumes that \a c points to a
2195 buffer with enough space to hold the word. If the buffer is too
2196 small, your application may crash. For a word consisting of \c{n} QChars,
2197 the buffer needs to be at least \c{3*n+1} characters long.
2198
2199 If possible, use the QByteArray operator instead.
2200*/
2201QTextStream &QTextStream::operator>>(char *c)
2202{
2203 Q_D(QTextStream);
2204 *c = 0;
2205 CHECK_VALID_STREAM(*this);
2206 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2207 d->consumeLastToken();
2208
2209 const QChar *ptr;
2210 qsizetype length;
2211 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: QTextStreamPrivate::Space)) {
2212 setStatus(ReadPastEnd);
2213 return *this;
2214 }
2215
2216 QStringEncoder encoder(QStringConverter::Utf8);
2217 char *e = encoder.appendToBuffer(out: c, in: QStringView(ptr, length));
2218 *e = '\0';
2219 d->consumeLastToken();
2220 return *this;
2221}
2222
2223/*!
2224 \internal
2225 */
2226void QTextStreamPrivate::putNumber(qulonglong number, bool negative)
2227{
2228 unsigned flags = 0;
2229 const QTextStream::NumberFlags numberFlags = params.numberFlags;
2230 if (numberFlags & QTextStream::ShowBase)
2231 flags |= QLocaleData::ShowBase;
2232 // ForceSign is irrelevant when we'll be including a sign in any case:
2233 if ((numberFlags & QTextStream::ForceSign) && !negative)
2234 flags |= QLocaleData::AlwaysShowSign;
2235 if (numberFlags & QTextStream::UppercaseBase)
2236 flags |= QLocaleData::UppercaseBase;
2237 if (numberFlags & QTextStream::UppercaseDigits)
2238 flags |= QLocaleData::CapitalEorX;
2239
2240 // Group digits. For backward compatibility, we skip this for the C locale.
2241 if (locale != QLocale::c() && !locale.numberOptions().testFlag(flag: QLocale::OmitGroupSeparator))
2242 flags |= QLocaleData::GroupDigits;
2243
2244 const QLocaleData *dd = locale.d->m_data;
2245 int base = params.integerBase ? params.integerBase : 10;
2246 QString result = dd->unsLongLongToString(l: number, precision: -1, base, width: -1, flags);
2247 if (negative) {
2248 result.prepend(s: locale.negativeSign());
2249 } else if (number == 0 && base == 8 && params.numberFlags & QTextStream::ShowBase
2250 && result == "0"_L1) {
2251 // Workaround for backward compatibility - in octal form with ShowBase
2252 // flag set, zero should get its 0 prefix before its 0 value, but
2253 // QLocalePrivate only adds the prefix if the number doesn't start with
2254 // a zero.
2255 result.prepend(c: u'0');
2256 }
2257 putString(data: result, mode: PutStringMode::Number);
2258}
2259
2260/*!
2261 Writes the character \a c to the stream, then returns a reference
2262 to the QTextStream.
2263
2264 \sa setFieldWidth()
2265*/
2266QTextStream &QTextStream::operator<<(QChar c)
2267{
2268 Q_D(QTextStream);
2269 CHECK_VALID_STREAM(*this);
2270 d->putChar(ch: c);
2271 return *this;
2272}
2273
2274/*!
2275 \overload
2276
2277 Converts \a c from ASCII to a QChar, then writes it to the stream.
2278*/
2279QTextStream &QTextStream::operator<<(char c)
2280{
2281 Q_D(QTextStream);
2282 CHECK_VALID_STREAM(*this);
2283 d->putChar(ch: QChar::fromLatin1(c));
2284 return *this;
2285}
2286
2287/*!
2288 \fn QTextStream &QTextStream::operator<<(char16_t c)
2289 \overload
2290 \since 6.3.1
2291
2292 Writes the Unicode character \a c to the stream, then returns a
2293 reference to the QTextStream.
2294*/
2295
2296/*!
2297 Writes the integer number \a i to the stream, then returns a
2298 reference to the QTextStream. By default, the number is stored in
2299 decimal form, but you can also set the base by calling
2300 setIntegerBase().
2301
2302 \sa setFieldWidth(), setNumberFlags()
2303*/
2304QTextStream &QTextStream::operator<<(signed short i)
2305{
2306 Q_D(QTextStream);
2307 CHECK_VALID_STREAM(*this);
2308 d->putNumber(number: QtPrivate::qUnsignedAbs(t: i), negative: i < 0);
2309 return *this;
2310}
2311
2312/*!
2313 \overload
2314
2315 Writes the unsigned short \a i to the stream.
2316*/
2317QTextStream &QTextStream::operator<<(unsigned short i)
2318{
2319 Q_D(QTextStream);
2320 CHECK_VALID_STREAM(*this);
2321 d->putNumber(number: (qulonglong)i, negative: false);
2322 return *this;
2323}
2324
2325/*!
2326 \overload
2327
2328 Writes the signed int \a i to the stream.
2329*/
2330QTextStream &QTextStream::operator<<(signed int i)
2331{
2332 Q_D(QTextStream);
2333 CHECK_VALID_STREAM(*this);
2334 d->putNumber(number: QtPrivate::qUnsignedAbs(t: i), negative: i < 0);
2335 return *this;
2336}
2337
2338/*!
2339 \overload
2340
2341 Writes the unsigned int \a i to the stream.
2342*/
2343QTextStream &QTextStream::operator<<(unsigned int i)
2344{
2345 Q_D(QTextStream);
2346 CHECK_VALID_STREAM(*this);
2347 d->putNumber(number: (qulonglong)i, negative: false);
2348 return *this;
2349}
2350
2351/*!
2352 \overload
2353
2354 Writes the signed long \a i to the stream.
2355*/
2356QTextStream &QTextStream::operator<<(signed long i)
2357{
2358 Q_D(QTextStream);
2359 CHECK_VALID_STREAM(*this);
2360 d->putNumber(number: QtPrivate::qUnsignedAbs(t: i), negative: i < 0);
2361 return *this;
2362}
2363
2364/*!
2365 \overload
2366
2367 Writes the unsigned long \a i to the stream.
2368*/
2369QTextStream &QTextStream::operator<<(unsigned long i)
2370{
2371 Q_D(QTextStream);
2372 CHECK_VALID_STREAM(*this);
2373 d->putNumber(number: (qulonglong)i, negative: false);
2374 return *this;
2375}
2376
2377/*!
2378 \overload
2379
2380 Writes the qlonglong \a i to the stream.
2381*/
2382QTextStream &QTextStream::operator<<(qlonglong i)
2383{
2384 Q_D(QTextStream);
2385 CHECK_VALID_STREAM(*this);
2386 d->putNumber(number: QtPrivate::qUnsignedAbs(t: i), negative: i < 0);
2387 return *this;
2388}
2389
2390/*!
2391 \overload
2392
2393 Writes the qulonglong \a i to the stream.
2394*/
2395QTextStream &QTextStream::operator<<(qulonglong i)
2396{
2397 Q_D(QTextStream);
2398 CHECK_VALID_STREAM(*this);
2399 d->putNumber(number: i, negative: false);
2400 return *this;
2401}
2402
2403/*!
2404 Writes the real number \a f to the stream, then returns a
2405 reference to the QTextStream. By default, QTextStream stores it
2406 using SmartNotation, with up to 6 digits of precision. You can
2407 change the textual representation QTextStream will use for real
2408 numbers by calling setRealNumberNotation(),
2409 setRealNumberPrecision() and setNumberFlags().
2410
2411 \sa setFieldWidth(), setRealNumberNotation(),
2412 setRealNumberPrecision(), setNumberFlags()
2413*/
2414QTextStream &QTextStream::operator<<(float f)
2415{
2416 return *this << double(f);
2417}
2418
2419/*!
2420 \overload
2421
2422 Writes the double \a f to the stream.
2423*/
2424QTextStream &QTextStream::operator<<(double f)
2425{
2426 Q_D(QTextStream);
2427 CHECK_VALID_STREAM(*this);
2428
2429 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
2430 switch (realNumberNotation()) {
2431 case FixedNotation:
2432 form = QLocaleData::DFDecimal;
2433 break;
2434 case ScientificNotation:
2435 form = QLocaleData::DFExponent;
2436 break;
2437 case SmartNotation:
2438 form = QLocaleData::DFSignificantDigits;
2439 break;
2440 }
2441
2442 uint flags = 0;
2443 const QLocale::NumberOptions numberOptions = locale().numberOptions();
2444 if (numberFlags() & ShowBase)
2445 flags |= QLocaleData::ShowBase;
2446 if (numberFlags() & ForceSign)
2447 flags |= QLocaleData::AlwaysShowSign;
2448 if (numberFlags() & UppercaseBase)
2449 flags |= QLocaleData::UppercaseBase;
2450 if (numberFlags() & UppercaseDigits)
2451 flags |= QLocaleData::CapitalEorX;
2452 if (numberFlags() & ForcePoint) {
2453 flags |= QLocaleData::ForcePoint;
2454
2455 // Only for backwards compatibility
2456 flags |= QLocaleData::AddTrailingZeroes | QLocaleData::ShowBase;
2457 }
2458 if (locale() != QLocale::c() && !(numberOptions & QLocale::OmitGroupSeparator))
2459 flags |= QLocaleData::GroupDigits;
2460 if (!(numberOptions & QLocale::OmitLeadingZeroInExponent))
2461 flags |= QLocaleData::ZeroPadExponent;
2462 if (numberOptions & QLocale::IncludeTrailingZeroesAfterDot)
2463 flags |= QLocaleData::AddTrailingZeroes;
2464
2465 const QLocaleData *dd = d->locale.d->m_data;
2466 QString num = dd->doubleToString(d: f, precision: d->params.realNumberPrecision, form, width: -1, flags);
2467 d->putString(data: num, mode: QTextStreamPrivate::PutStringMode::Number);
2468 return *this;
2469}
2470
2471/*!
2472 Writes the string \a string to the stream, and returns a reference
2473 to the QTextStream. The string is first encoded using the assigned
2474 encoding (the default is UTF-8) before it is written to the stream.
2475
2476 \sa setFieldWidth(), setEncoding()
2477*/
2478QTextStream &QTextStream::operator<<(const QString &string)
2479{
2480 Q_D(QTextStream);
2481 CHECK_VALID_STREAM(*this);
2482 d->putString(data: string);
2483 return *this;
2484}
2485
2486/*!
2487 \overload
2488
2489 Writes \a string to the stream, and returns a reference to the
2490 QTextStream.
2491 \since 5.12
2492*/
2493QTextStream &QTextStream::operator<<(QStringView string)
2494{
2495 Q_D(QTextStream);
2496 CHECK_VALID_STREAM(*this);
2497 d->putString(data: string);
2498 return *this;
2499}
2500
2501/*!
2502 \overload
2503
2504 Writes \a string to the stream, and returns a reference to the
2505 QTextStream.
2506*/
2507QTextStream &QTextStream::operator<<(QLatin1StringView string)
2508{
2509 Q_D(QTextStream);
2510 CHECK_VALID_STREAM(*this);
2511 d->putString(data: string);
2512 return *this;
2513}
2514
2515/*!
2516 \overload
2517
2518 Writes \a array to the stream. The contents of \a array are
2519 converted with QString::fromUtf8().
2520*/
2521QTextStream &QTextStream::operator<<(const QByteArray &array)
2522{
2523 Q_D(QTextStream);
2524 CHECK_VALID_STREAM(*this);
2525 d->putString(data: QUtf8StringView{array});
2526 return *this;
2527}
2528
2529/*!
2530 \overload
2531
2532 Writes the constant string pointed to by \a string to the stream. \a
2533 string is assumed to be in UTF-8 encoding. This operator
2534 is convenient when working with constant string data. Example:
2535
2536 \snippet code/src_corelib_io_qtextstream.cpp 8
2537
2538 Warning: QTextStream assumes that \a string points to a string of
2539 text, terminated by a '\\0' character. If there is no terminating
2540 '\\0' character, your application may crash.
2541*/
2542QTextStream &QTextStream::operator<<(const char *string)
2543{
2544 Q_D(QTextStream);
2545 CHECK_VALID_STREAM(*this);
2546 d->putString(data: QUtf8StringView(string));
2547 return *this;
2548}
2549
2550/*!
2551 \overload
2552
2553 Writes \a ptr to the stream as a hexadecimal number with a base.
2554*/
2555
2556QTextStream &QTextStream::operator<<(const void *ptr)
2557{
2558 Q_D(QTextStream);
2559 CHECK_VALID_STREAM(*this);
2560 const int oldBase = d->params.integerBase;
2561 const NumberFlags oldFlags = d->params.numberFlags;
2562 d->params.integerBase = 16;
2563 d->params.numberFlags |= ShowBase;
2564 d->putNumber(number: reinterpret_cast<quintptr>(ptr), negative: false);
2565 d->params.integerBase = oldBase;
2566 d->params.numberFlags = oldFlags;
2567 return *this;
2568}
2569
2570/*!
2571 \fn QTextStream::operator bool() const
2572 \since 6.10
2573
2574 Returns whether this stream has no errors (status() returns \l{Ok}).
2575*/
2576
2577namespace Qt {
2578
2579/*!
2580 Calls QTextStream::setIntegerBase(2) on \a stream and returns \a
2581 stream.
2582
2583 \since 5.14
2584
2585 \sa oct(), dec(), hex(), {QTextStream manipulators}
2586*/
2587QTextStream &bin(QTextStream &stream)
2588{
2589 stream.setIntegerBase(2);
2590 return stream;
2591}
2592
2593/*!
2594 Calls QTextStream::setIntegerBase(8) on \a stream and returns \a
2595 stream.
2596
2597 \since 5.14
2598
2599 \sa bin(), dec(), hex(), {QTextStream manipulators}
2600*/
2601QTextStream &oct(QTextStream &stream)
2602{
2603 stream.setIntegerBase(8);
2604 return stream;
2605}
2606
2607/*!
2608 Calls QTextStream::setIntegerBase(10) on \a stream and returns \a
2609 stream.
2610
2611 \since 5.14
2612
2613 \sa bin(), oct(), hex(), {QTextStream manipulators}
2614*/
2615QTextStream &dec(QTextStream &stream)
2616{
2617 stream.setIntegerBase(10);
2618 return stream;
2619}
2620
2621/*!
2622 Calls QTextStream::setIntegerBase(16) on \a stream and returns \a
2623 stream.
2624
2625 \since 5.14
2626
2627 \note The hex modifier can only be used for writing to streams.
2628 \sa bin(), oct(), dec(), {QTextStream manipulators}
2629*/
2630QTextStream &hex(QTextStream &stream)
2631{
2632 stream.setIntegerBase(16);
2633 return stream;
2634}
2635
2636/*!
2637 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() |
2638 QTextStream::ShowBase) on \a stream and returns \a stream.
2639
2640 \since 5.14
2641
2642 \sa noshowbase(), forcesign(), forcepoint(), {QTextStream manipulators}
2643*/
2644QTextStream &showbase(QTextStream &stream)
2645{
2646 stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase);
2647 return stream;
2648}
2649
2650/*!
2651 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() |
2652 QTextStream::ForceSign) on \a stream and returns \a stream.
2653
2654 \since 5.14
2655
2656 \sa noforcesign(), forcepoint(), showbase(), {QTextStream manipulators}
2657*/
2658QTextStream &forcesign(QTextStream &stream)
2659{
2660 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign);
2661 return stream;
2662}
2663
2664/*!
2665 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() |
2666 QTextStream::ForcePoint) on \a stream and returns \a stream.
2667
2668 \since 5.14
2669
2670 \sa noforcepoint(), forcesign(), showbase(), {QTextStream manipulators}
2671*/
2672QTextStream &forcepoint(QTextStream &stream)
2673{
2674 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForcePoint);
2675 return stream;
2676}
2677
2678/*!
2679 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() &
2680 ~QTextStream::ShowBase) on \a stream and returns \a stream.
2681
2682 \since 5.14
2683
2684 \sa showbase(), noforcesign(), noforcepoint(), {QTextStream manipulators}
2685*/
2686QTextStream &noshowbase(QTextStream &stream)
2687{
2688 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ShowBase);
2689 return stream;
2690}
2691
2692/*!
2693 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() &
2694 ~QTextStream::ForceSign) on \a stream and returns \a stream.
2695
2696 \since 5.14
2697
2698 \sa forcesign(), noforcepoint(), noshowbase(), {QTextStream manipulators}
2699*/
2700QTextStream &noforcesign(QTextStream &stream)
2701{
2702 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForceSign);
2703 return stream;
2704}
2705
2706/*!
2707 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() &
2708 ~QTextStream::ForcePoint) on \a stream and returns \a stream.
2709
2710 \since 5.14
2711
2712 \sa forcepoint(), noforcesign(), noshowbase(), {QTextStream manipulators}
2713*/
2714QTextStream &noforcepoint(QTextStream &stream)
2715{
2716 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForcePoint);
2717 return stream;
2718}
2719
2720/*!
2721 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() |
2722 QTextStream::UppercaseBase) on \a stream and returns \a stream.
2723
2724 \since 5.14
2725
2726 \sa lowercasebase(), uppercasedigits(), {QTextStream manipulators}
2727*/
2728QTextStream &uppercasebase(QTextStream &stream)
2729{
2730 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseBase);
2731 return stream;
2732}
2733
2734/*!
2735 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() |
2736 QTextStream::UppercaseDigits) on \a stream and returns \a stream.
2737
2738 \since 5.14
2739
2740 \sa lowercasedigits(), uppercasebase(), {QTextStream manipulators}
2741*/
2742QTextStream &uppercasedigits(QTextStream &stream)
2743{
2744 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseDigits);
2745 return stream;
2746}
2747
2748/*!
2749 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() &
2750 ~QTextStream::UppercaseBase) on \a stream and returns \a stream.
2751
2752 \since 5.14
2753
2754 \sa uppercasebase(), lowercasedigits(), {QTextStream manipulators}
2755*/
2756QTextStream &lowercasebase(QTextStream &stream)
2757{
2758 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseBase);
2759 return stream;
2760}
2761
2762/*!
2763 Calls QTextStream::setNumberFlags(QTextStream::numberFlags() &
2764 ~QTextStream::UppercaseDigits) on \a stream and returns \a stream.
2765
2766 \since 5.14
2767
2768 \sa uppercasedigits(), lowercasebase(), {QTextStream manipulators}
2769*/
2770QTextStream &lowercasedigits(QTextStream &stream)
2771{
2772 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseDigits);
2773 return stream;
2774}
2775
2776/*!
2777 Calls QTextStream::setRealNumberNotation(QTextStream::FixedNotation)
2778 on \a stream and returns \a stream.
2779
2780 \since 5.14
2781
2782 \sa scientific(), {QTextStream manipulators}
2783*/
2784QTextStream &fixed(QTextStream &stream)
2785{
2786 stream.setRealNumberNotation(QTextStream::FixedNotation);
2787 return stream;
2788}
2789
2790/*!
2791 Calls QTextStream::setRealNumberNotation(QTextStream::ScientificNotation)
2792 on \a stream and returns \a stream.
2793
2794 \since 5.14
2795
2796 \sa fixed(), {QTextStream manipulators}
2797*/
2798QTextStream &scientific(QTextStream &stream)
2799{
2800 stream.setRealNumberNotation(QTextStream::ScientificNotation);
2801 return stream;
2802}
2803
2804/*!
2805 Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft)
2806 on \a stream and returns \a stream.
2807
2808 \since 5.14
2809
2810 \sa right(), center(), {QTextStream manipulators}
2811*/
2812QTextStream &left(QTextStream &stream)
2813{
2814 stream.setFieldAlignment(QTextStream::AlignLeft);
2815 return stream;
2816}
2817
2818/*!
2819 Calls QTextStream::setFieldAlignment(QTextStream::AlignRight)
2820 on \a stream and returns \a stream.
2821
2822 \since 5.14
2823
2824 \sa left(), center(), {QTextStream manipulators}
2825*/
2826QTextStream &right(QTextStream &stream)
2827{
2828 stream.setFieldAlignment(QTextStream::AlignRight);
2829 return stream;
2830}
2831
2832/*!
2833 Calls QTextStream::setFieldAlignment(QTextStream::AlignCenter)
2834 on \a stream and returns \a stream.
2835
2836 \since 5.14
2837
2838 \sa left(), right(), {QTextStream manipulators}
2839*/
2840QTextStream &center(QTextStream &stream)
2841{
2842 stream.setFieldAlignment(QTextStream::AlignCenter);
2843 return stream;
2844}
2845
2846/*!
2847 Writes '\\n' to the \a stream and flushes the stream.
2848
2849 Equivalent to
2850
2851 \snippet code/src_corelib_io_qtextstream.cpp 9
2852
2853 Note: On Windows, all '\\n' characters are written as '\\r\\n' if
2854 QTextStream's device or string is opened using the \l QIODeviceBase::Text flag.
2855
2856 \since 5.14
2857
2858 \sa flush(), reset(), {QTextStream manipulators}
2859*/
2860QTextStream &endl(QTextStream &stream)
2861{
2862 return stream << '\n'_L1 << Qt::flush;
2863}
2864
2865/*!
2866 Calls QTextStream::flush() on \a stream and returns \a stream.
2867
2868 \since 5.14
2869
2870 \sa endl(), reset(), {QTextStream manipulators}
2871*/
2872QTextStream &flush(QTextStream &stream)
2873{
2874 stream.flush();
2875 return stream;
2876}
2877
2878/*!
2879 Calls QTextStream::reset() on \a stream and returns \a stream.
2880
2881 \since 5.14
2882
2883 \sa flush(), {QTextStream manipulators}
2884*/
2885QTextStream &reset(QTextStream &stream)
2886{
2887 stream.reset();
2888 return stream;
2889}
2890
2891/*!
2892 Calls \l {QTextStream::}{skipWhiteSpace()} on \a stream and returns \a stream.
2893
2894 \since 5.14
2895
2896 \sa {QTextStream manipulators}
2897*/
2898QTextStream &ws(QTextStream &stream)
2899{
2900 stream.skipWhiteSpace();
2901 return stream;
2902}
2903
2904} // namespace Qt
2905
2906/*!
2907 \fn QTextStreamManipulator qSetFieldWidth(int width)
2908 \relates QTextStream
2909
2910 Equivalent to QTextStream::setFieldWidth(\a width).
2911*/
2912
2913/*!
2914 \fn QTextStreamManipulator qSetPadChar(QChar ch)
2915 \relates QTextStream
2916
2917 Equivalent to QTextStream::setPadChar(\a ch).
2918*/
2919
2920/*!
2921 \fn QTextStreamManipulator qSetRealNumberPrecision(int precision)
2922 \relates QTextStream
2923
2924 Equivalent to QTextStream::setRealNumberPrecision(\a precision).
2925*/
2926
2927
2928namespace Qt {
2929/*!
2930 Toggles insertion of the Byte Order Mark on \a stream when QTextStream is
2931 used with a UTF encoding.
2932
2933 \since 5.14
2934
2935 \sa QTextStream::setGenerateByteOrderMark(), {QTextStream manipulators}
2936*/
2937QTextStream &bom(QTextStream &stream)
2938{
2939 stream.setGenerateByteOrderMark(true);
2940 return stream;
2941}
2942
2943} // namespace Qt
2944
2945
2946/*!
2947 \since 6.0
2948 Sets the encoding for this stream to \a encoding. The encoding is used for
2949 decoding any data that is read from the assigned device, and for
2950 encoding any data that is written. By default,
2951 QStringConverter::Utf8 is used, and automatic unicode
2952 detection is enabled.
2953
2954 If QTextStream operates on a string, this function does nothing.
2955
2956 \warning If you call this function while the text stream is reading
2957 from an open sequential socket, the internal buffer may still contain
2958 text decoded using the old encoding.
2959
2960 \sa encoding(), setAutoDetectUnicode(), setLocale()
2961*/
2962void QTextStream::setEncoding(QStringConverter::Encoding encoding)
2963{
2964 Q_D(QTextStream);
2965 if (d->encoding == encoding)
2966 return;
2967
2968 qint64 seekPos = -1;
2969 if (!d->readBuffer.isEmpty()) {
2970 if (!d->device->isSequential()) {
2971 seekPos = pos();
2972 }
2973 }
2974
2975 d->encoding = encoding;
2976 d->toUtf16 = QStringDecoder(d->encoding);
2977 bool generateBOM = !d->hasWrittenData && d->generateBOM;
2978 d->fromUtf16 = QStringEncoder(d->encoding,
2979 generateBOM ? QStringEncoder::Flag::WriteBom : QStringEncoder::Flag::Default);
2980
2981 if (seekPos >=0 && !d->readBuffer.isEmpty())
2982 seek(pos: seekPos);
2983}
2984
2985/*!
2986 Returns the encoding that is current assigned to the stream.
2987
2988 \sa setEncoding(), setAutoDetectUnicode(), locale()
2989*/
2990QStringConverter::Encoding QTextStream::encoding() const
2991{
2992 Q_D(const QTextStream);
2993 return d->encoding;
2994}
2995
2996/*!
2997 If \a enabled is true, QTextStream will attempt to detect Unicode encoding
2998 by peeking into the stream data to see if it can find the UTF-8, UTF-16, or
2999 UTF-32 Byte Order Mark (BOM). If this mark is found, QTextStream will
3000 replace the current encoding with the UTF encoding.
3001
3002 This function can be used together with setEncoding(). It is common
3003 to set the encoding to UTF-8, and then enable UTF-16 detection.
3004
3005 \sa autoDetectUnicode(), setEncoding()
3006*/
3007void QTextStream::setAutoDetectUnicode(bool enabled)
3008{
3009 Q_D(QTextStream);
3010 d->autoDetectUnicode = enabled;
3011}
3012
3013/*!
3014 Returns \c true if automatic Unicode detection is enabled, otherwise
3015 returns \c false. Automatic Unicode detection is enabled by default.
3016
3017 \sa setAutoDetectUnicode(), setEncoding()
3018*/
3019bool QTextStream::autoDetectUnicode() const
3020{
3021 Q_D(const QTextStream);
3022 return d->autoDetectUnicode;
3023}
3024
3025/*!
3026 If \a generate is true and a UTF encoding is used, QTextStream will insert
3027 the BOM (Byte Order Mark) before any data has been written to the
3028 device. If \a generate is false, no BOM will be inserted. This function
3029 must be called before any data is written. Otherwise, it does nothing.
3030
3031 \sa generateByteOrderMark(), {Qt::}{bom()}
3032*/
3033void QTextStream::setGenerateByteOrderMark(bool generate)
3034{
3035 Q_D(QTextStream);
3036 if (d->hasWrittenData || d->generateBOM == generate)
3037 return;
3038
3039 d->generateBOM = generate;
3040 d->fromUtf16 = QStringEncoder(d->encoding, generate ? QStringConverter::Flag::WriteBom : QStringConverter::Flag::Default);
3041}
3042
3043/*!
3044 Returns \c true if QTextStream is set to generate the UTF BOM (Byte Order
3045 Mark) when using a UTF encoding; otherwise returns \c false. UTF BOM generation is
3046 set to false by default.
3047
3048 \sa setGenerateByteOrderMark()
3049*/
3050bool QTextStream::generateByteOrderMark() const
3051{
3052 Q_D(const QTextStream);
3053 return d->generateBOM;
3054}
3055
3056/*!
3057 \since 4.5
3058
3059 Sets the locale for this stream to \a locale. The specified locale is
3060 used for conversions between numbers and their string representations.
3061
3062 The default locale is C and it is a special case - the thousands
3063 group separator is not used for backward compatibility reasons.
3064
3065 \sa locale()
3066*/
3067void QTextStream::setLocale(const QLocale &locale)
3068{
3069 Q_D(QTextStream);
3070 d->locale = locale;
3071}
3072
3073/*!
3074 \since 4.5
3075
3076 Returns the locale for this stream. The default locale is C.
3077
3078 \sa setLocale()
3079*/
3080QLocale QTextStream::locale() const
3081{
3082 Q_D(const QTextStream);
3083 return d->locale;
3084}
3085
3086QT_END_NAMESPACE
3087

source code of qtbase/src/corelib/serialization/qtextstream.cpp