Orb/Doxygen/qtools/qtextstream.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /****************************************************************************
       
     2 ** 
       
     3 **
       
     4 ** Implementation of QTextStream class
       
     5 **
       
     6 ** Created : 940922
       
     7 **
       
     8 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
       
     9 **
       
    10 ** This file is part of the tools module of the Qt GUI Toolkit.
       
    11 **
       
    12 ** This file may be distributed under the terms of the Q Public License
       
    13 ** as defined by Trolltech AS of Norway and appearing in the file
       
    14 ** LICENSE.QPL included in the packaging of this file.
       
    15 **
       
    16 ** This file may be distributed and/or modified under the terms of the
       
    17 ** GNU General Public License version 2 as published by the Free Software
       
    18 ** Foundation and appearing in the file LICENSE.GPL included in the
       
    19 ** packaging of this file.
       
    20 **
       
    21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
       
    22 ** licenses may use this file in accordance with the Qt Commercial License
       
    23 ** Agreement provided with the Software.
       
    24 **
       
    25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
       
    26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
       
    27 **
       
    28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
       
    29 **   information about Qt Commercial License Agreements.
       
    30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
       
    31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
       
    32 **
       
    33 ** Contact info@trolltech.com if any conditions of this licensing are
       
    34 ** not clear to you.
       
    35 **
       
    36 **********************************************************************/
       
    37 
       
    38 #include "qtextstream.h"
       
    39 
       
    40 #ifndef QT_NO_TEXTSTREAM
       
    41 #include "qtextcodec.h"
       
    42 #include "qregexp.h"
       
    43 #include "qbuffer.h"
       
    44 #include "qfile.h"
       
    45 #include <stdio.h>
       
    46 #include <ctype.h>
       
    47 #include <stdlib.h>
       
    48 
       
    49 #if defined(_OS_WIN32_)
       
    50 #include <windows.h>
       
    51 #endif
       
    52 
       
    53 // NOT REVISED
       
    54 /*!
       
    55   \class QTextStream qtextstream.h
       
    56 
       
    57   \brief The QTextStream class provides basic functions for reading and
       
    58   writing text using a QIODevice.
       
    59 
       
    60   \ingroup io
       
    61 
       
    62   \define endl
       
    63   \define bin
       
    64   \define oct
       
    65   \define dec
       
    66   \define hex
       
    67   \define flush
       
    68   \define ws
       
    69 
       
    70   The text stream class has a functional interface that is very
       
    71   similar to that of the standard C++ iostream class.  The difference
       
    72   between iostream and QTextStream is that our stream operates on a
       
    73   QIODevice, which is easily subclassed, while iostream operates on
       
    74   FILE * pointers, which can not be subclassed.
       
    75 
       
    76   Qt provides several global functions similar to the ones in iostream:
       
    77   <ul>
       
    78   <li> \c bin sets the QTextStream to read/write binary numbers
       
    79   <li> \c oct sets the QTextStream to read/write octal numbers
       
    80   <li> \c dec sets the QTextStream to read/write decimal numbers
       
    81   <li> \c hex sets the QTextStream to read/write hexadecimal numbers
       
    82   <li> \c endl forces a line break
       
    83   <li> \c flush forces the QIODevice to flush any buffered data
       
    84   <li> \c ws eats any available white space (on input)
       
    85   <li> \c reset resets the QTextStream to its default mode (see reset()).
       
    86   </ul>
       
    87 
       
    88   \warning By default, QTextStream will automatically detect whether
       
    89   integers in the stream are in decimal, octal, hexadecimal or binary
       
    90   format when reading from the stream. In particular, a leading '0'
       
    91   signifies octal, ie. the sequence "0100" will be interpreted as
       
    92   64.
       
    93 
       
    94   The QTextStream class reads and writes text and it is not
       
    95   appropriate for dealing with binary data (but QDataStream is).
       
    96 
       
    97   By default output of Unicode text (ie. QString) is done using the
       
    98   local 8-bit encoding.  This can be changed using the setEncoding()
       
    99   method.  For input, the QTextStream will auto-detect standard
       
   100   Unicode "byte order marked" text files, but otherwise the local
       
   101   8-bit encoding is used.
       
   102 
       
   103   \sa QDataStream
       
   104 */
       
   105 
       
   106 /*
       
   107   \class QTSManip qtextstream.h
       
   108 
       
   109   \brief The QTSManip class is an internal helper class for the
       
   110   QTextStream.
       
   111 
       
   112   It is generally a very bad idea to use this class directly in
       
   113   application programs.
       
   114 
       
   115   \internal
       
   116 
       
   117   This class makes it possible to give the QTextStream function objects
       
   118   with arguments, like this:
       
   119   \code
       
   120     QTextStream cout( stdout, IO_WriteOnly );
       
   121     cout << setprecision( 8 );		// QTSManip used here!
       
   122     cout << 3.14159265358979323846;
       
   123   \endcode
       
   124 
       
   125   The setprecision() function returns a QTSManip object.
       
   126   The QTSManip object contains a pointer to a member function in
       
   127   QTextStream and an integer argument.
       
   128   When serializing a QTSManip into a QTextStream, the function
       
   129   is executed with the argument.
       
   130 */
       
   131 
       
   132 /*! \fn QTSManip::QTSManip (QTSMFI m, int a)
       
   133 
       
   134   Constructs a QTSManip object which will call \a m (a member function
       
   135   in QTextStream which accepts a single int) with argument \a a when
       
   136   QTSManip::exec() is called.  Used internally in e.g. endl:
       
   137 
       
   138   \code
       
   139     s << "some text" << endl << "more text";
       
   140   \endcode
       
   141 */
       
   142 
       
   143 /*! \fn void QTSManip::exec (QTextStream& s)
       
   144 
       
   145   Calls the member function specified in the constructor, for object
       
   146   \a s.  Used internally in e.g. endl:
       
   147 
       
   148   \code
       
   149     s << "some text" << endl << "more text";
       
   150   \endcode
       
   151 */
       
   152 
       
   153 
       
   154 /*****************************************************************************
       
   155   QTextStream member functions
       
   156  *****************************************************************************/
       
   157 
       
   158 #if defined(CHECK_STATE)
       
   159 #undef  CHECK_STREAM_PRECOND
       
   160 #define CHECK_STREAM_PRECOND  if ( !dev ) {				\
       
   161 				qWarning( "QTextStream: No device" );	\
       
   162 				return *this; }
       
   163 #else
       
   164 #define CHECK_STREAM_PRECOND
       
   165 #endif
       
   166 
       
   167 
       
   168 #define I_SHORT		0x0010
       
   169 #define I_INT		0x0020
       
   170 #define I_LONG		0x0030
       
   171 #define I_TYPE_MASK	0x00f0
       
   172 
       
   173 #define I_BASE_2	QTS::bin
       
   174 #define I_BASE_8	QTS::oct
       
   175 #define I_BASE_10	QTS::dec
       
   176 #define I_BASE_16	QTS::hex
       
   177 #define I_BASE_MASK	(QTS::bin | QTS::oct | QTS::dec | QTS::hex)
       
   178 
       
   179 #define I_SIGNED	0x0100
       
   180 #define I_UNSIGNED	0x0200
       
   181 #define I_SIGN_MASK	0x0f00
       
   182 
       
   183 
       
   184 static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.
       
   185 
       
   186 const int QTextStream::basefield   = I_BASE_MASK;
       
   187 const int QTextStream::adjustfield = ( QTextStream::left |
       
   188 				       QTextStream::right |
       
   189 				       QTextStream::internal );
       
   190 const int QTextStream::floatfield  = ( QTextStream::scientific |
       
   191 				       QTextStream::fixed );
       
   192 
       
   193 
       
   194 class QTextStreamPrivate {
       
   195 public:
       
   196 #ifndef QT_NO_TEXTCODEC
       
   197     QTextStreamPrivate() : decoder( 0 ), sourceType( NotSet ) {}
       
   198     ~QTextStreamPrivate() { delete decoder; }
       
   199     QTextDecoder *decoder;		//???
       
   200 #else
       
   201     QTextStreamPrivate() : sourceType( NotSet ) {}
       
   202     ~QTextStreamPrivate() { }
       
   203 #endif
       
   204     QString ungetcBuf;
       
   205 
       
   206     enum SourceType { NotSet, IODevice, String, ByteArray, File };
       
   207     SourceType sourceType;
       
   208 };
       
   209 
       
   210 
       
   211 // skips whitespace and returns the first non-whitespace character
       
   212 QChar QTextStream::eat_ws()
       
   213 {
       
   214     QChar c;
       
   215     do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );
       
   216     return c;
       
   217 }
       
   218 
       
   219 void QTextStream::init()
       
   220 {
       
   221     // ### ungetcBuf = QEOF;
       
   222     dev = 0;					// no device set
       
   223     fstrm = owndev = FALSE;
       
   224     mapper = 0;
       
   225     d = new QTextStreamPrivate;
       
   226     doUnicodeHeader = TRUE;	 //default to autodetect
       
   227     latin1 = TRUE;		 // ### should use local?
       
   228     internalOrder = QChar::networkOrdered(); //default to network order
       
   229 }
       
   230 
       
   231 /*!
       
   232   Constructs a data stream that has no IO device.
       
   233 */
       
   234 
       
   235 QTextStream::QTextStream()
       
   236 {
       
   237     init();
       
   238     setEncoding( Locale ); //###
       
   239     reset();
       
   240     d->sourceType = QTextStreamPrivate::NotSet;
       
   241 }
       
   242 
       
   243 /*!
       
   244   Constructs a text stream that uses the IO device \a iod.
       
   245 */
       
   246 
       
   247 QTextStream::QTextStream( QIODevice *iod )
       
   248 {
       
   249     init();
       
   250     setEncoding( Locale ); //###
       
   251     dev = iod;					// set device
       
   252     reset();
       
   253     d->sourceType = QTextStreamPrivate::IODevice;
       
   254 }
       
   255 
       
   256 // TODO: use special-case handling of this case in QTextStream, and
       
   257 //	 simplify this class to only deal with QChar or QString data.
       
   258 class QStringBuffer : public QIODevice {
       
   259 public:
       
   260     QStringBuffer( QString* str );
       
   261     ~QStringBuffer();
       
   262     bool  open( int m );
       
   263     void  close();
       
   264     void  flush();
       
   265     uint  size() const;
       
   266     int   at()   const;
       
   267     bool  at( int pos );
       
   268     int   readBlock( char *p, uint len );
       
   269     int writeBlock( const char *p, uint len );
       
   270     int   getch();
       
   271     int   putch( int ch );
       
   272     int   ungetch( int ch );
       
   273 protected:
       
   274     QString* s;
       
   275 
       
   276 private:        // Disabled copy constructor and operator=
       
   277     QStringBuffer( const QStringBuffer & );
       
   278     QStringBuffer &operator=( const QStringBuffer & );
       
   279 };
       
   280 
       
   281 
       
   282 QStringBuffer::QStringBuffer( QString* str )
       
   283 {
       
   284     s = str;
       
   285 }
       
   286 
       
   287 QStringBuffer::~QStringBuffer()
       
   288 {
       
   289 }
       
   290 
       
   291 
       
   292 bool QStringBuffer::open( int m )
       
   293 {
       
   294     if ( !s ) {
       
   295 #if defined(CHECK_STATE)
       
   296 	qWarning( "QStringBuffer::open: No string" );
       
   297 #endif
       
   298 	return FALSE;
       
   299     }
       
   300     if ( isOpen() ) {                           // buffer already open
       
   301 #if defined(CHECK_STATE)
       
   302 	qWarning( "QStringBuffer::open: Buffer already open" );
       
   303 #endif
       
   304 	return FALSE;
       
   305     }
       
   306     setMode( m );
       
   307     if ( m & IO_Truncate ) {                    // truncate buffer
       
   308 	s->truncate( 0 );
       
   309     }
       
   310     if ( m & IO_Append ) {                      // append to end of buffer
       
   311 	ioIndex = s->length()*sizeof(QChar);
       
   312     } else {
       
   313 	ioIndex = 0;
       
   314     }
       
   315     setState( IO_Open );
       
   316     setStatus( 0 );
       
   317     return TRUE;
       
   318 }
       
   319 
       
   320 void QStringBuffer::close()
       
   321 {
       
   322     if ( isOpen() ) {
       
   323 	setFlags( IO_Direct );
       
   324 	ioIndex = 0;
       
   325     }
       
   326 }
       
   327 
       
   328 void QStringBuffer::flush()
       
   329 {
       
   330 }
       
   331 
       
   332 uint QStringBuffer::size() const
       
   333 {
       
   334     return s ? s->length()*sizeof(QChar) : 0;
       
   335 }
       
   336 
       
   337 int  QStringBuffer::at()   const
       
   338 {
       
   339     return ioIndex;
       
   340 }
       
   341 
       
   342 bool QStringBuffer::at( int pos )
       
   343 {
       
   344 #if defined(CHECK_STATE)
       
   345     if ( !isOpen() ) {
       
   346 	qWarning( "QStringBuffer::at: Buffer is not open" );
       
   347 	return FALSE;
       
   348     }
       
   349 #endif
       
   350     if ( (uint)pos >= s->length()*2 ) {
       
   351 #if defined(CHECK_RANGE)
       
   352 	qWarning( "QStringBuffer::at: Index %d out of range", pos );
       
   353 #endif
       
   354 	return FALSE;
       
   355     }
       
   356     ioIndex = pos;
       
   357     return TRUE;
       
   358 }
       
   359 
       
   360 
       
   361 int  QStringBuffer::readBlock( char *p, uint len )
       
   362 {
       
   363 #if defined(CHECK_STATE)
       
   364     CHECK_PTR( p );
       
   365     if ( !isOpen() ) {                          // buffer not open
       
   366 	qWarning( "QStringBuffer::readBlock: Buffer not open" );
       
   367 	return -1;
       
   368     }
       
   369     if ( !isReadable() ) {                      // reading not permitted
       
   370 	qWarning( "QStringBuffer::readBlock: Read operation not permitted" );
       
   371 	return -1;
       
   372     }
       
   373 #endif
       
   374     if ( (uint)ioIndex + len > s->length()*sizeof(QChar) ) {
       
   375 	// overflow
       
   376 	if ( (uint)ioIndex >= s->length()*sizeof(QChar) ) {
       
   377 	    setStatus( IO_ReadError );
       
   378 	    return -1;
       
   379 	} else {
       
   380 	    len = s->length()*2 - (uint)ioIndex;
       
   381 	}
       
   382     }
       
   383     memcpy( p, ((const char*)(s->unicode()))+ioIndex, len );
       
   384     ioIndex += len;
       
   385     return len;
       
   386 }
       
   387 
       
   388 int QStringBuffer::writeBlock( const char *p, uint len )
       
   389 {
       
   390 #if defined(CHECK_NULL)
       
   391     if ( p == 0 && len != 0 )
       
   392 	qWarning( "QStringBuffer::writeBlock: Null pointer error" );
       
   393 #endif
       
   394 #if defined(CHECK_STATE)
       
   395     if ( !isOpen() ) {                          // buffer not open
       
   396 	qWarning( "QStringBuffer::writeBlock: Buffer not open" );
       
   397 	return -1;
       
   398     }
       
   399     if ( !isWritable() ) {                      // writing not permitted
       
   400 	qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );
       
   401 	return -1;
       
   402     }
       
   403     if ( ioIndex&1 ) {
       
   404 	qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );
       
   405 	return -1;
       
   406     }
       
   407     if ( len&1 ) {
       
   408 	qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );
       
   409 	return -1;
       
   410     }
       
   411 #endif
       
   412     s->replace(ioIndex/2, len/2, (QChar*)p, len/2);
       
   413     ioIndex += len;
       
   414     return len;
       
   415 }
       
   416 
       
   417 int QStringBuffer::getch()
       
   418 {
       
   419 #if defined(CHECK_STATE)
       
   420     if ( !isOpen() ) {                          // buffer not open
       
   421 	qWarning( "QStringBuffer::getch: Buffer not open" );
       
   422 	return -1;
       
   423     }
       
   424     if ( !isReadable() ) {                      // reading not permitted
       
   425 	qWarning( "QStringBuffer::getch: Read operation not permitted" );
       
   426 	return -1;
       
   427     }
       
   428 #endif
       
   429     if ( (uint)ioIndex >= s->length()*2 ) {           // overflow
       
   430 	setStatus( IO_ReadError );
       
   431 	return -1;
       
   432     }
       
   433     return *((char*)s->unicode() + ioIndex++);
       
   434 }
       
   435 
       
   436 int QStringBuffer::putch( int ch )
       
   437 {
       
   438     char c = ch;
       
   439     if ( writeBlock(&c,1) < 0 )
       
   440 	return -1;
       
   441     else
       
   442 	return ch;
       
   443 }
       
   444 
       
   445 int QStringBuffer::ungetch( int ch )
       
   446 {
       
   447 #if defined(CHECK_STATE)
       
   448     if ( !isOpen() ) {                          // buffer not open
       
   449 	qWarning( "QStringBuffer::ungetch: Buffer not open" );
       
   450 	return -1;
       
   451     }
       
   452     if ( !isReadable() ) {                      // reading not permitted
       
   453 	qWarning( "QStringBuffer::ungetch: Read operation not permitted" );
       
   454 	return -1;
       
   455     }
       
   456 #endif
       
   457     if ( ch != -1 ) { // something to do with eof
       
   458 	if ( ioIndex )
       
   459 	    ioIndex--;
       
   460 	else
       
   461 	    ch = -1;
       
   462     }
       
   463     return ch;
       
   464 }
       
   465 
       
   466 
       
   467 /*!
       
   468   Constructs a text stream that operates on a Unicode QString through an
       
   469   internal device.
       
   470 
       
   471   If you set an encoding or codec with setEncoding() or setCodec(), this
       
   472   setting is ignored for text streams that operate on QString.
       
   473 
       
   474   Example:
       
   475   \code
       
   476     QString str;
       
   477     QTextStream ts( &str, IO_WriteOnly );
       
   478     ts << "pi = " << 3.14;			// str == "pi = 3.14"
       
   479   \endcode
       
   480 
       
   481   Writing data to the text stream will modify the contents of the string.
       
   482   The string will be expanded when data is written beyond the end of the
       
   483   string. Note that the string will not be truncated:
       
   484   \code
       
   485     QString str = "pi = 3.14";
       
   486     QTextStream ts( &str, IO_WriteOnly );
       
   487     ts <<  "2+2 = " << 2+2; 		// str == "2+2 = 414"
       
   488   \endcode
       
   489 
       
   490   Note that since QString is Unicode, you should not use readRawBytes()
       
   491   or writeRawBytes() on such a stream.
       
   492 */
       
   493 
       
   494 QTextStream::QTextStream( QString* str, int filemode )
       
   495 {
       
   496     // TODO: optimize for this case as it becomes more common
       
   497     //        (see QStringBuffer above)
       
   498     init();
       
   499     dev = new QStringBuffer( str );
       
   500     ((QStringBuffer *)dev)->open( filemode );
       
   501     owndev = TRUE;
       
   502     setEncoding(RawUnicode);
       
   503     reset();
       
   504     d->sourceType = QTextStreamPrivate::String;
       
   505 }
       
   506 
       
   507 /*! \obsolete
       
   508 
       
   509   This constructor is equivalent to the constructor taking a QString*
       
   510   parameter.
       
   511 */
       
   512 
       
   513 QTextStream::QTextStream( QString& str, int filemode )
       
   514 {
       
   515     init();
       
   516     dev = new QStringBuffer( &str );
       
   517     ((QStringBuffer *)dev)->open( filemode );
       
   518     owndev = TRUE;
       
   519     setEncoding(RawUnicode);
       
   520     reset();
       
   521     d->sourceType = QTextStreamPrivate::String;
       
   522 }
       
   523 
       
   524 /*!
       
   525   Constructs a text stream that operates on a byte array through an
       
   526   internal QBuffer device.
       
   527 
       
   528   Example:
       
   529   \code
       
   530     QByteArray array;
       
   531     QTextStream ts( array, IO_WriteOnly );
       
   532     ts << "pi = " << 3.14 << '\0';		// array == "pi = 3.14"
       
   533   \endcode
       
   534 
       
   535   Writing data to the text stream will modify the contents of the array.
       
   536   The array will be expanded when data is written beyond the end of the
       
   537   string.
       
   538 
       
   539   Same example, using a QBuffer:
       
   540   \code
       
   541     QByteArray array;
       
   542     QBuffer buf( array );
       
   543     buf.open( IO_WriteOnly );
       
   544     QTextStream ts( &buf );
       
   545     ts << "pi = " << 3.14 << '\0';		// array == "pi = 3.14"
       
   546     buf.close();
       
   547   \endcode
       
   548 */
       
   549 
       
   550 QTextStream::QTextStream( QByteArray a, int mode )
       
   551 {
       
   552     init();
       
   553     dev = new QBuffer( a );
       
   554     ((QBuffer *)dev)->open( mode );
       
   555     owndev = TRUE;
       
   556     setEncoding( Latin1 ); //### Locale???
       
   557     reset();
       
   558     d->sourceType = QTextStreamPrivate::ByteArray;
       
   559 }
       
   560 
       
   561 /*!
       
   562   Constructs a text stream that operates on an existing file handle \e fh
       
   563   through an internal QFile device.
       
   564 
       
   565   Example:
       
   566   \code
       
   567     QTextStream cout( stdout, IO_WriteOnly );
       
   568     QTextStream cin ( stdin,  IO_ReadOnly );
       
   569     QTextStream cerr( stderr, IO_WriteOnly );
       
   570  \endcode
       
   571 */
       
   572 
       
   573 QTextStream::QTextStream( FILE *fh, int mode )
       
   574 {
       
   575     init();
       
   576     setEncoding( Locale ); //###
       
   577     dev = new QFile;
       
   578     ((QFile *)dev)->open( mode, fh );
       
   579     fstrm = owndev = TRUE;
       
   580     reset();
       
   581     d->sourceType = QTextStreamPrivate::File;
       
   582 }
       
   583 
       
   584 /*!
       
   585   Destructs the text stream.
       
   586 
       
   587   The destructor does not affect the current IO device.
       
   588 */
       
   589 
       
   590 QTextStream::~QTextStream()
       
   591 {
       
   592     if ( owndev )
       
   593 	delete dev;
       
   594     delete d;
       
   595 }
       
   596 
       
   597 /*!
       
   598   Positions the read pointer at the first non-whitespace character.
       
   599 */
       
   600 void QTextStream::skipWhiteSpace()
       
   601 {
       
   602     ts_ungetc( eat_ws() );
       
   603 }
       
   604 
       
   605 
       
   606 /*!
       
   607   \fn Encoding QTextStream::encoding() const
       
   608 
       
   609   Returns the encoding mode of the stream.
       
   610 
       
   611   \sa setEncoding()
       
   612 */
       
   613 
       
   614 /*!
       
   615   Tries to read len characters from the stream and stores them in \a buf.
       
   616   Returns the number of characters really read.
       
   617   Attention: There will no QEOF appended if the read reaches the end of
       
   618   the file. EOF is reached when the return value does not equal \a len.
       
   619 */
       
   620 uint QTextStream::ts_getbuf( QChar* buf, uint len )
       
   621 {
       
   622     if( len<1 )
       
   623 	return 0;
       
   624 
       
   625     uint rnum=0;   // the number of QChars really read
       
   626 
       
   627     if ( d && d->ungetcBuf.length() ) {
       
   628 	while( rnum < len && rnum < d->ungetcBuf.length() ) {
       
   629 	    buf[rnum] = d->ungetcBuf.constref(rnum);
       
   630 	    rnum++;
       
   631 	}
       
   632 	d->ungetcBuf = d->ungetcBuf.mid( rnum );
       
   633 	if ( rnum >= len )
       
   634 	    return rnum;
       
   635     }
       
   636 
       
   637     // we use dev->ungetch() for one of the bytes of the unicode
       
   638     // byte-order mark, but a local unget hack for the other byte:
       
   639     int ungetHack = EOF;
       
   640 
       
   641     if ( doUnicodeHeader ) {
       
   642 	doUnicodeHeader = FALSE; //only at the top
       
   643 	int c1 = dev->getch();
       
   644 	if ( c1 == EOF )
       
   645 	    return rnum;
       
   646 	int c2 = dev->getch();
       
   647 	if ( c1 == 0xfe && c2 == 0xff ) {
       
   648 	    mapper = 0;
       
   649 	    latin1 = FALSE;
       
   650 	    internalOrder = QChar::networkOrdered();   //network order
       
   651 	} else if ( c1 == 0xff && c2 == 0xfe ) {
       
   652 	    mapper = 0;
       
   653 	    latin1 = FALSE;
       
   654 	    internalOrder = !QChar::networkOrdered();   //reverse network order
       
   655 	} else {
       
   656 	    if ( c2 != EOF ) {
       
   657 	 	dev->ungetch( c2 );
       
   658 		ungetHack = c1;
       
   659 	    } else {
       
   660 	 	dev->ungetch( c1 );
       
   661 		// note that a small possible bug might hide here
       
   662 		// here, if only the first byte of a file has made it
       
   663 		// so far, and that first byte is half of the
       
   664 		// byte-order mark, then the utfness will not be
       
   665 		// detected.  whether or not this is a bug depends on
       
   666 		// taste.  I can't really decide.
       
   667 	    }
       
   668 	}
       
   669     }
       
   670 
       
   671 #ifndef QT_NO_TEXTCODEC
       
   672     if ( mapper ) {
       
   673 	bool shortRead = FALSE;
       
   674 	if ( !d->decoder )
       
   675 	    d->decoder = mapper->makeDecoder();
       
   676 	while( rnum < len ) {
       
   677 	    QString s;
       
   678 	    bool readBlock = !( len == 1+rnum );
       
   679 	    while ( TRUE ) {
       
   680 		// for efficiency: normally read a whole block
       
   681 		if ( readBlock ) {
       
   682 		    // guess buffersize; this may be wrong (too small or too
       
   683 		    // big). But we can handle this (either iterate reading
       
   684 		    // or use ungetcBuf).
       
   685 		    // Note that this might cause problems for codecs where
       
   686 		    // one byte can result in >1 Unicode Characters if bytes
       
   687 		    // are written to the stream in the meantime (loss of
       
   688 		    // synchronicity).
       
   689 		    uint rlen = len - rnum;
       
   690 		    char *cbuf = new char[ rlen ];
       
   691 		    if ( ungetHack != EOF ) {
       
   692 			rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
       
   693 			cbuf[0] = (char)ungetHack;
       
   694 			ungetHack = EOF;
       
   695 		    } else {
       
   696 			rlen = dev->readBlock( cbuf, rlen );
       
   697 		    }
       
   698 		    s  += d->decoder->toUnicode( cbuf, rlen );
       
   699 		    delete[] cbuf;
       
   700 		    // use buffered reading only for the first time, because we
       
   701 		    // have to get the stream synchronous again (this is easier
       
   702 		    // with single character reading)
       
   703 		    readBlock = FALSE;
       
   704 		}
       
   705 		// get stream (and codec) in sync
       
   706 		int c;
       
   707 		if ( ungetHack == EOF ) {
       
   708 		    c = dev->getch();
       
   709 		} else {
       
   710 		    c = ungetHack;
       
   711 		    ungetHack = EOF;
       
   712 		}
       
   713 		if ( c == EOF ) {
       
   714 		    shortRead = TRUE;
       
   715 		    break;
       
   716 		}
       
   717 		char b = c;
       
   718 		uint lengthBefore = s.length();
       
   719 		s  += d->decoder->toUnicode( &b, 1 );
       
   720 		if ( s.length() > lengthBefore )
       
   721 		    break; // it seems we are in sync now
       
   722 	    }
       
   723 	    uint i = 0;
       
   724 	    while( rnum < len && i < s.length() )
       
   725 		buf[rnum++] = s.constref(i++);
       
   726 	    if ( s.length() > i )
       
   727 		// could be = but append is clearer
       
   728 		d->ungetcBuf.append( s.mid( i ) );
       
   729 	    if ( shortRead )
       
   730 		return rnum;
       
   731 	}
       
   732     } else
       
   733 #endif
       
   734     if ( latin1 ) {
       
   735 	if ( len == 1+rnum ) {
       
   736 	    // use this method for one character because it is more efficient
       
   737 	    // (arnt doubts whether it makes a difference, but lets it stand)
       
   738 	    int c = (ungetHack == EOF) ? dev->getch() : ungetHack;
       
   739 	    if ( c != EOF )
       
   740 		buf[rnum++] = (char)c;
       
   741 	} else {
       
   742 	    if ( ungetHack != EOF ) {
       
   743 		buf[rnum++] = (char)ungetHack;
       
   744 		ungetHack = EOF;
       
   745 	    }
       
   746 	    char *cbuf = new char[len - rnum];
       
   747 	    while ( !dev->atEnd() && rnum < len ) {
       
   748 		uint rlen = len - rnum;
       
   749 		rlen = dev->readBlock( cbuf, rlen );
       
   750 		uint i = 0;
       
   751 		while( i < rlen )
       
   752 		    buf[rnum++] = cbuf[i++];
       
   753 	    }
       
   754 	    delete[] cbuf;
       
   755 	}
       
   756     } else { // UCS-2 or UTF-16
       
   757 	if ( len == 1+rnum ) {
       
   758 	    int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;
       
   759 	    if ( c1 == EOF )
       
   760 		return rnum;
       
   761 	    int c2 = dev->getch();
       
   762 	    if ( c2 == EOF )
       
   763 		return rnum;
       
   764 	    if ( isNetworkOrder() )
       
   765 		buf[rnum++] = QChar( c2, c1 );
       
   766 	    else
       
   767 		buf[rnum++] = QChar( c1, c2 );
       
   768 	} else {
       
   769 	    char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
       
   770 	    while ( !dev->atEnd() && rnum < len ) {
       
   771 		uint rlen = 2 * ( len-rnum );
       
   772 		if ( ungetHack != EOF ) {
       
   773 		    rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
       
   774 		    cbuf[0] = (char)ungetHack;
       
   775 		    ungetHack = EOF;
       
   776 		} else {
       
   777 		    rlen = dev->readBlock( cbuf, rlen );
       
   778 		}
       
   779 		// We can't use an odd number of bytes, so put it back. But
       
   780 		// do it only if we are capable of reading more -- normally
       
   781 		// there should not be an odd number, but the file might be
       
   782 		// truncated or not in UTF-16...
       
   783 		if ( (rlen & 1) == 1 )
       
   784 		    if ( !dev->atEnd() )
       
   785 			dev->ungetch( cbuf[--rlen] );
       
   786 		uint i = 0;
       
   787 		if ( isNetworkOrder() ) {
       
   788 		    while( i < rlen ) {
       
   789 			buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );
       
   790 			i+=2;
       
   791 		    }
       
   792 		} else {
       
   793 		    while( i < rlen ) {
       
   794 			buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
       
   795 			i+=2;
       
   796 		    }
       
   797 		}
       
   798 	    }
       
   799 	    delete[] cbuf;
       
   800 	}
       
   801     }
       
   802     return rnum;
       
   803 }
       
   804 
       
   805 
       
   806 /*!
       
   807   Puts one character to the stream.
       
   808 */
       
   809 void QTextStream::ts_putc( QChar c )
       
   810 {
       
   811 #ifndef QT_NO_TEXTCODEC
       
   812     if ( mapper ) {
       
   813 	int len = 1;
       
   814 	QString s = c;
       
   815 	QCString block = mapper->fromUnicode( s, len );
       
   816 	dev->writeBlock( block, len );
       
   817     } else
       
   818 #endif
       
   819     if ( latin1 ) {
       
   820 	if( c.row() )
       
   821 	    dev->putch( '?' ); //######unknown character???
       
   822 	else
       
   823 	    dev->putch( c.cell() );
       
   824     } else {
       
   825 	if ( doUnicodeHeader ) {
       
   826 	    doUnicodeHeader = FALSE;
       
   827 	    ts_putc( QChar::byteOrderMark );
       
   828 	}
       
   829 	if ( internalOrder ) {
       
   830 	    dev->writeBlock( (char*)&c, sizeof(QChar) );
       
   831 	} else if ( isNetworkOrder() ) {
       
   832 	    dev->putch(c.row());
       
   833 	    dev->putch(c.cell());
       
   834 	} else {
       
   835 	    dev->putch(c.cell());
       
   836 	    dev->putch(c.row());
       
   837 	}
       
   838     }
       
   839 }
       
   840 
       
   841 /*!
       
   842   Puts one character to the stream.
       
   843 */
       
   844 void QTextStream::ts_putc(int ch)
       
   845 {
       
   846     ts_putc(QChar((ushort)ch));
       
   847 }
       
   848 
       
   849 bool QTextStream::ts_isdigit(QChar c)
       
   850 {
       
   851     return c.isDigit();
       
   852 }
       
   853 
       
   854 bool QTextStream::ts_isspace( QChar c )
       
   855 {
       
   856     return c.isSpace();
       
   857 }
       
   858 
       
   859 void QTextStream::ts_ungetc( QChar c )
       
   860 {
       
   861     if ( c.unicode() == 0xffff )
       
   862 	return;
       
   863 
       
   864     d->ungetcBuf.prepend( c );
       
   865 }
       
   866 
       
   867 
       
   868 
       
   869 /*!
       
   870   Reads \e len bytes from the stream into \e e s and returns a reference to
       
   871   the stream.
       
   872 
       
   873   The buffer \e s must be preallocated.
       
   874 
       
   875   Note that no encoding is done by this function.
       
   876 
       
   877   \warning The behaviour of this function is undefined unless the
       
   878   stream's encoding is set to Unicode or Latin1.
       
   879 
       
   880   \sa QIODevice::readBlock()
       
   881 */
       
   882 
       
   883 QTextStream &QTextStream::readRawBytes( char *s, uint len )
       
   884 {
       
   885     dev->readBlock( s, len );
       
   886     return *this;
       
   887 }
       
   888 
       
   889 /*!
       
   890   Writes the \e len bytes from \e s to the stream and returns a reference to
       
   891   the stream.
       
   892 
       
   893   Note that no encoding is done by this function.
       
   894 
       
   895   \sa QIODevice::writeBlock()
       
   896 */
       
   897 
       
   898 QTextStream &QTextStream::writeRawBytes( const char* s, uint len )
       
   899 {
       
   900     dev->writeBlock( s, len );
       
   901     return *this;
       
   902 }
       
   903 
       
   904 
       
   905 QTextStream &QTextStream::writeBlock( const char* p, uint len )
       
   906 {
       
   907     if ( doUnicodeHeader ) {
       
   908 	doUnicodeHeader = FALSE;
       
   909 	if ( !mapper && !latin1 )
       
   910 	    ts_putc( QChar::byteOrderMark );
       
   911     }
       
   912     //All QCStrings and const char* are defined to be in Latin1
       
   913     if ( !mapper && latin1 ) {
       
   914 	dev->writeBlock( p, len );
       
   915     } else if ( !mapper && internalOrder ) {
       
   916 	QChar *u = new QChar[len];
       
   917 	for (uint i=0; i<len; i++)
       
   918 	    u[i] = p[i];
       
   919 	dev->writeBlock( (char*)u, len*sizeof(QChar) );
       
   920 	delete [] u;
       
   921     } else {
       
   922 	for (uint i=0; i<len; i++)
       
   923 	    ts_putc( (uchar)p[i] );
       
   924     }
       
   925     return *this;
       
   926 }
       
   927 
       
   928 QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
       
   929 {
       
   930     if ( !mapper && !latin1 && internalOrder ) {
       
   931 	if ( doUnicodeHeader ) {
       
   932 	    doUnicodeHeader = FALSE;
       
   933 	    ts_putc( QChar::byteOrderMark );
       
   934 	}
       
   935 	dev->writeBlock( (char*)p, sizeof(QChar)*len );
       
   936     } else {
       
   937 	for (uint i=0; i<len; i++)
       
   938 	    ts_putc( p[i] );
       
   939     }
       
   940     return *this;
       
   941 }
       
   942 
       
   943 
       
   944 
       
   945 /*!
       
   946   Resets the text stream.
       
   947 
       
   948   <ul>
       
   949   <li> All flags are set to 0.
       
   950   <li> The field width is set to 0.
       
   951   <li> The fill character is set to ' ' (space).
       
   952   <li> The precision is set to 6.
       
   953   </ul>
       
   954 
       
   955   \sa setf(), width(), fill(), precision()
       
   956 */
       
   957 
       
   958 void QTextStream::reset()
       
   959 {
       
   960     fflags = 0;
       
   961     fwidth = 0;
       
   962     fillchar = ' ';
       
   963     fprec = 6;
       
   964 }
       
   965 
       
   966 
       
   967 /*!
       
   968   \fn QIODevice *QTextStream::device() const
       
   969   Returns the IO device currently set.
       
   970   \sa setDevice(), unsetDevice()
       
   971 */
       
   972 
       
   973 /*!
       
   974   Sets the IO device to \a iod.
       
   975   \sa device(), unsetDevice()
       
   976 */
       
   977 
       
   978 void QTextStream::setDevice( QIODevice *iod )
       
   979 {
       
   980     if ( owndev ) {
       
   981 	delete dev;
       
   982 	owndev = FALSE;
       
   983     }
       
   984     dev = iod;
       
   985     d->sourceType = QTextStreamPrivate::IODevice;
       
   986 }
       
   987 
       
   988 /*!
       
   989   Unsets the IO device.	 Equivalent to setDevice( 0 ).
       
   990   \sa device(), setDevice()
       
   991 */
       
   992 
       
   993 void QTextStream::unsetDevice()
       
   994 {
       
   995     setDevice( 0 );
       
   996     d->sourceType = QTextStreamPrivate::NotSet;
       
   997 }
       
   998 
       
   999 /*!
       
  1000   \fn bool QTextStream::atEnd() const
       
  1001   Returns TRUE if the IO device has reached the end position (end of
       
  1002   stream or file) or if there is no IO device set.
       
  1003 
       
  1004   Returns FALSE if the current position of the read/write head of the IO
       
  1005   device is somewhere before the end position.
       
  1006 
       
  1007   \sa QIODevice::atEnd()
       
  1008 */
       
  1009 
       
  1010 /*!\fn bool QTextStream::eof() const
       
  1011 
       
  1012   \obsolete
       
  1013 
       
  1014   This function has been renamed to atEnd().
       
  1015 
       
  1016   \sa QIODevice::atEnd()
       
  1017 */
       
  1018 
       
  1019 /*****************************************************************************
       
  1020   QTextStream read functions
       
  1021  *****************************************************************************/
       
  1022 
       
  1023 
       
  1024 /*!
       
  1025   Reads a \c char from the stream and returns a reference to the stream.
       
  1026   Note that whitespace is skipped.
       
  1027 */
       
  1028 
       
  1029 QTextStream &QTextStream::operator>>( char &c )
       
  1030 {
       
  1031     CHECK_STREAM_PRECOND
       
  1032     c = eat_ws();
       
  1033     return *this;
       
  1034 }
       
  1035 
       
  1036 /*!
       
  1037   Reads a \c char from the stream and returns a reference to the stream.
       
  1038   Note that whitespace is \e not skipped.
       
  1039 */
       
  1040 
       
  1041 QTextStream &QTextStream::operator>>( QChar &c )
       
  1042 {
       
  1043     CHECK_STREAM_PRECOND
       
  1044     c = ts_getc();
       
  1045     return *this;
       
  1046 }
       
  1047 
       
  1048 
       
  1049 ulong QTextStream::input_bin()
       
  1050 {
       
  1051     ulong val = 0;
       
  1052     QChar ch = eat_ws();
       
  1053     int dv = ch.digitValue();
       
  1054     while (  dv == 0 || dv == 1 ) {
       
  1055 	val = ( val << 1 ) + dv;
       
  1056 	ch = ts_getc();
       
  1057 	dv = ch.digitValue();
       
  1058     }
       
  1059     if ( ch != QEOF )
       
  1060 	ts_ungetc( ch );
       
  1061     return val;
       
  1062 }
       
  1063 
       
  1064 ulong QTextStream::input_oct()
       
  1065 {
       
  1066     ulong val = 0;
       
  1067     QChar ch = eat_ws();
       
  1068     int dv = ch.digitValue();
       
  1069     while ( dv >= 0 && dv <= 7 ) {
       
  1070 	val = ( val << 3 ) + dv;
       
  1071 	ch = ts_getc();
       
  1072 	dv = ch.digitValue();
       
  1073     }
       
  1074     if ( dv == 8 || dv == 9 ) {
       
  1075 	while ( ts_isdigit(ch) )
       
  1076 	    ch = ts_getc();
       
  1077     }
       
  1078     if ( ch != QEOF )
       
  1079 	ts_ungetc( ch );
       
  1080     return val;
       
  1081 }
       
  1082 
       
  1083 ulong QTextStream::input_dec()
       
  1084 {
       
  1085     ulong val = 0;
       
  1086     QChar ch = eat_ws();
       
  1087     int dv = ch.digitValue();
       
  1088     while ( ts_isdigit(ch) ) {
       
  1089 	val = val * 10 + dv;
       
  1090 	ch = ts_getc();
       
  1091 	dv = ch.digitValue();
       
  1092     }
       
  1093     if ( ch != QEOF )
       
  1094 	ts_ungetc( ch );
       
  1095     return val;
       
  1096 }
       
  1097 
       
  1098 ulong QTextStream::input_hex()
       
  1099 {
       
  1100     ulong val = 0;
       
  1101     QChar ch = eat_ws();
       
  1102     char c = ch;
       
  1103     while ( isxdigit(c) ) {
       
  1104 	val <<= 4;
       
  1105 	if ( ts_isdigit(c) )
       
  1106 	    val += c - '0';
       
  1107 	else
       
  1108 	    val += 10 + tolower(c) - 'a';
       
  1109 	c = ch = ts_getc();
       
  1110     }
       
  1111     if ( ch != QEOF )
       
  1112 	ts_ungetc( ch );
       
  1113     return val;
       
  1114 }
       
  1115 
       
  1116 long QTextStream::input_int()
       
  1117 {
       
  1118     long val;
       
  1119     QChar ch;
       
  1120     char c;
       
  1121     switch ( flags() & basefield ) {
       
  1122     case bin:
       
  1123 	val = (long)input_bin();
       
  1124 	break;
       
  1125     case oct:
       
  1126 	val = (long)input_oct();
       
  1127 	break;
       
  1128     case dec:
       
  1129 	c = ch = eat_ws();
       
  1130 	if ( ch == QEOF ) {
       
  1131 	    val = 0;
       
  1132 	} else {
       
  1133 	    if ( !(c == '-' || c == '+') )
       
  1134 		ts_ungetc( ch );
       
  1135 	    if ( c == '-' ) {
       
  1136 		ulong v = input_dec();
       
  1137 		if ( v ) {		// ensure that LONG_MIN can be read
       
  1138 		    v--;
       
  1139 		    val = -((long)v) - 1;
       
  1140 		} else {
       
  1141 		    val = 0;
       
  1142 		}
       
  1143 	    } else {
       
  1144 		val = (long)input_dec();
       
  1145 	    }
       
  1146 	}
       
  1147 	break;
       
  1148     case hex:
       
  1149 	val = (long)input_hex();
       
  1150 	break;
       
  1151     default:
       
  1152 	val = 0;
       
  1153 	c = ch = eat_ws();
       
  1154 	if ( c == '0' ) {		// bin, oct or hex
       
  1155 	    c = ch = ts_getc();
       
  1156 	    if ( tolower(c) == 'x' )
       
  1157 		val = (long)input_hex();
       
  1158 	    else if ( tolower(c) == 'b' )
       
  1159 		val = (long)input_bin();
       
  1160 	    else {			// octal
       
  1161 		ts_ungetc( ch );
       
  1162 		if ( c >= '0' && c <= '7' ) {
       
  1163 		    val = (long)input_oct();
       
  1164 		} else {
       
  1165 		    val = 0;
       
  1166 		}
       
  1167 	    }
       
  1168 	} else if ( ts_isdigit(ch) ) {
       
  1169 	    ts_ungetc( ch );
       
  1170 	    val = (long)input_dec();
       
  1171 	} else if ( c == '-' || c == '+' ) {
       
  1172 	    ulong v = input_dec();
       
  1173 	    if ( c == '-' ) {
       
  1174 		if ( v ) {		// ensure that LONG_MIN can be read
       
  1175 		    v--;
       
  1176 		    val = -((long)v) - 1;
       
  1177 		} else {
       
  1178 		    val = 0;
       
  1179 		}
       
  1180 	    } else {
       
  1181 		val = (long)v;
       
  1182 	    }
       
  1183 	}
       
  1184     }
       
  1185     return val;
       
  1186 }
       
  1187 
       
  1188 //
       
  1189 // We use a table-driven FSM to parse floating point numbers
       
  1190 // strtod() cannot be used directly since we're reading from a QIODevice
       
  1191 //
       
  1192 
       
  1193 double QTextStream::input_double()
       
  1194 {
       
  1195     const int Init	 = 0;			// states
       
  1196     const int Sign	 = 1;
       
  1197     const int Mantissa	 = 2;
       
  1198     const int Dot	 = 3;
       
  1199     const int Abscissa	 = 4;
       
  1200     const int ExpMark	 = 5;
       
  1201     const int ExpSign	 = 6;
       
  1202     const int Exponent	 = 7;
       
  1203     const int Done	 = 8;
       
  1204 
       
  1205     const int InputSign	 = 1;			// input tokens
       
  1206     const int InputDigit = 2;
       
  1207     const int InputDot	 = 3;
       
  1208     const int InputExp	 = 4;
       
  1209 
       
  1210     static uchar table[8][5] = {
       
  1211      /* None	 InputSign   InputDigit InputDot InputExp */
       
  1212 	{ 0,	    Sign,     Mantissa,	 Dot,	   0,	   }, // Init
       
  1213 	{ 0,	    0,	      Mantissa,	 Dot,	   0,	   }, // Sign
       
  1214 	{ Done,	    Done,     Mantissa,	 Dot,	   ExpMark,}, // Mantissa
       
  1215 	{ 0,	    0,	      Abscissa,	 0,	   0,	   }, // Dot
       
  1216 	{ Done,	    Done,     Abscissa,	 Done,	   ExpMark,}, // Abscissa
       
  1217 	{ 0,	    ExpSign,  Exponent,	 0,	   0,	   }, // ExpMark
       
  1218 	{ 0,	    0,	      Exponent,	 0,	   0,	   }, // ExpSign
       
  1219 	{ Done,	    Done,     Exponent,	 Done,	   Done	   }  // Exponent
       
  1220     };
       
  1221 
       
  1222     int state = Init;				// parse state
       
  1223     int input;					// input token
       
  1224 
       
  1225     char buf[256];
       
  1226     int i = 0;
       
  1227     QChar c = eat_ws();
       
  1228 
       
  1229     while ( TRUE ) {
       
  1230 
       
  1231 	switch ( c ) {
       
  1232 	    case '+':
       
  1233 	    case '-':
       
  1234 		input = InputSign;
       
  1235 		break;
       
  1236 	    case '0': case '1': case '2': case '3': case '4':
       
  1237 	    case '5': case '6': case '7': case '8': case '9':
       
  1238 		input = InputDigit;
       
  1239 		break;
       
  1240 	    case '.':
       
  1241 		input = InputDot;
       
  1242 		break;
       
  1243 	    case 'e':
       
  1244 	    case 'E':
       
  1245 		input = InputExp;
       
  1246 		break;
       
  1247 	    default:
       
  1248 		input = 0;
       
  1249 		break;
       
  1250 	}
       
  1251 
       
  1252 	state = table[state][input];
       
  1253 
       
  1254 	if  ( state == 0 || state == Done || i > 250 ) {
       
  1255 	    if ( i > 250 ) {			// ignore rest of digits
       
  1256 		do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );
       
  1257 	    }
       
  1258 	    if ( c != QEOF )
       
  1259 		ts_ungetc( c );
       
  1260 	    buf[i] = '\0';
       
  1261 	    char *end;
       
  1262 	    return strtod( buf, &end );
       
  1263 	}
       
  1264 
       
  1265 	buf[i++] = c;
       
  1266 	c = ts_getc();
       
  1267     }
       
  1268 
       
  1269 #if !defined(_CC_EGG_)
       
  1270     return 0.0;
       
  1271 #endif
       
  1272 }
       
  1273 
       
  1274 
       
  1275 /*!
       
  1276   Reads a signed \c short integer from the stream and returns a reference to
       
  1277   the stream. See flags() for an explanation of expected input format.
       
  1278 */
       
  1279 
       
  1280 QTextStream &QTextStream::operator>>( signed short &i )
       
  1281 {
       
  1282     CHECK_STREAM_PRECOND
       
  1283     i = (signed short)input_int();
       
  1284     return *this;
       
  1285 }
       
  1286 
       
  1287 
       
  1288 /*!
       
  1289   Reads an unsigned \c short integer from the stream and returns a reference to
       
  1290   the stream. See flags() for an explanation of expected input format.
       
  1291 */
       
  1292 
       
  1293 QTextStream &QTextStream::operator>>( unsigned short &i )
       
  1294 {
       
  1295     CHECK_STREAM_PRECOND
       
  1296     i = (unsigned short)input_int();
       
  1297     return *this;
       
  1298 }
       
  1299 
       
  1300 
       
  1301 /*!
       
  1302   Reads a signed \c int from the stream and returns a reference to the
       
  1303   stream. See flags() for an explanation of expected input format.
       
  1304 */
       
  1305 
       
  1306 QTextStream &QTextStream::operator>>( signed int &i )
       
  1307 {
       
  1308     CHECK_STREAM_PRECOND
       
  1309     i = (signed int)input_int();
       
  1310     return *this;
       
  1311 }
       
  1312 
       
  1313 
       
  1314 /*!
       
  1315   Reads an unsigned \c int from the stream and returns a reference to the
       
  1316   stream. See flags() for an explanation of expected input format.
       
  1317 */
       
  1318 
       
  1319 QTextStream &QTextStream::operator>>( unsigned int &i )
       
  1320 {
       
  1321     CHECK_STREAM_PRECOND
       
  1322     i = (unsigned int)input_int();
       
  1323     return *this;
       
  1324 }
       
  1325 
       
  1326 
       
  1327 /*!
       
  1328   Reads a signed \c long int from the stream and returns a reference to the
       
  1329   stream. See flags() for an explanation of expected input format.
       
  1330 */
       
  1331 
       
  1332 QTextStream &QTextStream::operator>>( signed long &i )
       
  1333 {
       
  1334     CHECK_STREAM_PRECOND
       
  1335     i = (signed long)input_int();
       
  1336     return *this;
       
  1337 }
       
  1338 
       
  1339 
       
  1340 /*!
       
  1341   Reads an unsigned \c long int from the stream and returns a reference to the
       
  1342   stream. See flags() for an explanation of expected input format.
       
  1343 */
       
  1344 
       
  1345 QTextStream &QTextStream::operator>>( unsigned long &i )
       
  1346 {
       
  1347     CHECK_STREAM_PRECOND
       
  1348     i = (unsigned long)input_int();
       
  1349     return *this;
       
  1350 }
       
  1351 
       
  1352 
       
  1353 /*!
       
  1354   Reads a \c float from the stream and returns a reference to the stream.
       
  1355   See flags() for an explanation of expected input format.
       
  1356 */
       
  1357 
       
  1358 QTextStream &QTextStream::operator>>( float &f )
       
  1359 {
       
  1360     CHECK_STREAM_PRECOND
       
  1361     f = (float)input_double();
       
  1362     return *this;
       
  1363 }
       
  1364 
       
  1365 
       
  1366 /*!
       
  1367   Reads a \c double from the stream and returns a reference to the stream.
       
  1368   See flags() for an explanation of expected input format.
       
  1369 */
       
  1370 
       
  1371 QTextStream &QTextStream::operator>>( double &f )
       
  1372 {
       
  1373     CHECK_STREAM_PRECOND
       
  1374     f = input_double();
       
  1375     return *this;
       
  1376 }
       
  1377 
       
  1378 
       
  1379 /*!
       
  1380   Reads a word from the stream and returns a reference to the stream.
       
  1381 */
       
  1382 
       
  1383 QTextStream &QTextStream::operator>>( char *s )
       
  1384 {
       
  1385     CHECK_STREAM_PRECOND
       
  1386     int maxlen = width( 0 );
       
  1387     QChar c = eat_ws();
       
  1388     if ( !maxlen )
       
  1389 	maxlen = -1;
       
  1390     while ( c != QEOF ) {
       
  1391 	if ( ts_isspace(c) || maxlen-- == 0 ) {
       
  1392 	    ts_ungetc( c );
       
  1393 	    break;
       
  1394 	}
       
  1395 	*s++ = c;
       
  1396 	c = ts_getc();
       
  1397     }
       
  1398 
       
  1399     *s = '\0';
       
  1400     return *this;
       
  1401 }
       
  1402 
       
  1403 /*!
       
  1404   Reads a word from the stream and returns a reference to the stream.
       
  1405 */
       
  1406 
       
  1407 QTextStream &QTextStream::operator>>( QString &str )
       
  1408 {
       
  1409     CHECK_STREAM_PRECOND
       
  1410     str=QString::fromLatin1("");
       
  1411     QChar	c = eat_ws();
       
  1412 
       
  1413     while ( c != QEOF ) {
       
  1414 	if ( ts_isspace(c) ) {
       
  1415 	    ts_ungetc( c );
       
  1416 	    break;
       
  1417 	}
       
  1418 	str += c;
       
  1419 	c = ts_getc();
       
  1420     }
       
  1421     return *this;
       
  1422 }
       
  1423 
       
  1424 /*!
       
  1425   Reads a word from the stream and returns a reference to the stream.
       
  1426 */
       
  1427 
       
  1428 QTextStream &QTextStream::operator>>( QCString &str )
       
  1429 {
       
  1430     CHECK_STREAM_PRECOND
       
  1431     QCString  *dynbuf = 0;
       
  1432     const int buflen = 256;
       
  1433     char      buffer[buflen];
       
  1434     char     *s = buffer;
       
  1435     int	      i = 0;
       
  1436     QChar	      c = eat_ws();
       
  1437 
       
  1438     while ( c != QEOF ) {
       
  1439 	if ( ts_isspace(c) ) {
       
  1440 	    ts_ungetc( c );
       
  1441 	    break;
       
  1442 	}
       
  1443 	if ( i >= buflen-1 ) {
       
  1444 	    if ( !dynbuf )  {			// create dynamic buffer
       
  1445 		dynbuf = new QCString(buflen*2);
       
  1446 		memcpy( dynbuf->data(), s, i );	// copy old data
       
  1447 	    } else if ( i >= (int)dynbuf->size()-1 ) {
       
  1448 		dynbuf->resize( dynbuf->size()*2 );
       
  1449 	    }
       
  1450 	    s = dynbuf->data();
       
  1451 	}
       
  1452 	s[i++] = c;
       
  1453 	c = ts_getc();
       
  1454     }
       
  1455     str.resize( i+1 );
       
  1456     memcpy( str.data(), s, i );
       
  1457     delete dynbuf;
       
  1458     return *this;
       
  1459 }
       
  1460 
       
  1461 
       
  1462 /*!
       
  1463   Reads a line from the stream and returns a string containing the text.
       
  1464 
       
  1465   The returned string does not contain any trailing newline or carriage
       
  1466   return. Note that this is different from QIODevice::readLine(), which
       
  1467   does not strip the newline at the end of the line.
       
  1468 
       
  1469   On EOF you will get a QString that is null. On reading an empty line the
       
  1470   returned QString is empty but not null.
       
  1471 
       
  1472   \sa QIODevice::readLine()
       
  1473 */
       
  1474 
       
  1475 QString QTextStream::readLine()
       
  1476 {
       
  1477 #if defined(CHECK_STATE)
       
  1478     if ( !dev ) {
       
  1479 	qWarning( "QTextStream::readLine: No device" );
       
  1480 	return QString::null;
       
  1481     }
       
  1482 #endif
       
  1483     QString result( "" );
       
  1484     const int buf_size = 256;
       
  1485     QChar c[buf_size];
       
  1486     int pos = 0;
       
  1487 
       
  1488     c[pos] = ts_getc();
       
  1489     if ( c[pos] == QEOF )
       
  1490 	return QString::null;
       
  1491 
       
  1492     while ( c[pos] != QEOF && c[pos] != '\n' ) {
       
  1493 	pos++;
       
  1494 	if ( pos >= buf_size ) {
       
  1495 	    result += QString( c, pos );
       
  1496 	    pos = 0;
       
  1497 	}
       
  1498 	c[pos] = ts_getc();
       
  1499     }
       
  1500     result += QString( c, pos );
       
  1501 
       
  1502     int len = (int)result.length();
       
  1503     if ( len && result[len-1] == '\r' )
       
  1504 	result.truncate(len-1); // (if there are two \r, let one stay)
       
  1505 
       
  1506     return result;
       
  1507 }
       
  1508 
       
  1509 
       
  1510 /*!
       
  1511   Reads the entire stream and returns a string containing the text.
       
  1512 
       
  1513   \sa QIODevice::readLine()
       
  1514 */
       
  1515 
       
  1516 QString QTextStream::read()
       
  1517 {
       
  1518 #if defined(CHECK_STATE)
       
  1519     if ( !dev ) {
       
  1520 	qWarning( "QTextStream::read: No device" );
       
  1521 	return QString::null;
       
  1522     }
       
  1523 #endif
       
  1524     QString    result;
       
  1525     const uint bufsize = 512;
       
  1526     QChar      buf[bufsize];
       
  1527     uint       i, num, start;
       
  1528     bool       skipped_cr = FALSE;
       
  1529 
       
  1530     while ( 1 ) {
       
  1531 	num = ts_getbuf(buf,bufsize);
       
  1532 	// do a s/\r\n/\n
       
  1533 	start = 0;
       
  1534 	for ( i=0; i<num; i++ ) {
       
  1535 	    if ( buf[i] == '\r' ) {
       
  1536 		// Only skip single cr's preceding lf's
       
  1537 		if ( skipped_cr ) {
       
  1538 		    result += buf[i];
       
  1539 		    start++;
       
  1540 		} else {
       
  1541 		    result += QString( &buf[start], i-start );
       
  1542 		    start = i+1;
       
  1543 		    skipped_cr = TRUE;
       
  1544 		}
       
  1545 	    } else {
       
  1546 		if ( skipped_cr ) {
       
  1547 		    if ( buf[i] != '\n' ) {
       
  1548 			// Should not have skipped it
       
  1549 			result += '\r';
       
  1550 		    }
       
  1551 		    skipped_cr = FALSE;
       
  1552 		}
       
  1553 	    }
       
  1554 	}
       
  1555 	if ( start < num )
       
  1556 	    result += QString( &buf[start], i-start );
       
  1557 	if ( num != bufsize ) // if ( EOF )
       
  1558 	    break;
       
  1559     }
       
  1560     return result;
       
  1561 }
       
  1562 
       
  1563 
       
  1564 
       
  1565 /*****************************************************************************
       
  1566   QTextStream write functions
       
  1567  *****************************************************************************/
       
  1568 
       
  1569 /*!
       
  1570   Writes a \c char to the stream and returns a reference to the stream.
       
  1571 
       
  1572   The character \a c is assumed to be Latin1 encoded independent of the Encoding set
       
  1573   for the QTextStream.
       
  1574 */
       
  1575 QTextStream &QTextStream::operator<<( QChar c )
       
  1576 {
       
  1577     CHECK_STREAM_PRECOND
       
  1578     ts_putc( c );
       
  1579     return *this;
       
  1580 }
       
  1581 
       
  1582 /*!
       
  1583   Writes a \c char to the stream and returns a reference to the stream.
       
  1584 */
       
  1585 QTextStream &QTextStream::operator<<( char c )
       
  1586 {
       
  1587     CHECK_STREAM_PRECOND
       
  1588     unsigned char uc = (unsigned char) c;
       
  1589     ts_putc( uc );
       
  1590     return *this;
       
  1591 }
       
  1592 
       
  1593 QTextStream &QTextStream::output_int( int format, ulong n, bool neg )
       
  1594 {
       
  1595     static char hexdigits_lower[] = "0123456789abcdef";
       
  1596     static char hexdigits_upper[] = "0123456789ABCDEF";
       
  1597     CHECK_STREAM_PRECOND
       
  1598     char buf[76];
       
  1599     register char *p;
       
  1600     int	  len;
       
  1601     char *hexdigits;
       
  1602 
       
  1603     switch ( flags() & I_BASE_MASK ) {
       
  1604 
       
  1605 	case I_BASE_2:				// output binary number
       
  1606 	    switch ( format & I_TYPE_MASK ) {
       
  1607 		case I_SHORT: len=16; break;
       
  1608 		case I_INT:   len=sizeof(int)*8; break;
       
  1609 		case I_LONG:  len=32; break;
       
  1610 		default:      len = 0;
       
  1611 	    }
       
  1612 	    p = &buf[74];			// go reverse order
       
  1613 	    *p = '\0';
       
  1614 	    while ( len-- ) {
       
  1615 		*--p = (char)(n&1) + '0';
       
  1616 		n >>= 1;
       
  1617 		if ( !n )
       
  1618 		    break;
       
  1619 	    }
       
  1620 	    if ( flags() & showbase ) {		// show base
       
  1621 		*--p = (flags() & uppercase) ? 'B' : 'b';
       
  1622 		*--p = '0';
       
  1623 	    }
       
  1624 	    break;
       
  1625 
       
  1626 	case I_BASE_8:				// output octal number
       
  1627 	    p = &buf[74];
       
  1628 	    *p = '\0';
       
  1629 	    do {
       
  1630 		*--p = (char)(n&7) + '0';
       
  1631 		n >>= 3;
       
  1632 	    } while ( n );
       
  1633 	    if ( flags() & showbase )
       
  1634 		*--p = '0';
       
  1635 	    break;
       
  1636 
       
  1637 	case I_BASE_16:				// output hexadecimal number
       
  1638 	    p = &buf[74];
       
  1639 	    *p = '\0';
       
  1640 	    hexdigits = (flags() & uppercase) ?
       
  1641 		hexdigits_upper : hexdigits_lower;
       
  1642 	    do {
       
  1643 		*--p = hexdigits[(int)n&0xf];
       
  1644 		n >>= 4;
       
  1645 	    } while ( n );
       
  1646 	    if ( flags() & showbase ) {
       
  1647 		*--p = (flags() & uppercase) ? 'X' : 'x';
       
  1648 		*--p = '0';
       
  1649 	    }
       
  1650 	    break;
       
  1651 
       
  1652 	default:				// decimal base is default
       
  1653 	    p = &buf[74];
       
  1654 	    *p = '\0';
       
  1655 	    if ( neg )
       
  1656 		n = (ulong)(-(long)n);
       
  1657 	    do {
       
  1658 		*--p = ((int)(n%10)) + '0';
       
  1659 		n /= 10;
       
  1660 	    } while ( n );
       
  1661 	    if ( neg )
       
  1662 		*--p = '-';
       
  1663 	    else if ( flags() & showpos )
       
  1664 		*--p = '+';
       
  1665 	    if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
       
  1666 		ts_putc( *p );			// special case for internal
       
  1667 		++p;				//   padding
       
  1668 		fwidth--;
       
  1669 		return *this << (const char*)p;
       
  1670 	    }
       
  1671     }
       
  1672     if ( fwidth ) {				// adjustment required
       
  1673 	if ( !(flags() & left) ) {		// but NOT left adjustment
       
  1674 	    len = qstrlen(p);
       
  1675 	    int padlen = fwidth - len;
       
  1676 	    if ( padlen <= 0 ) {		// no padding required
       
  1677 		writeBlock( p, len );
       
  1678 	    } else if ( padlen < (int)(p-buf) ) { // speeds up padding
       
  1679 		memset( p-padlen, (char)fillchar, padlen );
       
  1680 		writeBlock( p-padlen, padlen+len );
       
  1681 	    }
       
  1682 	    else				// standard padding
       
  1683 		*this << (const char*)p;
       
  1684 	}
       
  1685 	else
       
  1686 	    *this << (const char*)p;
       
  1687 	fwidth = 0;				// reset field width
       
  1688     }
       
  1689     else
       
  1690 	writeBlock( p, qstrlen(p) );
       
  1691     return *this;
       
  1692 }
       
  1693 
       
  1694 
       
  1695 /*!
       
  1696   Writes a \c short integer to the stream and returns a reference to
       
  1697   the stream.
       
  1698 */
       
  1699 
       
  1700 QTextStream &QTextStream::operator<<( signed short i )
       
  1701 {
       
  1702     return output_int( I_SHORT | I_SIGNED, i, i < 0 );
       
  1703 }
       
  1704 
       
  1705 
       
  1706 /*!
       
  1707   Writes an \c unsigned \c short integer to the stream and returns a reference
       
  1708   to the stream.
       
  1709 */
       
  1710 
       
  1711 QTextStream &QTextStream::operator<<( unsigned short i )
       
  1712 {
       
  1713     return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
       
  1714 }
       
  1715 
       
  1716 
       
  1717 /*!
       
  1718   Writes an \c int to the stream and returns a reference to
       
  1719   the stream.
       
  1720 */
       
  1721 
       
  1722 QTextStream &QTextStream::operator<<( signed int i )
       
  1723 {
       
  1724     return output_int( I_INT | I_SIGNED, i, i < 0 );
       
  1725 }
       
  1726 
       
  1727 
       
  1728 /*!
       
  1729   Writes an \c unsigned \c int to the stream and returns a reference to
       
  1730   the stream.
       
  1731 */
       
  1732 
       
  1733 QTextStream &QTextStream::operator<<( unsigned int i )
       
  1734 {
       
  1735     return output_int( I_INT | I_UNSIGNED, i, FALSE );
       
  1736 }
       
  1737 
       
  1738 
       
  1739 /*!
       
  1740   Writes a \c long \c int to the stream and returns a reference to
       
  1741   the stream.
       
  1742 */
       
  1743 
       
  1744 QTextStream &QTextStream::operator<<( signed long i )
       
  1745 {
       
  1746     return output_int( I_LONG | I_SIGNED, i, i < 0 );
       
  1747 }
       
  1748 
       
  1749 
       
  1750 /*!
       
  1751   Writes an \c unsigned \c long \c int to the stream and returns a reference to
       
  1752   the stream.
       
  1753 */
       
  1754 
       
  1755 QTextStream &QTextStream::operator<<( unsigned long i )
       
  1756 {
       
  1757     return output_int( I_LONG | I_UNSIGNED, i, FALSE );
       
  1758 }
       
  1759 
       
  1760 
       
  1761 /*!
       
  1762   Writes a \c float to the stream and returns a reference to the stream.
       
  1763 */
       
  1764 
       
  1765 QTextStream &QTextStream::operator<<( float f )
       
  1766 {
       
  1767     return *this << (double)f;
       
  1768 }
       
  1769 
       
  1770 
       
  1771 /*!
       
  1772   Writes a \c double to the stream and returns a reference to the stream.
       
  1773 */
       
  1774 
       
  1775 QTextStream &QTextStream::operator<<( double f )
       
  1776 {
       
  1777     CHECK_STREAM_PRECOND
       
  1778     char buf[64];
       
  1779     char f_char;
       
  1780     char format[16];
       
  1781     if ( (flags()&floatfield) == fixed )
       
  1782 	f_char = 'f';
       
  1783     else if ( (flags()&floatfield) == scientific )
       
  1784 	f_char = (flags() & uppercase) ? 'E' : 'e';
       
  1785     else
       
  1786 	f_char = (flags() & uppercase) ? 'G' : 'g';
       
  1787     register char *fs = format;			// generate format string
       
  1788     *fs++ = '%';				//   "%.<prec>l<f_char>"
       
  1789     *fs++ = '.';
       
  1790     int prec = precision();
       
  1791     if ( prec > 99 )
       
  1792 	prec = 99;
       
  1793     if ( prec >= 10 ) {
       
  1794 	*fs++ = prec / 10 + '0';
       
  1795 	*fs++ = prec % 10 + '0';
       
  1796     } else {
       
  1797 	*fs++ = prec + '0';
       
  1798     }
       
  1799     *fs++ = 'l';
       
  1800     *fs++ = f_char;
       
  1801     *fs = '\0';
       
  1802     sprintf( buf, format, f );			// convert to text
       
  1803     if ( fwidth )				// padding
       
  1804 	*this << (const char*)buf;
       
  1805     else					// just write it
       
  1806 	writeBlock( buf, qstrlen(buf) );
       
  1807     return *this;
       
  1808 }
       
  1809 
       
  1810 
       
  1811 /*!
       
  1812   Writes a string to the stream and returns a reference to the stream.
       
  1813 
       
  1814   The string \a s is assumed to be Latin1 encoded independent of the Encoding set
       
  1815   for the QTextStream.
       
  1816 */
       
  1817 
       
  1818 QTextStream &QTextStream::operator<<( const char* s )
       
  1819 {
       
  1820     CHECK_STREAM_PRECOND
       
  1821     char padbuf[48];
       
  1822     uint len = qstrlen( s );			// don't write null terminator
       
  1823     if ( fwidth ) {				// field width set
       
  1824 	int padlen = fwidth - len;
       
  1825 	fwidth = 0;				// reset width
       
  1826 	if ( padlen > 0 ) {
       
  1827 	    char *ppad;
       
  1828 	    if ( padlen > 46 ) {		// create extra big fill buffer
       
  1829 		ppad = new char[padlen];
       
  1830 		CHECK_PTR( ppad );
       
  1831 	    } else {
       
  1832 		ppad = padbuf;
       
  1833 	    }
       
  1834 	    memset( ppad, (char)fillchar, padlen );	// fill with fillchar
       
  1835 	    if ( !(flags() & left) ) {
       
  1836 		writeBlock( ppad, padlen );
       
  1837 		padlen = 0;
       
  1838 	    }
       
  1839 	    writeBlock( s, len );
       
  1840 	    if ( padlen )
       
  1841 		writeBlock( ppad, padlen );
       
  1842 	    if ( ppad != padbuf )		// delete extra big fill buf
       
  1843 		delete[] ppad;
       
  1844 	    return *this;
       
  1845 	}
       
  1846     }
       
  1847     writeBlock( s, len );
       
  1848     return *this;
       
  1849 }
       
  1850 
       
  1851 /*!
       
  1852   Writes \a s to the stream and returns a reference to the stream.
       
  1853 
       
  1854   The string \a s is assumed to be Latin1 encoded independent of the Encoding set
       
  1855   for the QTextStream.
       
  1856 */
       
  1857 
       
  1858 QTextStream &QTextStream::operator<<( const QCString & s )
       
  1859 {
       
  1860     return operator<<(s.data());
       
  1861 }
       
  1862 
       
  1863 /*!
       
  1864   Writes \a s to the stream and returns a reference to the stream.
       
  1865 */
       
  1866 
       
  1867 QTextStream &QTextStream::operator<<( const QString& s )
       
  1868 {
       
  1869     CHECK_STREAM_PRECOND
       
  1870     uint len = s.length();
       
  1871     QString s1 = s;
       
  1872     if ( fwidth ) {				// field width set
       
  1873 	if ( !(flags() & left) ) {
       
  1874 	    s1 = s.rightJustify(fwidth, (char)fillchar);
       
  1875 	} else {
       
  1876 	    s1 = s.leftJustify(fwidth, (char)fillchar);
       
  1877 	}
       
  1878 	fwidth = 0;				// reset width
       
  1879     }
       
  1880     writeBlock( s1.unicode(), len );
       
  1881     return *this;
       
  1882 }
       
  1883 
       
  1884 
       
  1885 /*!
       
  1886   Writes a pointer to the stream and returns a reference to the stream.
       
  1887 
       
  1888   The \e ptr is output as an unsigned long hexadecimal integer.
       
  1889 */
       
  1890 
       
  1891 QTextStream &QTextStream::operator<<( void *ptr )
       
  1892 {
       
  1893     int f = flags();
       
  1894     setf( hex, basefield );
       
  1895     setf( showbase );
       
  1896     unsetf( uppercase );
       
  1897     output_int( I_LONG | I_UNSIGNED, (ulong)ptr, FALSE );
       
  1898     flags( f );
       
  1899     return *this;
       
  1900 }
       
  1901 
       
  1902 
       
  1903 /*!
       
  1904   \fn int QTextStream::flags() const
       
  1905   Returns the current stream flags. The default value is 0.
       
  1906 
       
  1907   The meaning of the flags are:
       
  1908   <ul>
       
  1909     <li> \e skipws - Not currently used - whitespace always skipped
       
  1910     <li> \e left - Numeric fields are left-aligned
       
  1911     <li> \e right - Not currently used (by default numerics are right aligned)
       
  1912     <li> \e internal - Put any padding spaces between +/- and value
       
  1913     <li> \e bin - Output \e and input only in binary
       
  1914     <li> \e oct - Output \e and input only in octal
       
  1915     <li> \e dec - Output \e and input only in decimal
       
  1916     <li> \e hex - Output \e and input only in hexadecimal
       
  1917     <li> \e showbase - Annotate numeric outputs with 0b, 0, or 0x if in
       
  1918 		\e bin, \e oct, or \e hex format
       
  1919     <li> \e showpoint - Not currently used
       
  1920     <li> \e uppercase - Use 0B and 0X rather than 0b and 0x
       
  1921     <li> \e showpos - Show + for positive numeric values
       
  1922     <li> \e scientific - Use scientific notation for floating point values
       
  1923     <li> \e fixed - Use fixed-point notation for floating point values
       
  1924   </ul>
       
  1925 
       
  1926   Note that unless \e bin, \e oct, \e dec, or \e hex is set, the input base is
       
  1927     octal if the value starts with 0, hexadecimal if it starts with 0x, binary
       
  1928     if the value starts with 0b, and decimal otherwise.
       
  1929 
       
  1930   \sa setf(), unsetf()
       
  1931 */
       
  1932 
       
  1933 /*!
       
  1934   \fn int QTextStream::flags( int f )
       
  1935   Sets the stream flags to \e f.
       
  1936   Returns the previous stream flags.
       
  1937 
       
  1938   \sa setf(), unsetf(), flags()
       
  1939 */
       
  1940 
       
  1941 /*!
       
  1942   \fn int QTextStream::setf( int bits )
       
  1943   Sets the stream flag bits \e bits.
       
  1944   Returns the previous stream flags.
       
  1945 
       
  1946   Equivalent to <code>flags( flags() | bits )</code>.
       
  1947 
       
  1948   \sa setf(), unsetf()
       
  1949 */
       
  1950 
       
  1951 /*!
       
  1952   \fn int QTextStream::setf( int bits, int mask )
       
  1953   Sets the stream flag bits \e bits with a bit mask \e mask.
       
  1954   Returns the previous stream flags.
       
  1955 
       
  1956   Equivalent to <code>flags( (flags() & ~mask) | (bits & mask) )</code>.
       
  1957 
       
  1958   \sa setf(), unsetf()
       
  1959 */
       
  1960 
       
  1961 /*!
       
  1962   \fn int QTextStream::unsetf( int bits )
       
  1963   Clears the stream flag bits \e bits.
       
  1964   Returns the previous stream flags.
       
  1965 
       
  1966   Equivalent to <code>flags( flags() & ~mask )</code>.
       
  1967 
       
  1968   \sa setf()
       
  1969 */
       
  1970 
       
  1971 /*!
       
  1972   \fn int QTextStream::width() const
       
  1973   Returns the field width. The default value is 0.
       
  1974 */
       
  1975 
       
  1976 /*!
       
  1977   \fn int QTextStream::width( int w )
       
  1978   Sets the field width to \e w. Returns the previous field width.
       
  1979 */
       
  1980 
       
  1981 /*!
       
  1982   \fn int QTextStream::fill() const
       
  1983   Returns the fill character. The default value is ' ' (space).
       
  1984 */
       
  1985 
       
  1986 /*!
       
  1987   \fn int QTextStream::fill( int f )
       
  1988   Sets the fill character to \e f. Returns the previous fill character.
       
  1989 */
       
  1990 
       
  1991 /*!
       
  1992   \fn int QTextStream::precision() const
       
  1993   Returns the precision. The default value is 6.
       
  1994 */
       
  1995 
       
  1996 /*!
       
  1997   \fn int QTextStream::precision( int p )
       
  1998   Sets the precision to \e p. Returns the previous precision setting.
       
  1999 */
       
  2000 
       
  2001 
       
  2002  /*****************************************************************************
       
  2003   QTextStream manipulators
       
  2004  *****************************************************************************/
       
  2005 
       
  2006 QTextStream &bin( QTextStream &s )
       
  2007 {
       
  2008     s.setf(QTS::bin,QTS::basefield);
       
  2009     return s;
       
  2010 }
       
  2011 
       
  2012 QTextStream &oct( QTextStream &s )
       
  2013 {
       
  2014     s.setf(QTS::oct,QTS::basefield);
       
  2015     return s;
       
  2016 }
       
  2017 
       
  2018 QTextStream &dec( QTextStream &s )
       
  2019 {
       
  2020     s.setf(QTS::dec,QTS::basefield);
       
  2021     return s;
       
  2022 }
       
  2023 
       
  2024 QTextStream &hex( QTextStream &s )
       
  2025 {
       
  2026     s.setf(QTS::hex,QTS::basefield);
       
  2027     return s;
       
  2028 }
       
  2029 
       
  2030 QTextStream &endl( QTextStream &s )
       
  2031 {
       
  2032     return s << '\n';
       
  2033 }
       
  2034 
       
  2035 QTextStream &flush( QTextStream &s )
       
  2036 {
       
  2037     if ( s.device() )
       
  2038 	s.device()->flush();
       
  2039     return s;
       
  2040 }
       
  2041 
       
  2042 QTextStream &ws( QTextStream &s )
       
  2043 {
       
  2044     s.skipWhiteSpace();
       
  2045     return s;
       
  2046 }
       
  2047 
       
  2048 QTextStream &reset( QTextStream &s )
       
  2049 {
       
  2050     s.reset();
       
  2051     return s;
       
  2052 }
       
  2053 
       
  2054 
       
  2055 /*!
       
  2056   \class QTextIStream qtextstream.h
       
  2057   \brief A convenience class for input streams.
       
  2058 
       
  2059   For simple tasks, code should be simple.  Hence this
       
  2060   class is a shorthand to avoid passing the \e mode argument
       
  2061   to the normal QTextStream constructors.
       
  2062 
       
  2063   This makes it easy for example, to write things like this:
       
  2064 \code
       
  2065     QString data = "123 456";
       
  2066     int a, b;
       
  2067     QTextIStream(&data) >> a >> b;
       
  2068 \endcode
       
  2069 
       
  2070   \sa QTextOStream
       
  2071 */
       
  2072 
       
  2073 /*!
       
  2074   \fn QTextIStream::QTextIStream( QString *s )
       
  2075 
       
  2076   Constructs a stream to read from string \a s.
       
  2077 */
       
  2078 /*!
       
  2079   \fn QTextIStream::QTextIStream( QByteArray ba )
       
  2080 
       
  2081   Constructs a stream to read from the array \a ba.
       
  2082 */
       
  2083 /*!
       
  2084   \fn QTextIStream::QTextIStream( FILE *f )
       
  2085 
       
  2086   Constructs a stream to read from the file \a f.
       
  2087 */
       
  2088 
       
  2089 
       
  2090 /*!
       
  2091   \class QTextOStream qtextstream.h
       
  2092   \brief A convenience class for output streams.
       
  2093 
       
  2094   For simple tasks, code should be simple.  Hence this
       
  2095   class is a shorthand to avoid passing the \e mode argument
       
  2096   to the normal QTextStream constructors.
       
  2097 
       
  2098   This makes it easy for example, to write things like this:
       
  2099 \code
       
  2100     QString result;
       
  2101     QTextOStream(&result) << "pi = " << 3.14;
       
  2102 \endcode
       
  2103 */
       
  2104 
       
  2105 /*!
       
  2106   \fn QTextOStream::QTextOStream( QString *s )
       
  2107 
       
  2108   Constructs a stream to write to string \a s.
       
  2109 */
       
  2110 /*!
       
  2111   \fn QTextOStream::QTextOStream( QByteArray ba )
       
  2112 
       
  2113   Constructs a stream to write to the array \a ba.
       
  2114 */
       
  2115 /*!
       
  2116   \fn QTextOStream::QTextOStream( FILE *f )
       
  2117 
       
  2118   Constructs a stream to write to the file \a f.
       
  2119 */
       
  2120 
       
  2121 
       
  2122 
       
  2123 /*!
       
  2124   Sets the encoding of this stream to \a e, where \a e is one of:
       
  2125   <ul>
       
  2126   <li> \c Locale Using local file format (Latin1 if locale is not
       
  2127   set), but autodetecting Unicode(utf16) on input.
       
  2128   <li> \c Unicode Using Unicode(utf16) for input and output. Output
       
  2129   will be written in the order most efficient for the current platform
       
  2130   (i.e. the order used internally in QString).
       
  2131   <li> \c UnicodeUTF8 Using Unicode(utf8) for input and output. If you use it
       
  2132   for input it will autodetect utf16 and use it instead of utf8.
       
  2133   <li> \c Latin1  ISO-8859-1. Will not autodetect utf16.
       
  2134   <li> \c UnicodeNetworkOrder Using network order Unicode(utf16) for
       
  2135   input and output. Useful when reading Unicode data that does not
       
  2136   start with the byte order marker.
       
  2137   <li> \c UnicodeReverse Using reverse network order Unicode(utf16)
       
  2138   for input and output. Useful when reading Unicode data that does not
       
  2139   start with the byte order marker, or writing data that should be
       
  2140   read by buggy Windows applications.
       
  2141   <li> \c RawUnicode Like Unicode, but does not write the byte order
       
  2142   marker, nor does it autodetect the byte order. Only useful when
       
  2143   writing to non-persistent storage used by a single process.
       
  2144   </ul>
       
  2145 
       
  2146   \c Locale and all Unicode encodings, except \c RawUnicode, will look at
       
  2147   the first two bytes in a input stream to determine the byte order. The
       
  2148   initial byte order marker will be stripped off before data is read.
       
  2149 
       
  2150   Note that this function should be called before any data is read
       
  2151   to/written from the stream.
       
  2152   \sa setCodec()
       
  2153 */
       
  2154 
       
  2155 void QTextStream::setEncoding( Encoding e )
       
  2156 {
       
  2157     if ( d->sourceType == QTextStreamPrivate::String )
       
  2158 	return; // QString does not need any encoding
       
  2159     switch ( e ) {
       
  2160     case Unicode:
       
  2161 	mapper = 0;
       
  2162 	latin1 = FALSE;
       
  2163 	doUnicodeHeader = TRUE;
       
  2164 	internalOrder = TRUE;
       
  2165 	break;
       
  2166     case UnicodeUTF8:
       
  2167 #ifndef QT_NO_CODECS
       
  2168 	mapper = QTextCodec::codecForMib( 106 );
       
  2169 	latin1 = FALSE;
       
  2170 	doUnicodeHeader = TRUE;
       
  2171 	internalOrder = TRUE;
       
  2172 #else
       
  2173 	mapper = 0;
       
  2174 	latin1 = TRUE;
       
  2175 	doUnicodeHeader = TRUE;
       
  2176 #endif
       
  2177 	break;
       
  2178     case UnicodeNetworkOrder:
       
  2179 	mapper = 0;
       
  2180 	latin1 = FALSE;
       
  2181 	doUnicodeHeader = TRUE;
       
  2182 	internalOrder = QChar::networkOrdered();
       
  2183 	break;
       
  2184     case UnicodeReverse:
       
  2185 	mapper = 0;
       
  2186 	latin1 = FALSE;
       
  2187 	doUnicodeHeader = TRUE;
       
  2188 	internalOrder = !QChar::networkOrdered();   //reverse network ordered
       
  2189 	break;
       
  2190     case RawUnicode:
       
  2191 	mapper = 0;
       
  2192 	latin1 = FALSE;
       
  2193 	doUnicodeHeader = FALSE;
       
  2194 	internalOrder = TRUE;
       
  2195 	break;
       
  2196     case Locale:
       
  2197 	latin1 = TRUE; 				// fallback to Latin 1
       
  2198 #ifndef QT_NO_TEXTCODEC
       
  2199 	mapper = QTextCodec::codecForLocale();
       
  2200 #if defined(_OS_WIN32_)
       
  2201 	if ( GetACP() == 1252 )
       
  2202 	    mapper = 0;				// Optimized latin1 processing
       
  2203 #endif
       
  2204 	if ( mapper && mapper->mibEnum() == 4 )
       
  2205 #endif
       
  2206 	    mapper = 0;				// Optimized latin1 processing
       
  2207 	doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
       
  2208 	break;
       
  2209     case Latin1:
       
  2210 	mapper = 0;
       
  2211 	doUnicodeHeader = FALSE;
       
  2212 	latin1 = TRUE;
       
  2213 	break;
       
  2214     }
       
  2215 }
       
  2216 
       
  2217 
       
  2218 #ifndef QT_NO_TEXTCODEC
       
  2219 /*!  Sets the codec for this stream to \a codec. Will not try to
       
  2220   autodetect Unicode.
       
  2221 
       
  2222   Note that this function should be called before any data is read
       
  2223   to/written from the stream.
       
  2224 
       
  2225   \sa setEncoding()
       
  2226 */
       
  2227 
       
  2228 void QTextStream::setCodec( QTextCodec *codec )
       
  2229 {
       
  2230     if ( d->sourceType == QTextStreamPrivate::String )
       
  2231 	return; // QString does not need any codec
       
  2232     mapper = codec;
       
  2233     doUnicodeHeader = FALSE;
       
  2234 }
       
  2235 #endif
       
  2236 
       
  2237 #endif // QT_NO_TEXTSTREAM