Orb/Doxygen/qtools/qdatastream.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /****************************************************************************
       
     2 ** 
       
     3 **
       
     4 ** Implementation of QDataStream class
       
     5 **
       
     6 ** Created : 930831
       
     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 "qdatastream.h"
       
    39 
       
    40 #ifndef QT_NO_DATASTREAM
       
    41 #include "qbuffer.h"
       
    42 #include <stdio.h>
       
    43 #include <ctype.h>
       
    44 #include <stdlib.h>
       
    45 
       
    46 // REVISED: warwick
       
    47 /*!
       
    48   \class QDataStream qdatastream.h
       
    49 
       
    50   \brief The QDataStream class provides serialization of
       
    51   binary data to a QIODevice.
       
    52 
       
    53   \ingroup io
       
    54 
       
    55   A data stream is a binary stream of encoded information which is 100%
       
    56   independent of the host computer operation system, CPU or byte order.	 A
       
    57   stream that is written by a PC under DOS/Windows can be read by a
       
    58   Sun SPARC running Solaris.
       
    59 
       
    60   The QDataStream class implements serialization of primitive types, like
       
    61   \c char, \c short, \c int, \c char* etc.  Serialization of more complex
       
    62   data is accomplished by breaking up the data into primitive units.
       
    63 
       
    64   The programmer can select which byte order to use when serializing data.
       
    65   The default setting is big endian (MSB first). Changing it to little
       
    66   endian breaks the portability (unless the reader also changes to little
       
    67   endian).  We recommend keeping this setting unless you have
       
    68   special requirements.
       
    69 
       
    70   A data stream cooperates closely with a QIODevice. A QIODevice
       
    71   represents an input/output medium one can read data from and write data
       
    72   to.  The QFile class is an example of an IO device.
       
    73 
       
    74   Example (write data to a stream):
       
    75   \code
       
    76     QFile f( "file.dta" );
       
    77     f.open( IO_WriteOnly );			// open file for writing
       
    78     QDataStream s( &f );			// serialize using f
       
    79     s << "the answer is";			// serialize string
       
    80     s << (Q_INT32)42;				// serialize integer
       
    81   \endcode
       
    82 
       
    83   Example (read data from a stream):
       
    84   \code
       
    85     QFile f( "file.dta" );
       
    86     f.open( IO_ReadOnly );			// open file for reading
       
    87     QDataStream s( &f );			// serialize using f
       
    88     char   *str;
       
    89     Q_INT32 a;
       
    90     s >> str >> a;				// "the answer is" and 42
       
    91     delete str;					// delete string
       
    92   \endcode
       
    93 
       
    94   In the last example, if you read into a QString instead of a \c char*
       
    95   you do not have to delete it.
       
    96 
       
    97   Normally, each item written to the stream is written in a fixed binary
       
    98   format.
       
    99   For example, a \c char* is written as a 32-bit integer equal to the
       
   100   length of the string including the NUL byte, followed by all the
       
   101   characters of the string including the NUL byte. Similarly when
       
   102   reading a string, 4 bytes are read to create the 32-bit length value,
       
   103   then that many characters for the string including the NUL. For a complete
       
   104   description of all Qt types supporting data streaming see \link
       
   105   datastreamformat.html Format of the QDataStream operators \endlink .
       
   106 
       
   107   If you want a "parsing" input stream, see QTextStream. If you just want the
       
   108   data to be human-readable to aid in debugging, you can set the data
       
   109   stream into printable data mode with setPrintableData(). The data is
       
   110   then written slower, in a human readable bloated form that is sufficient
       
   111   for debugging.
       
   112 
       
   113   If you are producing a new binary data format, such as a file format
       
   114   for documents created by your application, you could use a QDataStream
       
   115   to write the data in a portable format. Typically, you would write
       
   116   a brief header containing a magic string and a version number to give
       
   117   yourself room for future expansion. For example:
       
   118 
       
   119   \code
       
   120     // Open the file.
       
   121     QFile f( "file.xxx" );
       
   122     f.open( IO_WriteOnly );
       
   123     QDataStream s( &f );
       
   124 
       
   125     // Write a header with a "magic number" and a version
       
   126     s << 0xa0b0c0d0;
       
   127     s << 123;
       
   128 
       
   129     // Write the data
       
   130     s << [lots of interesting data]
       
   131   \endcode
       
   132 
       
   133   Then read it in with:
       
   134 
       
   135   \code
       
   136     // Open the file.
       
   137     QFile f( "file.xxx" );
       
   138     f.open( IO_ReadOnly );
       
   139     QDataStream s( &f );
       
   140 
       
   141     // Read and check the header
       
   142     Q_UINT32 magic;
       
   143     s >> magic;
       
   144     if ( magic != 0xa0b0c0d0 )
       
   145 	return XXX_BAD_FILE_FORMAT;
       
   146 
       
   147     // Read the version
       
   148     Q_INT32 version;
       
   149     s >> version;
       
   150     if ( version < 100 )
       
   151 	return XXX_BAD_FILE_TOO_OLD;
       
   152     if ( version > 123 )
       
   153 	return XXX_BAD_FILE_TOO_NEW;
       
   154     if ( version <= 110 )
       
   155 	s.setVersion(1);
       
   156 
       
   157     // Read the data
       
   158     s >> [lots of interesting data];
       
   159     if ( version > 120 )
       
   160 	s >> [data new in XXX version 1.2];
       
   161     s >> [other interesting data];
       
   162   \endcode
       
   163 
       
   164   \sa QTextStream QVariant
       
   165 */
       
   166 
       
   167 
       
   168 /*****************************************************************************
       
   169   QDataStream member functions
       
   170  *****************************************************************************/
       
   171 
       
   172 #if defined(CHECK_STATE)
       
   173 #undef  CHECK_STREAM_PRECOND
       
   174 #define CHECK_STREAM_PRECOND  if ( !dev ) {				\
       
   175 				qWarning( "QDataStream: No device" );	\
       
   176 				return *this; }
       
   177 #else
       
   178 #define CHECK_STREAM_PRECOND
       
   179 #endif
       
   180 
       
   181 static int  systemWordSize = 0;
       
   182 static bool systemBigEndian;
       
   183 
       
   184 static const int DefaultStreamVersion = 3;
       
   185 // 3 is default in Qt 2.1
       
   186 // 2 is the Qt 2.0.x format
       
   187 // 1 is the Qt 1.x format
       
   188 
       
   189 /*!
       
   190   Constructs a data stream that has no IO device.
       
   191 
       
   192   \sa setDevice()
       
   193 */
       
   194 
       
   195 QDataStream::QDataStream()
       
   196 {
       
   197     if ( systemWordSize == 0 )			// get system features
       
   198 	qSysInfo( &systemWordSize, &systemBigEndian );
       
   199     dev	      = 0;				// no device set
       
   200     owndev    = FALSE;
       
   201     byteorder = BigEndian;			// default byte order
       
   202     printable = FALSE;
       
   203     ver	      = DefaultStreamVersion;
       
   204     noswap    = systemBigEndian;
       
   205 }
       
   206 
       
   207 /*!
       
   208   Constructs a data stream that uses the IO device \a d.
       
   209 
       
   210   \sa setDevice(), device()
       
   211 */
       
   212 
       
   213 QDataStream::QDataStream( QIODevice *d )
       
   214 {
       
   215     if ( systemWordSize == 0 )			// get system features
       
   216 	qSysInfo( &systemWordSize, &systemBigEndian );
       
   217     dev	      = d;				// set device
       
   218     owndev    = FALSE;
       
   219     byteorder = BigEndian;			// default byte order
       
   220     printable = FALSE;
       
   221     ver	      = DefaultStreamVersion;
       
   222     noswap    = systemBigEndian;
       
   223 }
       
   224 
       
   225 /*!
       
   226   Constructs a data stream that operates on a byte array through an
       
   227   internal QBuffer device.
       
   228 
       
   229   Example:
       
   230   \code
       
   231     static char bindata[] = { 231, 1, 44, ... };
       
   232     QByteArray	a;
       
   233     a.setRawData( bindata, sizeof(bindata) );	// a points to bindata
       
   234     QDataStream s( a, IO_ReadOnly );		// open on a's data
       
   235     s >> [something];				// read raw bindata
       
   236     a.resetRawData( bindata, sizeof(bindata) ); // finished
       
   237   \endcode
       
   238 
       
   239   The QArray::setRawData() function is not for the inexperienced.
       
   240 */
       
   241 
       
   242 QDataStream::QDataStream( QByteArray a, int mode )
       
   243 {
       
   244     if ( systemWordSize == 0 )			// get system features
       
   245 	qSysInfo( &systemWordSize, &systemBigEndian );
       
   246     dev	      = new QBuffer( a );		// create device
       
   247     ((QBuffer *)dev)->open( mode );		// open device
       
   248     owndev    = TRUE;
       
   249     byteorder = BigEndian;			// default byte order
       
   250     printable = FALSE;
       
   251     ver	      = DefaultStreamVersion;
       
   252     noswap    = systemBigEndian;
       
   253 }
       
   254 
       
   255 /*!
       
   256   Destructs the data stream.
       
   257 
       
   258   The destructor will not affect the current IO device, unless it
       
   259   is an internal IO device processing a QByteArray passed in the constructor.
       
   260 */
       
   261 
       
   262 QDataStream::~QDataStream()
       
   263 {
       
   264     if ( owndev )
       
   265 	delete dev;
       
   266 }
       
   267 
       
   268 
       
   269 /*!
       
   270   \fn QIODevice *QDataStream::device() const
       
   271   Returns the IO device currently set.
       
   272   \sa setDevice(), unsetDevice()
       
   273 */
       
   274 
       
   275 /*!
       
   276   void QDataStream::setDevice(QIODevice *d )
       
   277   Sets the IO device to \a d.
       
   278   \sa device(), unsetDevice()
       
   279 */
       
   280 
       
   281 void QDataStream::setDevice(QIODevice *d )
       
   282 {
       
   283     if ( owndev ) {
       
   284 	delete dev;
       
   285 	owndev = FALSE;
       
   286     }
       
   287     dev = d;
       
   288 }
       
   289 
       
   290 /*!
       
   291   Unsets the IO device.	 This is the same as calling setDevice( 0 ).
       
   292   \sa device(), setDevice()
       
   293 */
       
   294 
       
   295 void QDataStream::unsetDevice()
       
   296 {
       
   297     setDevice( 0 );
       
   298 }
       
   299 
       
   300 
       
   301 /*!
       
   302   \fn bool QDataStream::atEnd() const
       
   303   Returns TRUE if the IO device has reached the end position (end of
       
   304   stream or file) or if there is no IO device set.
       
   305 
       
   306   Returns FALSE if the current position of the read/write head of the IO
       
   307   device is somewhere before the end position.
       
   308 
       
   309   \sa QIODevice::atEnd()
       
   310 */
       
   311 
       
   312 /*!\fn bool QDataStream::eof() const
       
   313 
       
   314   \obsolete
       
   315 
       
   316   Returns TRUE if the IO device has reached the end position (end of
       
   317   stream or file) or if there is no IO device set.
       
   318 
       
   319   Returns FALSE if the current position of the read/write head of the IO
       
   320   device is somewhere before the end position.
       
   321 
       
   322   \sa QIODevice::atEnd()
       
   323 */
       
   324 
       
   325 /*!
       
   326   \fn int QDataStream::byteOrder() const
       
   327   Returns the current byte order setting - either \c BigEndian or
       
   328   \c LittleEndian.
       
   329 
       
   330   \sa setByteOrder()
       
   331 */
       
   332 
       
   333 /*!
       
   334   Sets the serialization byte order to \a bo.
       
   335 
       
   336   The \a bo parameter can be \c QDataStream::BigEndian or
       
   337   \c QDataStream::LittleEndian.
       
   338 
       
   339   The default setting is big endian.  We recommend leaving this setting unless
       
   340   you have special requirements.
       
   341 
       
   342   \sa byteOrder()
       
   343 */
       
   344 
       
   345 void QDataStream::setByteOrder( int bo )
       
   346 {
       
   347     byteorder = bo;
       
   348     if ( systemBigEndian )
       
   349 	noswap = byteorder == BigEndian;
       
   350     else
       
   351 	noswap = byteorder == LittleEndian;
       
   352 }
       
   353 
       
   354 
       
   355 /*!
       
   356   \fn bool QDataStream::isPrintableData() const
       
   357   Returns TRUE if the printable data flag has been set.
       
   358   \sa setPrintableData()
       
   359 */
       
   360 
       
   361 /*!
       
   362   \fn void QDataStream::setPrintableData( bool enable )
       
   363   Sets or clears the printable data flag.
       
   364 
       
   365   If this flag is set, the write functions will generate output that
       
   366   consists of printable characters (7 bit ASCII).
       
   367 
       
   368   We recommend enabling printable data only for debugging purposes
       
   369   (it is slower and creates larger output).
       
   370 */
       
   371 
       
   372 
       
   373 /*!
       
   374   \fn int QDataStream::version() const
       
   375   Returns the version number of the data serialization format.
       
   376   In Qt 2.1, this number is by default 3.
       
   377   \sa setVersion()
       
   378 */
       
   379 
       
   380 /*!
       
   381   \fn void QDataStream::setVersion( int v )
       
   382   Sets the version number of the data serialization format.
       
   383 
       
   384   In order to accomodate for new functionality, the datastream
       
   385   serialization format of some Qt classes has changed in some versions of
       
   386   Qt. If you want to read data that was created by an earlier version of
       
   387   Qt, or write data that can be read by a program that was compiled with
       
   388   an earlier version of Qt, use this function to modify the serialization
       
   389   format of QDataStream.
       
   390 
       
   391   For Qt 1.x compatibility, use \a v == 1.
       
   392 
       
   393   For Qt 2.0.x compatibility, use \a v == 2 (Not required for reading in
       
   394   Qt 2.1).
       
   395 
       
   396   \sa version()
       
   397 */
       
   398 
       
   399 /*****************************************************************************
       
   400   QDataStream read functions
       
   401  *****************************************************************************/
       
   402 
       
   403 
       
   404 static Q_INT32 read_int_ascii( QDataStream *s )
       
   405 {
       
   406     register int n = 0;
       
   407     char buf[40];
       
   408     while ( TRUE ) {
       
   409 	buf[n] = s->device()->getch();
       
   410 	if ( buf[n] == '\n' || n > 38 )		// $-terminator
       
   411 	    break;
       
   412 	n++;
       
   413     }
       
   414     buf[n] = '\0';
       
   415     return atol( buf );
       
   416 }
       
   417 
       
   418 
       
   419 /*!
       
   420   \fn QDataStream &QDataStream::operator>>( Q_UINT8 &i )
       
   421   Reads an unsigned byte from the stream and returns a reference to
       
   422   the stream.
       
   423 */
       
   424 
       
   425 /*!
       
   426   Reads a signed byte from the stream.
       
   427 */
       
   428 
       
   429 QDataStream &QDataStream::operator>>( Q_INT8 &i )
       
   430 {
       
   431     CHECK_STREAM_PRECOND
       
   432     if ( printable ) {				// printable data
       
   433 	i = (Q_INT8)dev->getch();
       
   434 	if ( i == '\\' ) {			// read octal code
       
   435 	    char buf[4];
       
   436 	    dev->readBlock( buf, 3 );
       
   437 	    i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
       
   438 	}
       
   439     } else {					// data or text
       
   440 	i = (Q_INT8)dev->getch();
       
   441     }
       
   442     return *this;
       
   443 }
       
   444 
       
   445 
       
   446 /*!
       
   447   \fn QDataStream &QDataStream::operator>>( Q_UINT16 &i )
       
   448   Reads an unsigned 16-bit integer from the stream and returns a reference to
       
   449   the stream.
       
   450 */
       
   451 
       
   452 /*!
       
   453   Reads a signed 16-bit integer from the stream and returns a reference to
       
   454   the stream.
       
   455 */
       
   456 
       
   457 QDataStream &QDataStream::operator>>( Q_INT16 &i )
       
   458 {
       
   459     CHECK_STREAM_PRECOND
       
   460     if ( printable ) {				// printable data
       
   461 	i = (Q_INT16)read_int_ascii( this );
       
   462     } else if ( noswap ) {			// no conversion needed
       
   463 	dev->readBlock( (char *)&i, sizeof(Q_INT16) );
       
   464     } else {					// swap bytes
       
   465 	register uchar *p = (uchar *)(&i);
       
   466 	char b[2];
       
   467 	dev->readBlock( b, 2 );
       
   468 	*p++ = b[1];
       
   469 	*p   = b[0];
       
   470     }
       
   471     return *this;
       
   472 }
       
   473 
       
   474 
       
   475 /*!
       
   476   \fn QDataStream &QDataStream::operator>>( Q_UINT32 &i )
       
   477   Reads an unsigned 32-bit integer from the stream and returns a reference to
       
   478   the stream.
       
   479 */
       
   480 
       
   481 /*!
       
   482   Reads a signed 32-bit integer from the stream and returns a reference to
       
   483   the stream.
       
   484 */
       
   485 
       
   486 QDataStream &QDataStream::operator>>( Q_INT32 &i )
       
   487 {
       
   488     CHECK_STREAM_PRECOND
       
   489     if ( printable ) {				// printable data
       
   490 	i = read_int_ascii( this );
       
   491     } else if ( noswap ) {			// no conversion needed
       
   492 	dev->readBlock( (char *)&i, sizeof(Q_INT32) );
       
   493     } else {					// swap bytes
       
   494 	register uchar *p = (uchar *)(&i);
       
   495 	char b[4];
       
   496 	dev->readBlock( b, 4 );
       
   497 	*p++ = b[3];
       
   498 	*p++ = b[2];
       
   499 	*p++ = b[1];
       
   500 	*p   = b[0];
       
   501     }
       
   502     return *this;
       
   503 }
       
   504 
       
   505 /*!
       
   506   \fn QDataStream &QDataStream::operator>>( Q_UINT64 &i )
       
   507   Reads an unsigned 64-bit integer from the stream and returns a reference to
       
   508   the stream, or uses the Q_UINT32 operator if 64 bit is not available.
       
   509 */
       
   510 
       
   511 /*!
       
   512   Reads a signed 64-bit integer from the stream and returns a reference to
       
   513   the stream, or uses the Q_UINT32 operator if 64 bit is not available.
       
   514 */
       
   515 
       
   516 QDataStream &QDataStream::operator>>( Q_INT64 &i )
       
   517 {
       
   518     CHECK_STREAM_PRECOND
       
   519     if ( printable ) {				// printable data
       
   520 	i = read_int_ascii( this );
       
   521     } else if ( noswap ) {			// no conversion needed
       
   522 	dev->readBlock( (char *)&i, sizeof(Q_INT64) );
       
   523     } else {					// swap bytes
       
   524 	register uchar *p = (uchar *)(&i);
       
   525 	char b[sizeof(Q_INT64)];
       
   526 	dev->readBlock( b, sizeof(Q_INT64) );
       
   527 	if ( sizeof(Q_INT64) == 8 ) {
       
   528 	    *p++ = b[7];
       
   529 	    *p++ = b[6];
       
   530 	    *p++ = b[5];
       
   531 	    *p++ = b[4];
       
   532 	}
       
   533 	*p++ = b[3];
       
   534 	*p++ = b[2];
       
   535 	*p++ = b[1];
       
   536 	*p   = b[0];
       
   537     }
       
   538     return *this;
       
   539 }
       
   540 
       
   541 static double read_double_ascii( QDataStream *s )
       
   542 {
       
   543     register int n = 0;
       
   544     char buf[80];
       
   545     while ( TRUE ) {
       
   546 	buf[n] = s->device()->getch();
       
   547 	if ( buf[n] == '\n' || n > 78 )		// $-terminator
       
   548 	    break;
       
   549 	n++;
       
   550     }
       
   551     buf[n] = '\0';
       
   552     return atof( buf );
       
   553 }
       
   554 
       
   555 
       
   556 /*!
       
   557   Reads a 32-bit floating point number from the stream using the standard
       
   558   IEEE754 format. Returns a reference to the stream.
       
   559 */
       
   560 
       
   561 QDataStream &QDataStream::operator>>( float &f )
       
   562 {
       
   563     CHECK_STREAM_PRECOND
       
   564     if ( printable ) {				// printable data
       
   565 	f = (float)read_double_ascii( this );
       
   566     } else if ( noswap ) {			// no conversion needed
       
   567 	dev->readBlock( (char *)&f, sizeof(float) );
       
   568     } else {					// swap bytes
       
   569 	register uchar *p = (uchar *)(&f);
       
   570 	char b[4];
       
   571 	dev->readBlock( b, 4 );
       
   572 	*p++ = b[3];
       
   573 	*p++ = b[2];
       
   574 	*p++ = b[1];
       
   575 	*p   = b[0];
       
   576     }
       
   577     return *this;
       
   578 }
       
   579 
       
   580 
       
   581 /*!
       
   582   Reads a 64-bit floating point number from the stream using the standard
       
   583   IEEE754 format. Returns a reference to the stream.
       
   584 */
       
   585 
       
   586 QDataStream &QDataStream::operator>>( double &f )
       
   587 {
       
   588     CHECK_STREAM_PRECOND
       
   589     if ( printable ) {				// printable data
       
   590 	f = read_double_ascii( this );
       
   591     } else if ( noswap ) {			// no conversion needed
       
   592 	dev->readBlock( (char *)&f, sizeof(double) );
       
   593     } else {					// swap bytes
       
   594 	register uchar *p = (uchar *)(&f);
       
   595 	char b[8];
       
   596 	dev->readBlock( b, 8 );
       
   597 	*p++ = b[7];
       
   598 	*p++ = b[6];
       
   599 	*p++ = b[5];
       
   600 	*p++ = b[4];
       
   601 	*p++ = b[3];
       
   602 	*p++ = b[2];
       
   603 	*p++ = b[1];
       
   604 	*p   = b[0];
       
   605     }
       
   606     return *this;
       
   607 }
       
   608 
       
   609 
       
   610 /*!
       
   611   Reads the '\0'-terminated string \a s from the stream and returns
       
   612   a reference to the stream.
       
   613 
       
   614   Space for the string is allocated using \c new - the caller must
       
   615   eventually call delete[] on the value.
       
   616 */
       
   617 
       
   618 QDataStream &QDataStream::operator>>( char *&s )
       
   619 {
       
   620     uint len = 0;
       
   621     return readBytes( s, len );
       
   622 }
       
   623 
       
   624 
       
   625 /*!
       
   626   Reads the buffer \a s from the stream and returns a reference to the
       
   627   stream.
       
   628 
       
   629   The buffer \a s is allocated using \c new. Destroy it with the \c delete[]
       
   630   operator.  If the length is zero or \a s cannot be allocated, \a s is
       
   631   set to 0.
       
   632 
       
   633   The \a l parameter will be set to the length of the buffer.
       
   634 
       
   635   The serialization format is an Q_UINT32 length specifier first, then the
       
   636   data (\a l bytes).
       
   637 
       
   638   \sa readRawBytes(), writeBytes()
       
   639 */
       
   640 
       
   641 QDataStream &QDataStream::readBytes( char *&s, uint &l )
       
   642 {
       
   643     CHECK_STREAM_PRECOND
       
   644     Q_UINT32 len;
       
   645     *this >> len;				// first read length spec
       
   646     l = (uint)len;
       
   647     if ( len == 0 || eof() ) {
       
   648 	s = 0;
       
   649 	return *this;
       
   650     } else {
       
   651 	s = new char[len];			// create char array
       
   652 	CHECK_PTR( s );
       
   653 	if ( !s )				// no memory
       
   654 	    return *this;
       
   655 	return readRawBytes( s, (uint)len );
       
   656     }
       
   657 }
       
   658 
       
   659 
       
   660 /*!
       
   661   Reads \a len bytes from the stream into \a s and returns a reference to
       
   662   the stream.
       
   663 
       
   664   The buffer \a s must be preallocated.
       
   665 
       
   666   \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
       
   667 */
       
   668 
       
   669 QDataStream &QDataStream::readRawBytes( char *s, uint len )
       
   670 {
       
   671     CHECK_STREAM_PRECOND
       
   672     if ( printable ) {				// printable data
       
   673 	register Q_INT8 *p = (Q_INT8*)s;
       
   674 	while ( len-- )
       
   675 	    *this >> *p++;
       
   676     } else {					// read data char array
       
   677 	dev->readBlock( s, len );
       
   678     }
       
   679     return *this;
       
   680 }
       
   681 
       
   682 
       
   683 /*****************************************************************************
       
   684   QDataStream write functions
       
   685  *****************************************************************************/
       
   686 
       
   687 
       
   688 /*!
       
   689   \fn QDataStream &QDataStream::operator<<( Q_UINT8 i )
       
   690   Writes an unsigned byte to the stream and returns a reference to
       
   691   the stream.
       
   692 */
       
   693 
       
   694 /*!
       
   695   Writes a signed byte to the stream.
       
   696 */
       
   697 
       
   698 QDataStream &QDataStream::operator<<( Q_INT8 i )
       
   699 {
       
   700     CHECK_STREAM_PRECOND
       
   701     if ( printable && (i == '\\' || !isprint(i)) ) {
       
   702 	char buf[6];				// write octal code
       
   703 	buf[0] = '\\';
       
   704 	buf[1] = '0' + ((i >> 6) & 0x07);
       
   705 	buf[2] = '0' + ((i >> 3) & 0x07);
       
   706 	buf[3] = '0' + (i & 0x07);
       
   707 	buf[4] = '\0';
       
   708 	dev->writeBlock( buf, 4 );
       
   709     } else {
       
   710 	dev->putch( i );
       
   711     }
       
   712     return *this;
       
   713 }
       
   714 
       
   715 
       
   716 /*!
       
   717   \fn QDataStream &QDataStream::operator<<( Q_UINT16 i )
       
   718   Writes an unsigned 16-bit integer to the stream and returns a reference
       
   719   to the stream.
       
   720 */
       
   721 
       
   722 /*!
       
   723   Writes a signed 16-bit integer to the stream and returns a reference to
       
   724   the stream.
       
   725 */
       
   726 
       
   727 QDataStream &QDataStream::operator<<( Q_INT16 i )
       
   728 {
       
   729     CHECK_STREAM_PRECOND
       
   730     if ( printable ) {				// printable data
       
   731 	char buf[16];
       
   732 	sprintf( buf, "%d\n", i );
       
   733 	dev->writeBlock( buf, strlen(buf) );
       
   734     } else if ( noswap ) {			// no conversion needed
       
   735 	dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
       
   736     } else {					// swap bytes
       
   737 	register uchar *p = (uchar *)(&i);
       
   738 	char b[2];
       
   739 	b[1] = *p++;
       
   740 	b[0] = *p;
       
   741 	dev->writeBlock( b, 2 );
       
   742     }
       
   743     return *this;
       
   744 }
       
   745 
       
   746 
       
   747 /*!
       
   748   \fn QDataStream &QDataStream::operator<<( Q_UINT32 i )
       
   749   Writes an unsigned 32-bit integer to the stream and returns a reference to
       
   750   the stream.
       
   751 */
       
   752 
       
   753 /*!
       
   754   Writes a signed 32-bit integer to the stream and returns a reference to
       
   755   the stream.
       
   756 */
       
   757 
       
   758 QDataStream &QDataStream::operator<<( Q_INT32 i )
       
   759 {
       
   760     CHECK_STREAM_PRECOND
       
   761     if ( printable ) {				// printable data
       
   762 	char buf[16];
       
   763 	sprintf( buf, "%d\n", i );
       
   764 	dev->writeBlock( buf, strlen(buf) );
       
   765     } else if ( noswap ) {			// no conversion needed
       
   766 	dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
       
   767     } else {					// swap bytes
       
   768 	register uchar *p = (uchar *)(&i);
       
   769 	char b[4];
       
   770 	b[3] = *p++;
       
   771 	b[2] = *p++;
       
   772 	b[1] = *p++;
       
   773 	b[0] = *p;
       
   774 	dev->writeBlock( b, 4 );
       
   775     }
       
   776     return *this;
       
   777 }
       
   778 
       
   779 /*!
       
   780   \fn QDataStream &QDataStream::operator<<( Q_UINT64 i )
       
   781   Writes an unsigned 64-bit integer to the stream and returns a reference to
       
   782   the stream, or uses the Q_UINT32-operator if 64 bit is not available.
       
   783 */
       
   784 
       
   785 /*!
       
   786   Writes a signed 64-bit integer to the stream and returns a reference to
       
   787   the stream, or calls the Q_INT32-operator if 64 bit is not available.
       
   788 */
       
   789 
       
   790 QDataStream &QDataStream::operator<<( Q_INT64 i )
       
   791 {
       
   792     CHECK_STREAM_PRECOND
       
   793     if ( printable ) {				// printable data
       
   794 	char buf[20];
       
   795 	sprintf( buf, "%ld\n", i );
       
   796 	dev->writeBlock( buf, strlen(buf) );
       
   797     } else if ( noswap ) {			// no conversion needed
       
   798 	dev->writeBlock( (char *)&i, sizeof(Q_INT64) );
       
   799     } else {					// swap bytes
       
   800 	register uchar *p = (uchar *)(&i);
       
   801 	char b[sizeof(Q_INT64)];
       
   802 	if ( sizeof(Q_INT64) == 8 ) {
       
   803 	    b[7] = *p++;
       
   804 	    b[6] = *p++;
       
   805 	    b[5] = *p++;
       
   806 	    b[4] = *p++;
       
   807 	}
       
   808 	b[3] = *p++;
       
   809 	b[2] = *p++;
       
   810 	b[1] = *p++;
       
   811 	b[0] = *p;
       
   812 	dev->writeBlock( b, sizeof(Q_INT64) );
       
   813     }
       
   814     return *this;
       
   815 }
       
   816 
       
   817 /*!
       
   818   \fn QDataStream &QDataStream::operator<<( uint i )
       
   819   Writes an unsigned integer to the stream as a 32-bit unsigned integer
       
   820   (Q_UINT32).
       
   821   Returns a reference to the stream.
       
   822 */
       
   823 
       
   824 /*!
       
   825   \fn QDataStream &QDataStream::operator<<( int i )
       
   826   Writes a signed integer to the stream as a 32-bit signed integer (Q_INT32).
       
   827   Returns a reference to the stream.
       
   828 */
       
   829 
       
   830 
       
   831 /*!
       
   832   Writes a 32-bit floating point number to the stream using the standard
       
   833   IEEE754 format.  Returns a reference to the stream.
       
   834 */
       
   835 
       
   836 QDataStream &QDataStream::operator<<( float f )
       
   837 {
       
   838     CHECK_STREAM_PRECOND
       
   839     if ( printable ) {				// printable data
       
   840 	char buf[32];
       
   841 	sprintf( buf, "%g\n", (double)f );
       
   842 	dev->writeBlock( buf, strlen(buf) );
       
   843     } else {
       
   844 	float g = f;				// fixes float-on-stack problem
       
   845 	if ( noswap ) {				// no conversion needed
       
   846 	    dev->writeBlock( (char *)&g, sizeof(float) );
       
   847 	} else {				// swap bytes
       
   848 	    register uchar *p = (uchar *)(&g);
       
   849 	    char b[4];
       
   850 	    b[3] = *p++;
       
   851 	    b[2] = *p++;
       
   852 	    b[1] = *p++;
       
   853 	    b[0] = *p;
       
   854 	    dev->writeBlock( b, 4 );
       
   855 	}
       
   856     }
       
   857     return *this;
       
   858 }
       
   859 
       
   860 
       
   861 /*!
       
   862   Writes a 64-bit floating point number to the stream using the standard
       
   863   IEEE754 format.  Returns a reference to the stream.
       
   864 */
       
   865 
       
   866 QDataStream &QDataStream::operator<<( double f )
       
   867 {
       
   868     CHECK_STREAM_PRECOND
       
   869     if ( printable ) {				// printable data
       
   870 	char buf[32];
       
   871 	sprintf( buf, "%g\n", f );
       
   872 	dev->writeBlock( buf, strlen(buf) );
       
   873     } else if ( noswap ) {			// no conversion needed
       
   874 	dev->writeBlock( (char *)&f, sizeof(double) );
       
   875     } else {					// swap bytes
       
   876 	register uchar *p = (uchar *)(&f);
       
   877 	char b[8];
       
   878 	b[7] = *p++;
       
   879 	b[6] = *p++;
       
   880 	b[5] = *p++;
       
   881 	b[4] = *p++;
       
   882 	b[3] = *p++;
       
   883 	b[2] = *p++;
       
   884 	b[1] = *p++;
       
   885 	b[0] = *p;
       
   886 	dev->writeBlock( b, 8 );
       
   887     }
       
   888     return *this;
       
   889 }
       
   890 
       
   891 
       
   892 /*!
       
   893   Writes the '\0'-terminated string \a s to the stream and returns
       
   894   a reference to the stream.
       
   895 
       
   896   The string is serialized using writeBytes().
       
   897 */
       
   898 
       
   899 QDataStream &QDataStream::operator<<( const char *s )
       
   900 {
       
   901     if ( !s ) {
       
   902 	*this << (Q_UINT32)0;
       
   903 	return *this;
       
   904     }
       
   905     uint len = qstrlen( s ) + 1;			// also write null terminator
       
   906     *this << (Q_UINT32)len;			// write length specifier
       
   907     return writeRawBytes( s, len );
       
   908 }
       
   909 
       
   910 
       
   911 /*!
       
   912   Writes the length specifier \a len and the buffer \a s to the stream and
       
   913   returns a reference to the stream.
       
   914 
       
   915   The \a len is serialized as an Q_UINT32, followed by \a len bytes from
       
   916   \a s.
       
   917 
       
   918   \sa writeRawBytes(), readBytes()
       
   919 */
       
   920 
       
   921 QDataStream &QDataStream::writeBytes(const char *s, uint len)
       
   922 {
       
   923     CHECK_STREAM_PRECOND
       
   924     *this << (Q_UINT32)len;			// write length specifier
       
   925     if ( len )
       
   926 	writeRawBytes( s, len );
       
   927     return *this;
       
   928 }
       
   929 
       
   930 
       
   931 /*!
       
   932   Writes \a len bytes from \a s to the stream and returns a reference to the
       
   933   stream.
       
   934 
       
   935   \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
       
   936 */
       
   937 
       
   938 QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
       
   939 {
       
   940     CHECK_STREAM_PRECOND
       
   941     if ( printable ) {				// write printable
       
   942 	register char *p = (char *)s;
       
   943 	while ( len-- )
       
   944 	    *this << *p++;
       
   945     } else {					// write data char array
       
   946 	dev->writeBlock( s, len );
       
   947     }
       
   948     return *this;
       
   949 }
       
   950 
       
   951 #endif // QT_NO_DATASTREAM