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