00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
00220
00221
00222
00223
00224
00231 QDataStream::QDataStream()
00232 {
00233 if ( systemWordSize == 0 )
00234 qSysInfo( &systemWordSize, &systemBigEndian );
00235 dev = 0;
00236 owndev = FALSE;
00237 byteorder = BigEndian;
00238 printable = FALSE;
00239 ver = DefaultStreamVersion;
00240 noswap = systemBigEndian;
00241 }
00242
00255 QDataStream::QDataStream( QIODevice *d )
00256 {
00257 if ( systemWordSize == 0 )
00258 qSysInfo( &systemWordSize, &systemBigEndian );
00259 dev = d;
00260 owndev = FALSE;
00261 byteorder = BigEndian;
00262 printable = FALSE;
00263 ver = DefaultStreamVersion;
00264 noswap = systemBigEndian;
00265 }
00266
00286 QDataStream::QDataStream( QByteArray a, int mode )
00287 {
00288 if ( systemWordSize == 0 )
00289 qSysInfo( &systemWordSize, &systemBigEndian );
00290 dev = new QBuffer( a );
00291 ((QBuffer *)dev)->open( mode );
00292 owndev = TRUE;
00293 byteorder = BigEndian;
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
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 )
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 ) {
00503 i = (Q_INT8)dev->getch();
00504 if ( i == '\\' ) {
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 {
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 ) {
00534 i = (Q_INT16)read_int_ascii( this );
00535 } else if ( noswap ) {
00536 dev->readBlock( (char *)&i, sizeof(Q_INT16) );
00537 } else {
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 ) {
00566 i = read_int_ascii( this );
00567 } else if ( noswap ) {
00568 dev->readBlock( (char *)&i, sizeof(Q_INT32) );
00569 } else {
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 ) {
00599 i = read_int_ascii( this );
00600 } else if ( noswap ) {
00601 dev->readBlock( (char *)&i, sizeof(Q_LONG) );
00602 } else {
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 )
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 ) {
00639 f = (float)read_double_ascii( this );
00640 } else if ( noswap ) {
00641 dev->readBlock( (char *)&f, sizeof(float) );
00642 } else {
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 ) {
00667 f = read_double_ascii( this );
00668 } else if ( noswap ) {
00669 dev->readBlock( (char *)&f, sizeof(double) );
00670 } else {
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;
00725 l = (uint)len;
00726 if ( len == 0 || eof() ) {
00727 s = 0;
00728 return *this;
00729 } else {
00730 s = new char[len];
00731 Q_CHECK_PTR( s );
00732 if ( !s )
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 ) {
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 {
00764 dev->readBlock( s, len );
00765 }
00766 return *this;
00767 }
00768
00769
00770
00771
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];
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 ) {
00823 char buf[16];
00824 sprintf( buf, "%d\n", i );
00825 dev->writeBlock( buf, strlen(buf) );
00826 } else if ( noswap ) {
00827 dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
00828 } else {
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 ) {
00849 char buf[16];
00850 sprintf( buf, "%d\n", i );
00851 dev->writeBlock( buf, strlen(buf) );
00852 } else if ( noswap ) {
00853 dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
00854 } else {
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 ) {
00884 char buf[20];
00885 sprintf( buf, "%ld\n", i );
00886 dev->writeBlock( buf, strlen(buf) );
00887 } else if ( noswap ) {
00888 dev->writeBlock( (char *)&i, sizeof(Q_LONG) );
00889 } else {
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 ) {
00917 char buf[32];
00918 sprintf( buf, "%g\n", (double)f );
00919 dev->writeBlock( buf, strlen(buf) );
00920 } else {
00921 float g = f;
00922 if ( noswap ) {
00923 dev->writeBlock( (char *)&g, sizeof(float) );
00924 } else {
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 ) {
00949 char buf[32];
00950 sprintf( buf, "%g\n", f );
00951 dev->writeBlock( buf, strlen(buf) );
00952 } else if ( noswap ) {
00953 dev->writeBlock( (char *)&f, sizeof(double) );
00954 } else {
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;
00987 *this << (Q_UINT32)len;
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;
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 ) {
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 {
01033 dev->writeBlock( s, len );
01034 }
01035 return *this;
01036 }
01037
01038 #endif // QT_NO_DATASTREAM