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