Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qdatastream.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qdatastream.cpp,v 1.2 2003/07/10 02:40:11 llornkcor Exp $
00003 **
00004 ** Implementation of QDataStream class
00005 **
00006 ** Created : 930831
00007 **
00008 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the tools module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 
00038 #include "qdatastream.h"
00039 
00040 #ifndef QT_NO_DATASTREAM
00041 #include "qbuffer.h"
00042 #include <stdio.h>
00043 #include <ctype.h>
00044 #include <stdlib.h>
00045 
00202 /*****************************************************************************
00203   QDataStream member functions
00204  *****************************************************************************/
00205 
00206 #if defined(QT_CHECK_STATE)
00207 #undef  CHECK_STREAM_PRECOND
00208 #define CHECK_STREAM_PRECOND  if ( !dev ) {                             \
00209                                 qWarning( "QDataStream: No device" );   \
00210                                 return *this; }
00211 #else
00212 #define CHECK_STREAM_PRECOND
00213 #endif
00214 
00215 static int  systemWordSize = 0;
00216 static bool systemBigEndian;
00217 
00218 static const int DefaultStreamVersion = 5;
00219 // 5 is default in Qt 3.1
00220 // 4 is default in Qt 3.0
00221 // 3 is default in Qt 2.1
00222 // 2 is the Qt 2.0.x format
00223 // 1 is the Qt 1.x format
00224 
00231 QDataStream::QDataStream()
00232 {
00233     if ( systemWordSize == 0 )                  // get system features
00234         qSysInfo( &systemWordSize, &systemBigEndian );
00235     dev       = 0;                              // no device set
00236     owndev    = FALSE;
00237     byteorder = BigEndian;                      // default byte order
00238     printable = FALSE;
00239     ver       = DefaultStreamVersion;
00240     noswap    = systemBigEndian;
00241 }
00242 
00255 QDataStream::QDataStream( QIODevice *d )
00256 {
00257     if ( systemWordSize == 0 )                  // get system features
00258         qSysInfo( &systemWordSize, &systemBigEndian );
00259     dev       = d;                              // set device
00260     owndev    = FALSE;
00261     byteorder = BigEndian;                      // default byte order
00262     printable = FALSE;
00263     ver       = DefaultStreamVersion;
00264     noswap    = systemBigEndian;
00265 }
00266 
00286 QDataStream::QDataStream( QByteArray a, int mode )
00287 {
00288     if ( systemWordSize == 0 )                  // get system features
00289         qSysInfo( &systemWordSize, &systemBigEndian );
00290     dev       = new QBuffer( a );               // create device
00291     ((QBuffer *)dev)->open( mode );             // open device
00292     owndev    = TRUE;
00293     byteorder = BigEndian;                      // default byte order
00294     printable = FALSE;
00295     ver       = DefaultStreamVersion;
00296     noswap    = systemBigEndian;
00297 }
00298 
00307 QDataStream::~QDataStream()
00308 {
00309     if ( owndev )
00310         delete dev;
00311 }
00312 
00313 
00330 void QDataStream::setDevice(QIODevice *d )
00331 {
00332     if ( owndev ) {
00333         delete dev;
00334         owndev = FALSE;
00335     }
00336     dev = d;
00337 }
00338 
00345 void QDataStream::unsetDevice()
00346 {
00347     setDevice( 0 );
00348 }
00349 
00350 
00396 void QDataStream::setByteOrder( int bo )
00397 {
00398     byteorder = bo;
00399     if ( systemBigEndian )
00400         noswap = byteorder == BigEndian;
00401     else
00402         noswap = byteorder == LittleEndian;
00403 }
00404 
00405 
00467 /*****************************************************************************
00468   QDataStream read functions
00469  *****************************************************************************/
00470 
00471 
00472 static Q_INT32 read_int_ascii( QDataStream *s )
00473 {
00474     register int n = 0;
00475     char buf[40];
00476     for ( ;; ) {
00477         buf[n] = s->device()->getch();
00478         if ( buf[n] == '\n' || n > 38 )         // $-terminator
00479             break;
00480         n++;
00481     }
00482     buf[n] = '\0';
00483     return atol( buf );
00484 }
00485 
00486 
00499 QDataStream &QDataStream::operator>>( Q_INT8 &i )
00500 {
00501     CHECK_STREAM_PRECOND
00502     if ( printable ) {                          // printable data
00503         i = (Q_INT8)dev->getch();
00504         if ( i == '\\' ) {                      // read octal code
00505             char buf[4];
00506             dev->readBlock( buf, 3 );
00507             i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
00508         }
00509     } else {                                    // data or text
00510         i = (Q_INT8)dev->getch();
00511     }
00512     return *this;
00513 }
00514 
00515 
00530 QDataStream &QDataStream::operator>>( Q_INT16 &i )
00531 {
00532     CHECK_STREAM_PRECOND
00533     if ( printable ) {                          // printable data
00534         i = (Q_INT16)read_int_ascii( this );
00535     } else if ( noswap ) {                      // no conversion needed
00536         dev->readBlock( (char *)&i, sizeof(Q_INT16) );
00537     } else {                                    // swap bytes
00538         register uchar *p = (uchar *)(&i);
00539         char b[2];
00540         dev->readBlock( b, 2 );
00541         *p++ = b[1];
00542         *p   = b[0];
00543     }
00544     return *this;
00545 }
00546 
00547 
00562 QDataStream &QDataStream::operator>>( Q_INT32 &i )
00563 {
00564     CHECK_STREAM_PRECOND
00565     if ( printable ) {                          // printable data
00566         i = read_int_ascii( this );
00567     } else if ( noswap ) {                      // no conversion needed
00568         dev->readBlock( (char *)&i, sizeof(Q_INT32) );
00569     } else {                                    // swap bytes
00570         uchar *p = (uchar *)(&i);
00571         char b[4];
00572         dev->readBlock( b, 4 );
00573         *p++ = b[3];
00574         *p++ = b[2];
00575         *p++ = b[1];
00576         *p   = b[0];
00577     }
00578     return *this;
00579 }
00580 
00595 QDataStream &QDataStream::operator>>( Q_LONG &i )
00596 {
00597     CHECK_STREAM_PRECOND
00598     if ( printable ) {                          // printable data
00599         i = read_int_ascii( this );
00600     } else if ( noswap ) {                      // no conversion needed
00601         dev->readBlock( (char *)&i, sizeof(Q_LONG) );
00602     } else {                                    // swap bytes
00603         register uchar *p = (uchar *)(&i);
00604         char b[sizeof(Q_LONG)];
00605         dev->readBlock( b, sizeof(Q_LONG) );
00606         for ( int j = sizeof(Q_LONG); j;  )
00607             *p++ = b[--j];
00608     }
00609     return *this;
00610 }
00611 
00612 static double read_double_ascii( QDataStream *s )
00613 {
00614     register int n = 0;
00615     char buf[80];
00616     for ( ;; ) {
00617         buf[n] = s->device()->getch();
00618         if ( buf[n] == '\n' || n > 78 )         // $-terminator
00619             break;
00620         n++;
00621     }
00622     buf[n] = '\0';
00623     return atof( buf );
00624 }
00625 
00626 
00635 QDataStream &QDataStream::operator>>( float &f )
00636 {
00637     CHECK_STREAM_PRECOND
00638     if ( printable ) {                          // printable data
00639         f = (float)read_double_ascii( this );
00640     } else if ( noswap ) {                      // no conversion needed
00641         dev->readBlock( (char *)&f, sizeof(float) );
00642     } else {                                    // swap bytes
00643         uchar *p = (uchar *)(&f);
00644         char b[4];
00645         dev->readBlock( b, 4 );
00646         *p++ = b[3];
00647         *p++ = b[2];
00648         *p++ = b[1];
00649         *p   = b[0];
00650     }
00651     return *this;
00652 }
00653 
00654 
00663 QDataStream &QDataStream::operator>>( double &f )
00664 {
00665     CHECK_STREAM_PRECOND
00666     if ( printable ) {                          // printable data
00667         f = read_double_ascii( this );
00668     } else if ( noswap ) {                      // no conversion needed
00669         dev->readBlock( (char *)&f, sizeof(double) );
00670     } else {                                    // swap bytes
00671         register uchar *p = (uchar *)(&f);
00672         char b[8];
00673         dev->readBlock( b, 8 );
00674         *p++ = b[7];
00675         *p++ = b[6];
00676         *p++ = b[5];
00677         *p++ = b[4];
00678         *p++ = b[3];
00679         *p++ = b[2];
00680         *p++ = b[1];
00681         *p   = b[0];
00682     }
00683     return *this;
00684 }
00685 
00686 
00697 QDataStream &QDataStream::operator>>( char *&s )
00698 {
00699     uint len = 0;
00700     return readBytes( s, len );
00701 }
00702 
00703 
00720 QDataStream &QDataStream::readBytes( char *&s, uint &l )
00721 {
00722     CHECK_STREAM_PRECOND
00723     Q_UINT32 len;
00724     *this >> len;                               // first read length spec
00725     l = (uint)len;
00726     if ( len == 0 || eof() ) {
00727         s = 0;
00728         return *this;
00729     } else {
00730         s = new char[len];                      // create char array
00731         Q_CHECK_PTR( s );
00732         if ( !s )                               // no memory
00733             return *this;
00734         return readRawBytes( s, (uint)len );
00735     }
00736 }
00737 
00738 
00748 QDataStream &QDataStream::readRawBytes( char *s, uint len )
00749 {
00750     CHECK_STREAM_PRECOND
00751     if ( printable ) {                          // printable data
00752         register Q_INT8 *p = (Q_INT8*)s;
00753         if ( version() < 4 ) {
00754             while ( len-- ) {
00755                 Q_INT32 tmp;
00756                 *this >> tmp;
00757                 *p++ = tmp;
00758             }
00759         } else {
00760             while ( len-- )
00761                 *this >> *p++;
00762         }
00763     } else {                                    // read data char array
00764         dev->readBlock( s, len );
00765     }
00766     return *this;
00767 }
00768 
00769 
00770 /*****************************************************************************
00771   QDataStream write functions
00772  *****************************************************************************/
00773 
00774 
00787 QDataStream &QDataStream::operator<<( Q_INT8 i )
00788 {
00789     CHECK_STREAM_PRECOND
00790     if ( printable && (i == '\\' || !isprint((uchar) i)) ) {
00791         char buf[6];                            // write octal code
00792         buf[0] = '\\';
00793         buf[1] = '0' + ((i >> 6) & 0x07);
00794         buf[2] = '0' + ((i >> 3) & 0x07);
00795         buf[3] = '0' + (i & 0x07);
00796         buf[4] = '\0';
00797         dev->writeBlock( buf, 4 );
00798     } else {
00799         dev->putch( i );
00800     }
00801     return *this;
00802 }
00803 
00804 
00819 QDataStream &QDataStream::operator<<( Q_INT16 i )
00820 {
00821     CHECK_STREAM_PRECOND
00822     if ( printable ) {                          // printable data
00823         char buf[16];
00824         sprintf( buf, "%d\n", i );
00825         dev->writeBlock( buf, strlen(buf) );
00826     } else if ( noswap ) {                      // no conversion needed
00827         dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
00828     } else {                                    // swap bytes
00829         register uchar *p = (uchar *)(&i);
00830         char b[2];
00831         b[1] = *p++;
00832         b[0] = *p;
00833         dev->writeBlock( b, 2 );
00834     }
00835     return *this;
00836 }
00837 
00845 QDataStream &QDataStream::operator<<( Q_INT32 i )
00846 {
00847     CHECK_STREAM_PRECOND
00848     if ( printable ) {                          // printable data
00849         char buf[16];
00850         sprintf( buf, "%d\n", i );
00851         dev->writeBlock( buf, strlen(buf) );
00852     } else if ( noswap ) {                      // no conversion needed
00853         dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
00854     } else {                                    // swap bytes
00855         register uchar *p = (uchar *)(&i);
00856         char b[4];
00857         b[3] = *p++;
00858         b[2] = *p++;
00859         b[1] = *p++;
00860         b[0] = *p;
00861         dev->writeBlock( b, 4 );
00862     }
00863     return *this;
00864 }
00865 
00880 QDataStream &QDataStream::operator<<( Q_LONG i )
00881 {
00882     CHECK_STREAM_PRECOND
00883     if ( printable ) {                          // printable data
00884         char buf[20];
00885         sprintf( buf, "%ld\n", i );
00886         dev->writeBlock( buf, strlen(buf) );
00887     } else if ( noswap ) {                      // no conversion needed
00888         dev->writeBlock( (char *)&i, sizeof(Q_LONG) );
00889     } else {                                    // swap bytes
00890         register uchar *p = (uchar *)(&i);
00891         char b[sizeof(Q_LONG)];
00892         for ( int j = sizeof(Q_LONG); j;  )
00893             b[--j] = *p++;
00894         dev->writeBlock( b, sizeof(Q_LONG) );
00895     }
00896     return *this;
00897 }
00898 
00913 QDataStream &QDataStream::operator<<( float f )
00914 {
00915     CHECK_STREAM_PRECOND
00916     if ( printable ) {                          // printable data
00917         char buf[32];
00918         sprintf( buf, "%g\n", (double)f );
00919         dev->writeBlock( buf, strlen(buf) );
00920     } else {
00921         float g = f;                            // fixes float-on-stack problem
00922         if ( noswap ) {                         // no conversion needed
00923             dev->writeBlock( (char *)&g, sizeof(float) );
00924         } else {                                // swap bytes
00925             register uchar *p = (uchar *)(&g);
00926             char b[4];
00927             b[3] = *p++;
00928             b[2] = *p++;
00929             b[1] = *p++;
00930             b[0] = *p;
00931             dev->writeBlock( b, 4 );
00932         }
00933     }
00934     return *this;
00935 }
00936 
00937 
00945 QDataStream &QDataStream::operator<<( double f )
00946 {
00947     CHECK_STREAM_PRECOND
00948     if ( printable ) {                          // printable data
00949         char buf[32];
00950         sprintf( buf, "%g\n", f );
00951         dev->writeBlock( buf, strlen(buf) );
00952     } else if ( noswap ) {                      // no conversion needed
00953         dev->writeBlock( (char *)&f, sizeof(double) );
00954     } else {                                    // swap bytes
00955         register uchar *p = (uchar *)(&f);
00956         char b[8];
00957         b[7] = *p++;
00958         b[6] = *p++;
00959         b[5] = *p++;
00960         b[4] = *p++;
00961         b[3] = *p++;
00962         b[2] = *p++;
00963         b[1] = *p++;
00964         b[0] = *p;
00965         dev->writeBlock( b, 8 );
00966     }
00967     return *this;
00968 }
00969 
00970 
00980 QDataStream &QDataStream::operator<<( const char *s )
00981 {
00982     if ( !s ) {
00983         *this << (Q_UINT32)0;
00984         return *this;
00985     }
00986     uint len = qstrlen( s ) + 1;                        // also write null terminator
00987     *this << (Q_UINT32)len;                     // write length specifier
00988     return writeRawBytes( s, len );
00989 }
00990 
00991 
01002 QDataStream &QDataStream::writeBytes(const char *s, uint len)
01003 {
01004     CHECK_STREAM_PRECOND
01005     *this << (Q_UINT32)len;                     // write length specifier
01006     if ( len )
01007         writeRawBytes( s, len );
01008     return *this;
01009 }
01010 
01011 
01019 QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
01020 {
01021     CHECK_STREAM_PRECOND
01022     if ( printable ) {                          // write printable
01023         if ( version() < 4 ) {
01024             register char *p = (char *)s;
01025             while ( len-- )
01026                 *this << *p++;
01027         } else {
01028             register Q_INT8 *p = (Q_INT8*)s;
01029             while ( len-- )
01030                 *this << *p++;
01031         }
01032     } else {                                    // write data char array
01033         dev->writeBlock( s, len );
01034     }
01035     return *this;
01036 }
01037 
01038 #endif // QT_NO_DATASTREAM

Generated on Sat Nov 5 16:18:29 2005 for OPIE by  doxygen 1.4.2