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