1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41//#define QTEXTSTREAM_DEBUG
42static const int QTEXTSTREAM_BUFFERSIZE = 16384;
43
44/*!
45 \class QTextStream
46 \inmodule QtCore
47
48 \brief The QTextStream class provides a convenient interface for
49 reading and writing text.
50
51 \ingroup io
52 \ingroup string-processing
53 \reentrant
54
55 QTextStream can operate on a QIODevice, a QByteArray or a
56 QString. Using QTextStream's streaming operators, you can
57 conveniently read and write words, lines and numbers. For
58 generating text, QTextStream supports formatting options for field
59 padding and alignment, and formatting of numbers. Example:
60
61 \snippet code/src_corelib_io_qtextstream.cpp 0
62
63 It's also common to use QTextStream to read console input and write
64 console output. QTextStream is locale aware, and will automatically decode
65 standard input using the correct 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
245QT_BEGIN_NAMESPACE
246
247// Returns a human readable representation of the first \a len
248// characters in \a data.
249static 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}
279QT_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
320QT_BEGIN_NAMESPACE
321
322//-------------------------------------------------------------------
323
324/*!
325 \internal
326*/
327QTextStreamPrivate::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*/
342QTextStreamPrivate::~QTextStreamPrivate()
343{
344 if (deleteDevice) {
345#ifndef QT_NO_QOBJECT
346 device->blockSignals(b: true);
347#endif
348 delete device;
349 }
350#if QT_CONFIG(textcodec)
351 delete readConverterSavedState;
352#endif
353}
354
355#if QT_CONFIG(textcodec)
356static void resetCodecConverterStateHelper(QTextCodec::ConverterState *state)
357{
358 state->~ConverterState();
359 new (state) QTextCodec::ConverterState;
360}
361
362static 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
376void 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*/
390void 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(state: &readConverterState);
407 resetCodecConverterStateHelper(state: &writeConverterState);
408 delete readConverterSavedState;
409 readConverterSavedState = nullptr;
410 writeConverterState.flags |= QTextCodec::IgnoreHeader;
411 autoDetectUnicode = true;
412#endif
413}
414
415/*!
416 \internal
417*/
418bool 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(data: buf, maxlen: qMin<qint64>(a: sizeof(buf), b: maxBytes));
453 else
454 bytesRead = device->read(data: buf, maxlen: 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(ba: QByteArray::fromRawData(buf, size: bytesRead), defaultCodec: 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(in: buf, length: bytesRead, state: &readConverterState)
491 : QString::fromLatin1(str: buf, size: 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(size: 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*/
536void QTextStreamPrivate::resetReadBuffer()
537{
538 readBuffer.clear();
539 readBufferOffset = 0;
540 readBufferStartDevicePos = (device ? device->pos() : 0);
541}
542
543/*!
544 \internal
545*/
546void 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(in: writeBuffer.data(), length: writeBuffer.size(), state: &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 *>(object: 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
622QString QTextStreamPrivate::read(int maxlen)
623{
624 QString ret;
625 if (string) {
626 lastTokenSize = qMin(a: maxlen, b: string->size() - stringOffset);
627 ret = string->mid(position: stringOffset, n: lastTokenSize);
628 } else {
629 while (readBuffer.size() - readBufferOffset < maxlen && fillReadBuffer()) ;
630 lastTokenSize = qMin(a: maxlen, b: readBuffer.size() - readBufferOffset);
631 ret = readBuffer.mid(position: readBufferOffset, n: 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*/
648bool 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*/
740inline 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*/
751inline void QTextStreamPrivate::consumeLastToken()
752{
753 if (lastTokenSize)
754 consume(nchars: lastTokenSize);
755 lastTokenSize = 0;
756}
757
758/*!
759 \internal
760*/
761inline 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(newPos: device->pos());
776 } else if (readBufferOffset > QTEXTSTREAM_BUFFERSIZE) {
777 readBuffer = readBuffer.remove(i: 0,len: readBufferOffset);
778 readConverterSavedStateOffset += readBufferOffset;
779 readBufferOffset = 0;
780 }
781 }
782}
783
784/*!
785 \internal
786*/
787inline 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(dest: readConverterSavedState, src: &readConverterState);
799#endif
800
801 readBufferStartDevicePos = newPos;
802 readConverterSavedStateOffset = 0;
803}
804
805/*!
806 \internal
807*/
808inline 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(dest: &readConverterState, src: readConverterSavedState);
815 } else {
816 // the only state we could save was the initial
817 // so reset to that
818 resetCodecConverterStateHelper(state: &readConverterState);
819 }
820#endif
821}
822
823/*!
824 \internal
825*/
826void QTextStreamPrivate::write(const QChar *data, int len)
827{
828 if (string) {
829 // ### What about seek()??
830 string->append(uc: data, len);
831 } else {
832 writeBuffer.append(uc: data, len);
833 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
834 flushWriteBuffer();
835 }
836}
837
838/*!
839 \internal
840*/
841inline void QTextStreamPrivate::write(QChar ch)
842{
843 if (string) {
844 // ### What about seek()??
845 string->append(c: ch);
846 } else {
847 writeBuffer += ch;
848 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
849 flushWriteBuffer();
850 }
851}
852
853/*!
854 \internal
855*/
856void QTextStreamPrivate::write(QLatin1String data)
857{
858 if (string) {
859 // ### What about seek()??
860 string->append(s: data);
861 } else {
862 writeBuffer += data;
863 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
864 flushWriteBuffer();
865 }
866}
867
868/*!
869 \internal
870*/
871void QTextStreamPrivate::writePadding(int len)
872{
873 if (string) {
874 // ### What about seek()??
875 string->resize(size: string->size() + len, fillChar: params.padChar);
876 } else {
877 writeBuffer.resize(size: writeBuffer.size() + len, fillChar: params.padChar);
878 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
879 flushWriteBuffer();
880 }
881}
882
883/*!
884 \internal
885*/
886inline 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(size: 1);
897 return true;
898}
899
900/*!
901 \internal
902*/
903inline void QTextStreamPrivate::ungetChar(QChar ch)
904{
905 if (string) {
906 if (stringOffset == 0)
907 string->prepend(c: ch);
908 else
909 (*string)[--stringOffset] = ch;
910 return;
911 }
912
913 if (readBufferOffset == 0) {
914 readBuffer.prepend(c: ch);
915 return;
916 }
917
918 readBuffer[--readBufferOffset] = ch;
919}
920
921/*!
922 \internal
923*/
924inline void QTextStreamPrivate::putChar(QChar ch)
925{
926 if (params.fieldWidth > 0)
927 putString(data: &ch, len: 1);
928 else
929 write(ch);
930}
931
932
933/*!
934 \internal
935*/
936QTextStreamPrivate::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: left, .right: right };
958}
959
960/*!
961 \internal
962*/
963void 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(data: &sign, len: 1);
976 ++data;
977 --len;
978 }
979 }
980
981 writePadding(len: pad.left);
982 write(data, len);
983 writePadding(len: pad.right);
984 } else {
985 write(data, len);
986 }
987}
988
989/*!
990 \internal
991*/
992void 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(len: 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(data: &sign, len: 1);
1005 data = QLatin1String(data.data() + 1, data.size() - 1);
1006 }
1007 }
1008
1009 writePadding(len: pad.left);
1010 write(data);
1011 writePadding(len: 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*/
1023QTextStream::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*/
1036QTextStream::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(stream: this, device: 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*/
1055QTextStream::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*/
1073QTextStream::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(mode: openMode);
1083 d->deleteDevice = true;
1084#ifndef QT_NO_QOBJECT
1085 d->deviceClosedNotifier.setupDevice(stream: this, device: 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*/
1100QTextStream::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(stream: this, device: 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
1131QTextStream::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(f: fileHandle, ioFlags: openMode);
1140
1141 Q_D(QTextStream);
1142 d->device = file;
1143 d->deleteDevice = true;
1144#ifndef QT_NO_QOBJECT
1145 d->deviceClosedNotifier.setupDevice(stream: this, device: 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*/
1156QTextStream::~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*/
1171void 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*/
1183void 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*/
1193bool 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(state: &d->readConverterState);
1208 resetCodecConverterStateHelper(state: &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*/
1238qint64 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(pos: 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(maxBytes: 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(msg: "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*/
1294void QTextStream::skipWhiteSpace()
1295{
1296 Q_D(QTextStream);
1297 CHECK_VALID_STREAM(Q_VOID);
1298 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: 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*/
1312void 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(stream: this, device: 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*/
1339QIODevice *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*/
1352void 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(b: 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*/
1377QString *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*/
1391void 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*/
1402QTextStream::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*/
1423void 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*/
1434QChar 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*/
1452void 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*/
1463int 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*/
1477void 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*/
1488QTextStream::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*/
1504void 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*/
1516int 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*/
1530void 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*/
1541QTextStream::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*/
1556void QTextStream::setRealNumberPrecision(int precision)
1557{
1558 Q_D(QTextStream);
1559 if (precision < 0) {
1560 qWarning(msg: "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*/
1573int 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
1585QTextStream::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*/
1598void 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*/
1614void 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*/
1627bool 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*/
1647QString 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*/
1672QString QTextStream::readLine(qint64 maxlen)
1673{
1674 QString line;
1675
1676 readLineInto(line: &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*/
1705bool 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(msg: "QTextStream: No device");
1711 if (line && !line->isNull())
1712 line->resize(size: 0);
1713 return false;
1714 }
1715
1716 const QChar *readPtr;
1717 int length;
1718 if (!d->scan(ptr: &readPtr, length: &length, maxlen: int(maxlen), delimiter: QTextStreamPrivate::EndOfLine)) {
1719 if (line && !line->isNull())
1720 line->resize(size: 0);
1721 return false;
1722 }
1723
1724 if (Q_LIKELY(line))
1725 line->setUnicode(unicode: readPtr, size: 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*/
1738QString QTextStream::read(qint64 maxlen)
1739{
1740 Q_D(QTextStream);
1741 CHECK_VALID_STREAM(QString());
1742
1743 if (maxlen <= 0)
1744 return QString::fromLatin1(str: ""); // empty, not null
1745
1746 return d->read(maxlen: int(maxlen));
1747}
1748
1749/*!
1750 \internal
1751*/
1752QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret)
1753{
1754 scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: NotSpace);
1755 consumeLastToken();
1756
1757 // detect int encoding
1758 int base = params.integerBase;
1759 if (base == 0) {
1760 QChar ch;
1761 if (!getChar(ch: &ch))
1762 return npsInvalidPrefix;
1763 if (ch == QLatin1Char('0')) {
1764 QChar ch2;
1765 if (!getChar(ch: &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(ch: 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(ch: &pf1) || pf1 != QLatin1Char('0'))
1800 return npsInvalidPrefix;
1801 if (!getChar(ch: &pf2) || pf2.toLower() != QLatin1Char('b'))
1802 return npsInvalidPrefix;
1803 // Parse digits
1804 int ndigits = 0;
1805 while (getChar(ch: &dig)) {
1806 int n = dig.toLower().unicode();
1807 if (n == '0' || n == '1') {
1808 val <<= 1;
1809 val += n - '0';
1810 } else {
1811 ungetChar(ch: dig);
1812 break;
1813 }
1814 ndigits++;
1815 }
1816 if (ndigits == 0) {
1817 // Unwind the prefix and abort
1818 ungetChar(ch: pf2);
1819 ungetChar(ch: pf1);
1820 return npsMissingDigit;
1821 }
1822 break;
1823 }
1824 case 8: {
1825 QChar pf, dig;
1826 // Parse prefix '0'
1827 if (!getChar(ch: &pf) || pf != QLatin1Char('0'))
1828 return npsInvalidPrefix;
1829 // Parse digits
1830 int ndigits = 0;
1831 while (getChar(ch: &dig)) {
1832 int n = dig.toLower().unicode();
1833 if (n >= '0' && n <= '7') {
1834 val *= 8;
1835 val += n - '0';
1836 } else {
1837 ungetChar(ch: dig);
1838 break;
1839 }
1840 ndigits++;
1841 }
1842 if (ndigits == 0) {
1843 // Unwind the prefix and abort
1844 ungetChar(ch: 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(ch: &sign))
1854 return npsMissingDigit;
1855 if (sign != locale.negativeSign() && sign != locale.positiveSign()) {
1856 if (!sign.isDigit()) {
1857 ungetChar(ch: sign);
1858 return npsMissingDigit;
1859 }
1860 val += sign.digitValue();
1861 ndigits++;
1862 }
1863 // Parse digits
1864 QChar ch;
1865 while (getChar(ch: &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(ch: &pf1) || pf1 != QLatin1Char('0'))
1891 return npsInvalidPrefix;
1892 if (!getChar(ch: &pf2) || pf2.toLower() != QLatin1Char('x'))
1893 return npsInvalidPrefix;
1894 // Parse digits
1895 int ndigits = 0;
1896 while (getChar(ch: &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(ch: 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*/
1929bool 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(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: NotSpace);
1984 consumeLastToken();
1985
1986 const int BufferSize = 128;
1987 char buf[BufferSize];
1988 int i = 0;
1989
1990 QChar c;
1991 while (getChar(ch: &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(ch: c);
2034 if (i > (BufferSize - 5)) { // ignore rest of digits
2035 while (getChar(ch: &c)) {
2036 if (!c.isDigit()) {
2037 ungetChar(ch: 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(s: QString::fromLatin1(str: buf), ok: &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
2083QTextStream &QTextStream::operator>>(QChar &c)
2084{
2085 Q_D(QTextStream);
2086 CHECK_VALID_STREAM(*this);
2087 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2088 if (!d->getChar(ch: &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*/
2102QTextStream &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*/
2134QTextStream &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*/
2144QTextStream &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*/
2154QTextStream &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*/
2164QTextStream &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*/
2174QTextStream &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*/
2184QTextStream &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*/
2194QTextStream &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*/
2204QTextStream &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*/
2220QTextStream &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*/
2230QTextStream &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*/
2242QTextStream &QTextStream::operator>>(QString &str)
2243{
2244 Q_D(QTextStream);
2245 CHECK_VALID_STREAM(*this);
2246
2247 str.clear();
2248 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2249 d->consumeLastToken();
2250
2251 const QChar *ptr;
2252 int length;
2253 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: 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*/
2270QTextStream &QTextStream::operator>>(QByteArray &array)
2271{
2272 Q_D(QTextStream);
2273 CHECK_VALID_STREAM(*this);
2274
2275 array.clear();
2276 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2277 d->consumeLastToken();
2278
2279 const QChar *ptr;
2280 int length;
2281 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: 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*/
2306QTextStream &QTextStream::operator>>(char *c)
2307{
2308 Q_D(QTextStream);
2309 *c = 0;
2310 CHECK_VALID_STREAM(*this);
2311 d->scan(ptr: nullptr, length: nullptr, maxlen: 0, delimiter: QTextStreamPrivate::NotSpace);
2312 d->consumeLastToken();
2313
2314 const QChar *ptr;
2315 int length;
2316 if (!d->scan(ptr: &ptr, length: &length, maxlen: 0, delimiter: 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 */
2331void 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(flag: 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(l: -static_cast<qlonglong>(number), precision: -1,
2355 base, width: -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(l: number, precision: -1, base, width: -1, flags);
2362 result.prepend(c: locale.negativeSign());
2363 } else {
2364 result = dd->unsLongLongToString(l: number, precision: -1, base, width: -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(c: QLatin1Char('0'));
2370 }
2371 }
2372 putString(ch: result, number: 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*/
2381QTextStream &QTextStream::operator<<(QChar c)
2382{
2383 Q_D(QTextStream);
2384 CHECK_VALID_STREAM(*this);
2385 d->putChar(ch: 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*/
2394QTextStream &QTextStream::operator<<(char c)
2395{
2396 Q_D(QTextStream);
2397 CHECK_VALID_STREAM(*this);
2398 d->putChar(ch: 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*/
2410QTextStream &QTextStream::operator<<(signed short i)
2411{
2412 Q_D(QTextStream);
2413 CHECK_VALID_STREAM(*this);
2414 d->putNumber(number: (qulonglong)qAbs(t: qlonglong(i)), negative: i < 0);
2415 return *this;
2416}
2417
2418/*!
2419 \overload
2420
2421 Writes the unsigned short \a i to the stream.
2422*/
2423QTextStream &QTextStream::operator<<(unsigned short i)
2424{
2425 Q_D(QTextStream);
2426 CHECK_VALID_STREAM(*this);
2427 d->putNumber(number: (qulonglong)i, negative: false);
2428 return *this;
2429}
2430
2431/*!
2432 \overload
2433
2434 Writes the signed int \a i to the stream.
2435*/
2436QTextStream &QTextStream::operator<<(signed int i)
2437{
2438 Q_D(QTextStream);
2439 CHECK_VALID_STREAM(*this);
2440 d->putNumber(number: (qulonglong)qAbs(t: qlonglong(i)), negative: i < 0);
2441 return *this;
2442}
2443
2444/*!
2445 \overload
2446
2447 Writes the unsigned int \a i to the stream.
2448*/
2449QTextStream &QTextStream::operator<<(unsigned int i)
2450{
2451 Q_D(QTextStream);
2452 CHECK_VALID_STREAM(*this);
2453 d->putNumber(number: (qulonglong)i, negative: false);
2454 return *this;
2455}
2456
2457/*!
2458 \overload
2459
2460 Writes the signed long \a i to the stream.
2461*/
2462QTextStream &QTextStream::operator<<(signed long i)
2463{
2464 Q_D(QTextStream);
2465 CHECK_VALID_STREAM(*this);
2466 d->putNumber(number: (qulonglong)qAbs(t: qlonglong(i)), negative: i < 0);
2467 return *this;
2468}
2469
2470/*!
2471 \overload
2472
2473 Writes the unsigned long \a i to the stream.
2474*/
2475QTextStream &QTextStream::operator<<(unsigned long i)
2476{
2477 Q_D(QTextStream);
2478 CHECK_VALID_STREAM(*this);
2479 d->putNumber(number: (qulonglong)i, negative: false);
2480 return *this;
2481}
2482
2483/*!
2484 \overload
2485
2486 Writes the qlonglong \a i to the stream.
2487*/
2488QTextStream &QTextStream::operator<<(qlonglong i)
2489{
2490 Q_D(QTextStream);
2491 CHECK_VALID_STREAM(*this);
2492 d->putNumber(number: (qulonglong)qAbs(t: i), negative: i < 0);
2493 return *this;
2494}
2495
2496/*!
2497 \overload
2498
2499 Writes the qulonglong \a i to the stream.
2500*/
2501QTextStream &QTextStream::operator<<(qulonglong i)
2502{
2503 Q_D(QTextStream);
2504 CHECK_VALID_STREAM(*this);
2505 d->putNumber(number: i, negative: 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*/
2520QTextStream &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*/
2530QTextStream &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(d: f, precision: d->params.realNumberPrecision, form, width: -1, flags);
2573 d->putString(ch: num, number: 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*/
2585QTextStream &QTextStream::operator<<(const QString &string)
2586{
2587 Q_D(QTextStream);
2588 CHECK_VALID_STREAM(*this);
2589 d->putString(ch: 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*/
2600QTextStream &QTextStream::operator<<(QStringView string)
2601{
2602 Q_D(QTextStream);
2603 CHECK_VALID_STREAM(*this);
2604 d->putString(data: string.cbegin(), len: 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*/
2614QTextStream &QTextStream::operator<<(QLatin1String string)
2615{
2616 Q_D(QTextStream);
2617 CHECK_VALID_STREAM(*this);
2618 d->putString(data: 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*/
2629QTextStream &QTextStream::operator<<(const QStringRef &string)
2630{
2631 Q_D(QTextStream);
2632 CHECK_VALID_STREAM(*this);
2633 d->putString(data: string.data(), len: 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*/
2643QTextStream &QTextStream::operator<<(const QByteArray &array)
2644{
2645 Q_D(QTextStream);
2646 CHECK_VALID_STREAM(*this);
2647 d->putString(ch: QString::fromUtf8(str: array.constData(), size: 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*/
2664QTextStream &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(data: 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
2679QTextStream &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(number: reinterpret_cast<quintptr>(ptr), negative: 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
2831namespace 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*/
2841QTextStream &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*/
2855QTextStream &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*/
2869QTextStream &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*/
2884QTextStream &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*/
2898QTextStream &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*/
2912QTextStream &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*/
2926QTextStream &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*/
2940QTextStream &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*/
2954QTextStream &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*/
2968QTextStream &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*/
2982QTextStream &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*/
2996QTextStream &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*/
3010QTextStream &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*/
3024QTextStream &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*/
3038QTextStream &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*/
3052QTextStream &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*/
3066QTextStream &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*/
3080QTextStream &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*/
3094QTextStream &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*/
3114QTextStream &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*/
3126QTextStream &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*/
3139QTextStream &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*/
3152QTextStream &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
3188namespace 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*/
3197QTextStream &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*/
3220void 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(pos: 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*/
3246void QTextStream::setCodec(const char *codecName)
3247{
3248 QTextCodec *codec = QTextCodec::codecForName(name: 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*/
3258QTextCodec *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*/
3275void 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*/
3287bool 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*/
3301void QTextStream::setGenerateByteOrderMark(bool generate)
3302{
3303 Q_D(QTextStream);
3304 if (d->writeBuffer.isEmpty()) {
3305 d->writeConverterState.flags.setFlag(flag: QTextCodec::IgnoreHeader, on: !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*/
3316bool 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*/
3335void 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*/
3348QLocale 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:
3356namespace QTextStreamFunctions {
3357QTextStream &bin(QTextStream &s) { return Qt::bin(stream&: s); }
3358QTextStream &oct(QTextStream &s) { return Qt::oct(stream&: s); }
3359QTextStream &dec(QTextStream &s) { return Qt::dec(stream&: s); }
3360QTextStream &hex(QTextStream &s) { return Qt::hex(stream&: s); }
3361
3362QTextStream &showbase(QTextStream &s) { return Qt::showbase(stream&: s); }
3363QTextStream &forcesign(QTextStream &s) { return Qt::forcesign(stream&: s); }
3364QTextStream &forcepoint(QTextStream &s) { return Qt::forcepoint(stream&: s); }
3365QTextStream &noshowbase(QTextStream &s) { return Qt::noshowbase(stream&: s); }
3366QTextStream &noforcesign(QTextStream &s) { return Qt::noforcesign(stream&: s); }
3367QTextStream &noforcepoint(QTextStream &s) { return Qt::noforcepoint(stream&: s); }
3368
3369QTextStream &uppercasebase(QTextStream &s) { return Qt::uppercasebase(stream&: s); }
3370QTextStream &uppercasedigits(QTextStream &s) { return Qt::uppercasedigits(stream&: s); }
3371QTextStream &lowercasebase(QTextStream &s) { return Qt::lowercasebase(stream&: s); }
3372QTextStream &lowercasedigits(QTextStream &s) { return Qt::lowercasedigits(stream&: s); }
3373
3374QTextStream &fixed(QTextStream &s) { return Qt::fixed(stream&: s); }
3375QTextStream &scientific(QTextStream &s) { return Qt::scientific(stream&: s); }
3376
3377QTextStream &left(QTextStream &s) { return Qt::left(stream&: s); }
3378QTextStream &right(QTextStream &s) { return Qt::right(stream&: s); }
3379QTextStream &center(QTextStream &s) { return Qt::center(stream&: s); }
3380
3381QTextStream &endl(QTextStream &s) { return Qt::endl(stream&: s); }
3382QTextStream &flush(QTextStream &s) { return Qt::flush(stream&: s); }
3383QTextStream &reset(QTextStream &s) { return Qt::reset(stream&: s); }
3384
3385QTextStream &ws(QTextStream &s) { return Qt::ws(stream&: s); }
3386
3387#if QT_CONFIG(textcodec)
3388QTextStream &bom(QTextStream &s) { return Qt::bom(stream&: 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
3395Q_CORE_EXPORT QTextStream &bin(QTextStream &s) { return Qt::bin(stream&: s); }
3396Q_CORE_EXPORT QTextStream &oct(QTextStream &s) { return Qt::oct(stream&: s); }
3397Q_CORE_EXPORT QTextStream &dec(QTextStream &s) { return Qt::dec(stream&: s); }
3398Q_CORE_EXPORT QTextStream &hex(QTextStream &s) { return Qt::hex(stream&: s); }
3399
3400Q_CORE_EXPORT QTextStream &showbase(QTextStream &s) { return Qt::showbase(stream&: s); }
3401Q_CORE_EXPORT QTextStream &forcesign(QTextStream &s) { return Qt::forcesign(stream&: s); }
3402Q_CORE_EXPORT QTextStream &forcepoint(QTextStream &s) { return Qt::forcepoint(stream&: s); }
3403Q_CORE_EXPORT QTextStream &noshowbase(QTextStream &s) { return Qt::noshowbase(stream&: s); }
3404Q_CORE_EXPORT QTextStream &noforcesign(QTextStream &s) { return Qt::noforcesign(stream&: s); }
3405Q_CORE_EXPORT QTextStream &noforcepoint(QTextStream &s) { return Qt::noforcepoint(stream&: s); }
3406
3407Q_CORE_EXPORT QTextStream &uppercasebase(QTextStream &s) { return Qt::uppercasebase(stream&: s); }
3408Q_CORE_EXPORT QTextStream &uppercasedigits(QTextStream &s) { return Qt::uppercasedigits(stream&: s); }
3409Q_CORE_EXPORT QTextStream &lowercasebase(QTextStream &s) { return Qt::lowercasebase(stream&: s); }
3410Q_CORE_EXPORT QTextStream &lowercasedigits(QTextStream &s) { return Qt::lowercasedigits(stream&: s); }
3411
3412Q_CORE_EXPORT QTextStream &fixed(QTextStream &s) { return Qt::fixed(stream&: s); }
3413Q_CORE_EXPORT QTextStream &scientific(QTextStream &s) { return Qt::scientific(stream&: s); }
3414
3415Q_CORE_EXPORT QTextStream &left(QTextStream &s) { return Qt::left(stream&: s); }
3416Q_CORE_EXPORT QTextStream &right(QTextStream &s) { return Qt::right(stream&: s); }
3417Q_CORE_EXPORT QTextStream &center(QTextStream &s) { return Qt::center(stream&: s); }
3418
3419Q_CORE_EXPORT QTextStream &endl(QTextStream &s) { return Qt::endl(stream&: s); }
3420Q_CORE_EXPORT QTextStream &flush(QTextStream &s) { return Qt::flush(stream&: s); }
3421Q_CORE_EXPORT QTextStream &reset(QTextStream &s) { return Qt::reset(stream&: s); }
3422
3423Q_CORE_EXPORT QTextStream &ws(QTextStream &s) { return Qt::ws(stream&: s); }
3424
3425#if QT_CONFIG(textcodec)
3426Q_CORE_EXPORT QTextStream &bom(QTextStream &s) { return Qt::bom(stream&: s); }
3427#endif
3428#endif
3429
3430QT_END_NAMESPACE
3431
3432#ifndef QT_NO_QOBJECT
3433#include "moc_qtextstream_p.cpp"
3434#endif
3435

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