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

Last change on this file since 469 was 172, checked in by Dmitry A. Kuminov, 16 years ago

corelib/io, gui/dialogs: Handle DOS-like filesystem details (drives, slashes) on OS/2 similarly to Win32.

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