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