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

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