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