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

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