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