source: trunk/src/corelib/io/qtextstream.cpp@ 807

Last change on this file since 807 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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