Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/qtools/qdatastream.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
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 )
145return XXX_BAD_FILE_FORMAT;
146
147 // Read the version
148 Q_INT32 version;
149 s >> version;
150 if ( version < 100 )
151return XXX_BAD_FILE_TOO_OLD;
152 if ( version > 123 )
153return XXX_BAD_FILE_TOO_NEW;
154 if ( version <= 110 )
155s.setVersion(1);
156
157 // Read the data
158 s >> [lots of interesting data];
159 if ( version > 120 )
160s >> [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 ) {\
175qWarning( "QDataStream: No device" );\
176return *this; }
177#else
178#define CHECK_STREAM_PRECOND
179#endif
180
181static int systemWordSize = 0;
182static bool systemBigEndian;
183
184static 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
195QDataStream::QDataStream()
196{
197 if ( systemWordSize == 0 )// get system features
198qSysInfo( &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
213QDataStream::QDataStream( QIODevice *d )
214{
215 if ( systemWordSize == 0 )// get system features
216qSysInfo( &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 QByteArraya;
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
242QDataStream::QDataStream( QByteArray a, int mode )
243{
244 if ( systemWordSize == 0 )// get system features
245qSysInfo( &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
262QDataStream::~QDataStream()
263{
264 if ( owndev )
265delete 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
281void QDataStream::setDevice(QIODevice *d )
282{
283 if ( owndev ) {
284delete dev;
285owndev = 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
295void 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
345void QDataStream::setByteOrder( int bo )
346{
347 byteorder = bo;
348 if ( systemBigEndian )
349noswap = byteorder == BigEndian;
350 else
351noswap = 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
404static Q_INT32 read_int_ascii( QDataStream *s )
405{
406 register int n = 0;
407 char buf[40];
408 while ( TRUE ) {
409buf[n] = s->device()->getch();
410if ( buf[n] == '\n' || n > 38 )// $-terminator
411 break;
412n++;
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
429QDataStream &QDataStream::operator>>( Q_INT8 &i )
430{
431 CHECK_STREAM_PRECOND
432 if ( printable ) {// printable data
433i = (Q_INT8)dev->getch();
434if ( 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
440i = (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
457QDataStream &QDataStream::operator>>( Q_INT16 &i )
458{
459 CHECK_STREAM_PRECOND
460 if ( printable ) {// printable data
461i = (Q_INT16)read_int_ascii( this );
462 } else if ( noswap ) {// no conversion needed
463dev->readBlock( (char *)&i, sizeof(Q_INT16) );
464 } else {// swap bytes
465register uchar *p = (uchar *)(&i);
466char b[2];
467dev->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
486QDataStream &QDataStream::operator>>( Q_INT32 &i )
487{
488 CHECK_STREAM_PRECOND
489 if ( printable ) {// printable data
490i = read_int_ascii( this );
491 } else if ( noswap ) {// no conversion needed
492dev->readBlock( (char *)&i, sizeof(Q_INT32) );
493 } else {// swap bytes
494register uchar *p = (uchar *)(&i);
495char b[4];
496dev->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
516QDataStream &QDataStream::operator>>( Q_INT64 &i )
517{
518 CHECK_STREAM_PRECOND
519 if ( printable ) {// printable data
520i = read_int_ascii( this );
521 } else if ( noswap ) {// no conversion needed
522dev->readBlock( (char *)&i, sizeof(Q_INT64) );
523 } else {// swap bytes
524register uchar *p = (uchar *)(&i);
525char b[sizeof(Q_INT64)];
526dev->readBlock( b, sizeof(Q_INT64) );
527if ( 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
541static double read_double_ascii( QDataStream *s )
542{
543 register int n = 0;
544 char buf[80];
545 while ( TRUE ) {
546buf[n] = s->device()->getch();
547if ( buf[n] == '\n' || n > 78 )// $-terminator
548 break;
549n++;
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
561QDataStream &QDataStream::operator>>( float &f )
562{
563 CHECK_STREAM_PRECOND
564 if ( printable ) {// printable data
565f = (float)read_double_ascii( this );
566 } else if ( noswap ) {// no conversion needed
567dev->readBlock( (char *)&f, sizeof(float) );
568 } else {// swap bytes
569register uchar *p = (uchar *)(&f);
570char b[4];
571dev->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
586QDataStream &QDataStream::operator>>( double &f )
587{
588 CHECK_STREAM_PRECOND
589 if ( printable ) {// printable data
590f = read_double_ascii( this );
591 } else if ( noswap ) {// no conversion needed
592dev->readBlock( (char *)&f, sizeof(double) );
593 } else {// swap bytes
594register uchar *p = (uchar *)(&f);
595char b[8];
596dev->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
618QDataStream &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
641QDataStream &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() ) {
648s = 0;
649return *this;
650 } else {
651s = new char[len];// create char array
652CHECK_PTR( s );
653if ( !s )// no memory
654 return *this;
655return 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
669QDataStream &QDataStream::readRawBytes( char *s, uint len )
670{
671 CHECK_STREAM_PRECOND
672 if ( printable ) {// printable data
673register Q_INT8 *p = (Q_INT8*)s;
674while ( len-- )
675 *this >> *p++;
676 } else {// read data char array
677dev->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
698QDataStream &QDataStream::operator<<( Q_INT8 i )
699{
700 CHECK_STREAM_PRECOND
701 if ( printable && (i == '\\' || !isprint(i)) ) {
702char buf[6];// write octal code
703buf[0] = '\\';
704buf[1] = '0' + ((i >> 6) & 0x07);
705buf[2] = '0' + ((i >> 3) & 0x07);
706buf[3] = '0' + (i & 0x07);
707buf[4] = '\0';
708dev->writeBlock( buf, 4 );
709 } else {
710dev->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
727QDataStream &QDataStream::operator<<( Q_INT16 i )
728{
729 CHECK_STREAM_PRECOND
730 if ( printable ) {// printable data
731char buf[16];
732sprintf( buf, "%d\n", i );
733dev->writeBlock( buf, strlen(buf) );
734 } else if ( noswap ) {// no conversion needed
735dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
736 } else {// swap bytes
737register uchar *p = (uchar *)(&i);
738char b[2];
739b[1] = *p++;
740b[0] = *p;
741dev->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
758QDataStream &QDataStream::operator<<( Q_INT32 i )
759{
760 CHECK_STREAM_PRECOND
761 if ( printable ) {// printable data
762char buf[16];
763sprintf( buf, "%d\n", i );
764dev->writeBlock( buf, strlen(buf) );
765 } else if ( noswap ) {// no conversion needed
766dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
767 } else {// swap bytes
768register uchar *p = (uchar *)(&i);
769char b[4];
770b[3] = *p++;
771b[2] = *p++;
772b[1] = *p++;
773b[0] = *p;
774dev->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
790QDataStream &QDataStream::operator<<( Q_INT64 i )
791{
792 CHECK_STREAM_PRECOND
793 if ( printable ) {// printable data
794char buf[20];
795sprintf( buf, "%ld\n", i );
796dev->writeBlock( buf, strlen(buf) );
797 } else if ( noswap ) {// no conversion needed
798dev->writeBlock( (char *)&i, sizeof(Q_INT64) );
799 } else {// swap bytes
800register uchar *p = (uchar *)(&i);
801char b[sizeof(Q_INT64)];
802if ( sizeof(Q_INT64) == 8 ) {
803 b[7] = *p++;
804 b[6] = *p++;
805 b[5] = *p++;
806 b[4] = *p++;
807}
808b[3] = *p++;
809b[2] = *p++;
810b[1] = *p++;
811b[0] = *p;
812dev->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
836QDataStream &QDataStream::operator<<( float f )
837{
838 CHECK_STREAM_PRECOND
839 if ( printable ) {// printable data
840char buf[32];
841sprintf( buf, "%g\n", (double)f );
842dev->writeBlock( buf, strlen(buf) );
843 } else {
844float g = f;// fixes float-on-stack problem
845if ( 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
866QDataStream &QDataStream::operator<<( double f )
867{
868 CHECK_STREAM_PRECOND
869 if ( printable ) {// printable data
870char buf[32];
871sprintf( buf, "%g\n", f );
872dev->writeBlock( buf, strlen(buf) );
873 } else if ( noswap ) {// no conversion needed
874dev->writeBlock( (char *)&f, sizeof(double) );
875 } else {// swap bytes
876register uchar *p = (uchar *)(&f);
877char b[8];
878b[7] = *p++;
879b[6] = *p++;
880b[5] = *p++;
881b[4] = *p++;
882b[3] = *p++;
883b[2] = *p++;
884b[1] = *p++;
885b[0] = *p;
886dev->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
899QDataStream &QDataStream::operator<<( const char *s )
900{
901 if ( !s ) {
902*this << (Q_UINT32)0;
903return *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
921QDataStream &QDataStream::writeBytes(const char *s, uint len)
922{
923 CHECK_STREAM_PRECOND
924 *this << (Q_UINT32)len;// write length specifier
925 if ( len )
926writeRawBytes( 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
938QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
939{
940 CHECK_STREAM_PRECOND
941 if ( printable ) {// write printable
942register char *p = (char *)s;
943while ( len-- )
944 *this << *p++;
945 } else {// write data char array
946dev->writeBlock( s, len );
947 }
948 return *this;
949}
950
951#endif // QT_NO_DATASTREAM
952

Archive Download this file

Revision: 1322