summaryrefslogtreecommitdiff
path: root/qmake/tools/qtextstream.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qtextstream.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qtextstream.cpp2593
1 files changed, 2593 insertions, 0 deletions
diff --git a/qmake/tools/qtextstream.cpp b/qmake/tools/qtextstream.cpp
new file mode 100644
index 0000000..75c6531
--- a/dev/null
+++ b/qmake/tools/qtextstream.cpp
@@ -0,0 +1,2593 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QTextStream class
5**
6** Created : 940922
7**
8** Copyright (C) 1992-2002 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 "qtextstream.h"
39
40#ifndef QT_NO_TEXTSTREAM
41#include "qtextcodec.h"
42#include "qregexp.h"
43#include "qbuffer.h"
44#include "qfile.h"
45#include <stdio.h>
46#include <ctype.h>
47#include <stdlib.h>
48
49#if defined(Q_OS_WIN32)
50#include <windows.h>
51#endif
52
53/*!
54 \class QTextStream qtextstream.h
55 \reentrant
56 \brief The QTextStream class provides basic functions for reading
57 and writing text using a QIODevice.
58
59 \ingroup io
60 \ingroup text
61 \mainclass
62
63 The text stream class has a functional interface that is very
64 similar to that of the standard C++ iostream class.
65
66 Qt provides several global functions similar to the ones in iostream:
67 \table
68 \header \i Function \i Meaning
69 \row \i bin \i sets the QTextStream to read/write binary numbers
70 \row \i oct \i sets the QTextStream to read/write octal numbers
71 \row \i dec \i sets the QTextStream to read/write decimal numbers
72 \row \i hex \i sets the QTextStream to read/write hexadecimal numbers
73 \row \i endl \i forces a line break
74 \row \i flush \i forces the QIODevice to flush any buffered data
75 \row \i ws \i eats any available whitespace (on input)
76 \row \i reset \i resets the QTextStream to its default mode (see reset())
77 \row \i qSetW(int) \i sets the \link width() field width \endlink
78 to the given argument
79 \row \i qSetFill(int) \i sets the \link fill() fill character
80 \endlink to the given argument
81 \row \i qSetPrecision(int) \i sets the \link precision() precision
82 \endlink to the given argument
83 \endtable
84
85 \warning By default QTextStream will automatically detect whether
86 integers in the stream are in decimal, octal, hexadecimal or
87 binary format when reading from the stream. In particular, a
88 leading '0' signifies octal, i.e. the sequence "0100" will be
89 interpreted as 64.
90
91 The QTextStream class reads and writes text; it is not appropriate
92 for dealing with binary data (but QDataStream is).
93
94 By default, output of Unicode text (i.e. QString) is done using
95 the local 8-bit encoding. This can be changed using the
96 setEncoding() method. For input, the QTextStream will auto-detect
97 standard Unicode "byte order marked" text files; otherwise the
98 local 8-bit encoding is used.
99
100 The QIODevice is set in the constructor, or later using
101 setDevice(). If the end of the input is reached atEnd() returns
102 TRUE. Data can be read into variables of the appropriate type
103 using the operator>>() overloads, or read in its entirety into a
104 single string using read(), or read a line at a time using
105 readLine(). Whitespace can be skipped over using skipWhiteSpace().
106 You can set flags for the stream using flags() or setf(). The
107 stream also supports width(), precision() and fill(); use reset()
108 to reset the defaults.
109
110 \sa QDataStream
111*/
112
113/*!
114 \enum QTextStream::Encoding
115
116 \value Locale
117 \value Latin1
118 \value Unicode
119 \value UnicodeNetworkOrder
120 \value UnicodeReverse
121 \value RawUnicode
122 \value UnicodeUTF8
123
124 See setEncoding() for an explanation of the encodings.
125*/
126
127/*
128 \class QTSManip
129
130 \brief The QTSManip class is an internal helper class for the
131 QTextStream.
132
133 It is generally a very bad idea to use this class directly in
134 application programs.
135
136 \internal
137
138 This class makes it possible to give the QTextStream function objects
139 with arguments, like this:
140 \code
141 QTextStream cout( stdout, IO_WriteOnly );
142 cout << setprecision( 8 ); // QTSManip used here!
143 cout << 3.14159265358979323846;
144 \endcode
145
146 The setprecision() function returns a QTSManip object.
147 The QTSManip object contains a pointer to a member function in
148 QTextStream and an integer argument.
149 When serializing a QTSManip into a QTextStream, the function
150 is executed with the argument.
151*/
152
153/*! \fn QTSManip::QTSManip( QTSMFI m, int a )
154
155 Constructs a QTSManip object which will call \a m (a member function
156 in QTextStream which accepts a single int) with argument \a a when
157 QTSManip::exec() is called. Used internally in e.g. endl:
158
159 \code
160 s << "some text" << endl << "more text";
161 \endcode
162*/
163
164/*! \fn void QTSManip::exec( QTextStream& s )
165
166 Calls the member function specified in the constructor, for object
167 \a s. Used internally in e.g. endl:
168
169 \code
170 s << "some text" << endl << "more text";
171 \endcode
172*/
173
174
175/*****************************************************************************
176 QTextStream member functions
177 *****************************************************************************/
178
179#if defined(QT_CHECK_STATE)
180#undef CHECK_STREAM_PRECOND
181 #define CHECK_STREAM_PRECOND if ( !dev ) { \
182 qWarning( "QTextStream: No device" );\
183 return *this; }
184#else
185#define CHECK_STREAM_PRECOND
186#endif
187
188
189 #define I_SHORT 0x0010
190 #define I_INT 0x0020
191 #define I_LONG 0x0030
192 #define I_TYPE_MASK0x00f0
193
194 #define I_BASE_2QTS::bin
195 #define I_BASE_8QTS::oct
196 #define I_BASE_10QTS::dec
197 #define I_BASE_16QTS::hex
198 #define I_BASE_MASK(QTS::bin | QTS::oct | QTS::dec | QTS::hex)
199
200 #define I_SIGNED0x0100
201 #define I_UNSIGNED0x0200
202 #define I_SIGN_MASK0x0f00
203
204
205static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.
206static const uint getline_buf_size = 256; // bufsize used by ts_getline()
207
208const int QTextStream::basefield = I_BASE_MASK;
209const int QTextStream::adjustfield = ( QTextStream::left |
210 QTextStream::right |
211 QTextStream::internal );
212const int QTextStream::floatfield = ( QTextStream::scientific |
213 QTextStream::fixed );
214
215
216class QTextStreamPrivate {
217public:
218#ifndef QT_NO_TEXTCODEC
219 QTextStreamPrivate()
220 : decoder( 0 ), encoder( 0 ), sourceType( NotSet ) { }
221 ~QTextStreamPrivate() {
222 delete decoder;
223 delete encoder;
224 }
225 QTextDecoder *decoder;
226 QTextEncoder *encoder;
227#else
228 QTextStreamPrivate() : sourceType( NotSet ) { }
229 ~QTextStreamPrivate() { }
230#endif
231 QString ungetcBuf;
232
233 enum SourceType { NotSet, IODevice, String, ByteArray, File };
234 SourceType sourceType;
235};
236
237
238// skips whitespace and returns the first non-whitespace character
239QChar QTextStream::eat_ws()
240{
241 QChar c;
242 do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );
243 return c;
244}
245
246void QTextStream::init()
247{
248 // ### ungetcBuf = QEOF;
249 dev = 0;
250 owndev = FALSE;
251 mapper = 0;
252 d = new QTextStreamPrivate;
253 doUnicodeHeader = TRUE; // autodetect
254 latin1 = TRUE; // should use locale?
255 internalOrder = QChar::networkOrdered();
256 networkOrder = TRUE;
257}
258
259/*!
260 Constructs a data stream that has no IO device.
261*/
262
263QTextStream::QTextStream()
264{
265 init();
266 setEncoding( Locale ); //###
267 reset();
268 d->sourceType = QTextStreamPrivate::NotSet;
269}
270
271/*!
272 Constructs a text stream that uses the IO device \a iod.
273*/
274
275QTextStream::QTextStream( QIODevice *iod )
276{
277 init();
278 setEncoding( Locale ); //###
279 dev = iod;
280 reset();
281 d->sourceType = QTextStreamPrivate::IODevice;
282}
283
284// TODO: use special-case handling of this case in QTextStream, and
285 // simplify this class to only deal with QChar or QString data.
286class QStringBuffer : public QIODevice {
287public:
288 QStringBuffer( QString* str );
289 ~QStringBuffer();
290 bool open( int m );
291 void close();
292 void flush();
293 Offset size() const;
294 Offset at() const;
295 bool at( Offset pos );
296 Q_LONG readBlock( char *p, Q_ULONG len );
297 Q_LONG writeBlock( const char *p, Q_ULONG len );
298 int getch();
299 int putch( int ch );
300 int ungetch( int ch );
301protected:
302 QString* s;
303
304private: // Disabled copy constructor and operator=
305 QStringBuffer( const QStringBuffer & );
306 QStringBuffer &operator=( const QStringBuffer & );
307};
308
309
310QStringBuffer::QStringBuffer( QString* str )
311{
312 s = str;
313}
314
315QStringBuffer::~QStringBuffer()
316{
317}
318
319
320bool QStringBuffer::open( int m )
321{
322 if ( !s ) {
323#if defined(QT_CHECK_STATE)
324 qWarning( "QStringBuffer::open: No string" );
325#endif
326 return FALSE;
327 }
328 if ( isOpen() ) { // buffer already open
329#if defined(QT_CHECK_STATE)
330 qWarning( "QStringBuffer::open: Buffer already open" );
331#endif
332 return FALSE;
333 }
334 setMode( m );
335 if ( m & IO_Truncate ) { // truncate buffer
336 s->truncate( 0 );
337 }
338 if ( m & IO_Append ) { // append to end of buffer
339 ioIndex = s->length()*sizeof(QChar);
340 } else {
341 ioIndex = 0;
342 }
343 setState( IO_Open );
344 setStatus( 0 );
345 return TRUE;
346}
347
348void QStringBuffer::close()
349{
350 if ( isOpen() ) {
351 setFlags( IO_Direct );
352 ioIndex = 0;
353 }
354}
355
356void QStringBuffer::flush()
357{
358}
359
360QIODevice::Offset QStringBuffer::size() const
361{
362 return s ? s->length()*sizeof(QChar) : 0;
363}
364
365QIODevice::Offset QStringBuffer::at() const
366{
367 return ioIndex;
368}
369
370bool QStringBuffer::at( Offset pos )
371{
372#if defined(QT_CHECK_STATE)
373 if ( !isOpen() ) {
374 qWarning( "QStringBuffer::at: Buffer is not open" );
375 return FALSE;
376 }
377#endif
378 if ( pos >= s->length()*2 ) {
379#if defined(QT_CHECK_RANGE)
380#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
381 qWarning( "QStringBuffer::at: Index %llu out of range", pos );
382#else
383 qWarning( "QStringBuffer::at: Index %lu out of range", pos );
384#endif
385#endif
386 return FALSE;
387 }
388 ioIndex = pos;
389 return TRUE;
390}
391
392
393Q_LONG QStringBuffer::readBlock( char *p, Q_ULONG len )
394{
395#if defined(QT_CHECK_STATE)
396 Q_CHECK_PTR( p );
397 if ( !isOpen() ) { // buffer not open
398 qWarning( "QStringBuffer::readBlock: Buffer not open" );
399 return -1;
400 }
401 if ( !isReadable() ) { // reading not permitted
402 qWarning( "QStringBuffer::readBlock: Read operation not permitted" );
403 return -1;
404 }
405#endif
406 if ( ioIndex + len > s->length()*sizeof(QChar) ) {
407 // overflow
408 if ( (uint)ioIndex >= s->length()*sizeof(QChar) ) {
409 setStatus( IO_ReadError );
410 return -1;
411 } else {
412 len = s->length()*2 - (uint)ioIndex;
413 }
414 }
415 memcpy( p, ((const char*)(s->unicode()))+ioIndex, len );
416 ioIndex += len;
417 return len;
418}
419
420Q_LONG QStringBuffer::writeBlock( const char *p, Q_ULONG len )
421{
422#if defined(QT_CHECK_NULL)
423 if ( p == 0 && len != 0 )
424 qWarning( "QStringBuffer::writeBlock: Null pointer error" );
425#endif
426#if defined(QT_CHECK_STATE)
427 if ( !isOpen() ) { // buffer not open
428 qWarning( "QStringBuffer::writeBlock: Buffer not open" );
429 return -1;
430 }
431 if ( !isWritable() ) { // writing not permitted
432 qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );
433 return -1;
434 }
435 if ( ioIndex&1 ) {
436 qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );
437 return -1;
438 }
439 if ( len&1 ) {
440 qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );
441 return -1;
442 }
443#endif
444 s->replace(ioIndex/2, len/2, (QChar*)p, len/2);
445 ioIndex += len;
446 return len;
447}
448
449int QStringBuffer::getch()
450{
451#if defined(QT_CHECK_STATE)
452 if ( !isOpen() ) { // buffer not open
453 qWarning( "QStringBuffer::getch: Buffer not open" );
454 return -1;
455 }
456 if ( !isReadable() ) { // reading not permitted
457 qWarning( "QStringBuffer::getch: Read operation not permitted" );
458 return -1;
459 }
460#endif
461 if ( (uint)ioIndex >= s->length()*2 ) { // overflow
462 setStatus( IO_ReadError );
463 return -1;
464 }
465 return (int) *( (const char *) s->unicode() + ioIndex++ );
466}
467
468int QStringBuffer::putch( int ch )
469{
470 char c = ch;
471 if ( writeBlock(&c,1) < 0 )
472 return -1;
473 else
474 return ch;
475}
476
477int QStringBuffer::ungetch( int ch )
478{
479#if defined(QT_CHECK_STATE)
480 if ( !isOpen() ) { // buffer not open
481 qWarning( "QStringBuffer::ungetch: Buffer not open" );
482 return -1;
483 }
484 if ( !isReadable() ) { // reading not permitted
485 qWarning( "QStringBuffer::ungetch: Read operation not permitted" );
486 return -1;
487 }
488#endif
489 if ( ch != -1 ) { // something to do with eof
490 if ( ioIndex )
491 ioIndex--;
492 else
493 ch = -1;
494 }
495 return ch;
496}
497
498
499/*!
500 Constructs a text stream that operates on the Unicode QString, \a
501 str, through an internal device. The \a filemode argument is
502 passed to the device's open() function; see \l{QIODevice::mode()}.
503
504 If you set an encoding or codec with setEncoding() or setCodec(),
505 this setting is ignored for text streams that operate on QString.
506
507 Example:
508 \code
509 QString str;
510 QTextStream ts( &str, IO_WriteOnly );
511 ts << "pi = " << 3.14; // str == "pi = 3.14"
512 \endcode
513
514 Writing data to the text stream will modify the contents of the
515 string. The string will be expanded when data is written beyond
516 the end of the string. Note that the string will not be truncated:
517 \code
518 QString str = "pi = 3.14";
519 QTextStream ts( &str, IO_WriteOnly );
520 ts << "2+2 = " << 2+2; // str == "2+2 = 414"
521 \endcode
522
523 Note that because QString is Unicode, you should not use
524 readRawBytes() or writeRawBytes() on such a stream.
525*/
526
527QTextStream::QTextStream( QString* str, int filemode )
528{
529 // TODO: optimize for this case as it becomes more common
530 // (see QStringBuffer above)
531 init();
532 dev = new QStringBuffer( str );
533 ((QStringBuffer *)dev)->open( filemode );
534 owndev = TRUE;
535 setEncoding(RawUnicode);
536 reset();
537 d->sourceType = QTextStreamPrivate::String;
538}
539
540/*! \obsolete
541
542 This constructor is equivalent to the constructor taking a QString*
543 parameter.
544*/
545
546QTextStream::QTextStream( QString& str, int filemode )
547{
548 init();
549 dev = new QStringBuffer( &str );
550 ((QStringBuffer *)dev)->open( filemode );
551 owndev = TRUE;
552 setEncoding(RawUnicode);
553 reset();
554 d->sourceType = QTextStreamPrivate::String;
555}
556
557/*!
558 Constructs a text stream that operates on the byte array, \a a,
559 through an internal QBuffer device. The \a mode argument is passed
560 to the device's open() function; see \l{QIODevice::mode()}.
561
562 Example:
563 \code
564 QByteArray array;
565 QTextStream ts( array, IO_WriteOnly );
566 ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
567 \endcode
568
569 Writing data to the text stream will modify the contents of the
570 array. The array will be expanded when data is written beyond the
571 end of the string.
572
573 Same example, using a QBuffer:
574 \code
575 QByteArray array;
576 QBuffer buf( array );
577 buf.open( IO_WriteOnly );
578 QTextStream ts( &buf );
579 ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
580 buf.close();
581 \endcode
582*/
583
584QTextStream::QTextStream( QByteArray a, int mode )
585{
586 init();
587 dev = new QBuffer( a );
588 ((QBuffer *)dev)->open( mode );
589 owndev = TRUE;
590 setEncoding( Latin1 ); //### Locale???
591 reset();
592 d->sourceType = QTextStreamPrivate::ByteArray;
593}
594
595/*!
596 Constructs a text stream that operates on an existing file handle
597 \a fh through an internal QFile device. The \a mode argument is
598 passed to the device's open() function; see \l{QIODevice::mode()}.
599
600 Note that if you create a QTextStream \c cout or another name that
601 is also used for another variable of a different type, some
602 linkers may confuse the two variables, which will often cause
603 crashes.
604*/
605
606QTextStream::QTextStream( FILE *fh, int mode )
607{
608 init();
609 setEncoding( Locale ); //###
610 dev = new QFile;
611 ((QFile *)dev)->open( mode, fh );
612 owndev = TRUE;
613 reset();
614 d->sourceType = QTextStreamPrivate::File;
615}
616
617/*!
618 Destroys the text stream.
619
620 The destructor does not affect the current IO device.
621*/
622
623QTextStream::~QTextStream()
624{
625 if ( owndev )
626 delete dev;
627 delete d;
628}
629
630/*!
631 Positions the read pointer at the first non-whitespace character.
632*/
633void QTextStream::skipWhiteSpace()
634{
635 ts_ungetc( eat_ws() );
636}
637
638
639/*!
640 Tries to read \a len characters from the stream and stores them in
641 \a buf. Returns the number of characters really read.
642
643 \warning There will no QEOF appended if the read reaches the end
644 of the file. EOF is reached when the return value does not equal
645 \a len.
646*/
647uint QTextStream::ts_getbuf( QChar* buf, uint len )
648{
649 if( len < 1 )
650 return 0;
651
652 uint rnum=0; // the number of QChars really read
653
654 if ( d && d->ungetcBuf.length() ) {
655 while( rnum < len && rnum < d->ungetcBuf.length() ) {
656 *buf = d->ungetcBuf.constref( rnum );
657 buf++;
658 rnum++;
659 }
660 d->ungetcBuf = d->ungetcBuf.mid( rnum );
661 if ( rnum >= len )
662 return rnum;
663 }
664
665 // we use dev->ungetch() for one of the bytes of the unicode
666 // byte-order mark, but a local unget hack for the other byte:
667 int ungetHack = EOF;
668
669 if ( doUnicodeHeader ) {
670 doUnicodeHeader = FALSE; // only at the top
671 int c1 = dev->getch();
672 if ( c1 == EOF )
673 return rnum;
674 int c2 = dev->getch();
675 if ( c1 == 0xfe && c2 == 0xff ) {
676 mapper = 0;
677 latin1 = FALSE;
678 internalOrder = QChar::networkOrdered();
679 networkOrder = TRUE;
680 } else if ( c1 == 0xff && c2 == 0xfe ) {
681 mapper = 0;
682 latin1 = FALSE;
683 internalOrder = !QChar::networkOrdered();
684 networkOrder = FALSE;
685 } else {
686 if ( c2 != EOF ) {
687 dev->ungetch( c2 );
688 ungetHack = c1;
689 } else {
690 /*
691 A small bug might hide here. If only the first byte
692 of a file has made it so far, and that first byte
693 is half of the byte-order mark, then the utfness
694 will not be detected.
695 */
696 dev->ungetch( c1 );
697 }
698 }
699 }
700
701#ifndef QT_NO_TEXTCODEC
702 if ( mapper ) {
703 bool shortRead = FALSE;
704 if ( !d->decoder )
705 d->decoder = mapper->makeDecoder();
706 while( rnum < len ) {
707 QString s;
708 bool readBlock = !( len == 1+rnum );
709 for (;;) {
710 // for efficiency: normally read a whole block
711 if ( readBlock ) {
712 // guess buffersize; this may be wrong (too small or too
713 // big). But we can handle this (either iterate reading
714 // or use ungetcBuf).
715 // Note that this might cause problems for codecs where
716 // one byte can result in >1 Unicode Characters if bytes
717 // are written to the stream in the meantime (loss of
718 // synchronicity).
719 uint rlen = len - rnum;
720 char *cbuf = new char[ rlen ];
721 if ( ungetHack != EOF ) {
722 rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
723 cbuf[0] = (char)ungetHack;
724 ungetHack = EOF;
725 } else {
726 rlen = dev->readBlock( cbuf, rlen );
727 }
728 s += d->decoder->toUnicode( cbuf, rlen );
729 delete[] cbuf;
730 // use buffered reading only for the first time, because we
731 // have to get the stream synchronous again (this is easier
732 // with single character reading)
733 readBlock = FALSE;
734 }
735 // get stream (and codec) in sync
736 int c;
737 if ( ungetHack == EOF ) {
738 c = dev->getch();
739 } else {
740 c = ungetHack;
741 ungetHack = EOF;
742 }
743 if ( c == EOF ) {
744 shortRead = TRUE;
745 break;
746 }
747 char b = c;
748 uint lengthBefore = s.length();
749 s += d->decoder->toUnicode( &b, 1 );
750 if ( s.length() > lengthBefore )
751 break; // it seems we are in sync now
752 }
753 uint i = 0;
754 uint end = QMIN( len-rnum, s.length() );
755 while( i < end ) {
756 *buf = s.constref(i++);
757 buf++;
758 }
759 rnum += end;
760 if ( s.length() > i )
761 // could be = but append is clearer
762 d->ungetcBuf.append( s.mid( i ) );
763 if ( shortRead )
764 return rnum;
765 }
766 } else
767#endif
768 if ( latin1 ) {
769 if ( len == 1+rnum ) {
770 // use this method for one character because it is more efficient
771 // (arnt doubts whether it makes a difference, but lets it stand)
772 int c = (ungetHack == EOF) ? dev->getch() : ungetHack;
773 if ( c != EOF ) {
774 *buf = (char)c;
775 buf++;
776 rnum++;
777 }
778 } else {
779 if ( ungetHack != EOF ) {
780 *buf = (char)ungetHack;
781 buf++;
782 rnum++;
783 ungetHack = EOF;
784 }
785 char *cbuf = new char[len - rnum];
786 while ( !dev->atEnd() && rnum < len ) {
787 uint rlen = len - rnum;
788 rlen = dev->readBlock( cbuf, rlen );
789 char *it = cbuf;
790 char *end = cbuf + rlen;
791 while ( it < end ) {
792 *buf = *it;
793 buf++;
794 it++;
795 }
796 rnum += rlen;
797 }
798 delete[] cbuf;
799 }
800 } else { // UCS-2 or UTF-16
801 if ( len == 1+rnum ) {
802 int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;
803 if ( c1 == EOF )
804 return rnum;
805 int c2 = dev->getch();
806 if ( c2 == EOF )
807 return rnum;
808
809 if ( networkOrder ) {
810 *buf = QChar( c2, c1 );
811 } else {
812 *buf = QChar( c1, c2 );
813 }
814 buf++;
815 rnum++;
816 } else {
817 char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
818 while ( !dev->atEnd() && rnum < len ) {
819 uint rlen = 2 * ( len-rnum );
820 if ( ungetHack != EOF ) {
821 rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
822 cbuf[0] = (char)ungetHack;
823 ungetHack = EOF;
824 } else {
825 rlen = dev->readBlock( cbuf, rlen );
826 }
827 // We can't use an odd number of bytes, so put it back. But
828 // do it only if we are capable of reading more -- normally
829 // there should not be an odd number, but the file might be
830 // truncated or not in UTF-16...
831 if ( (rlen & 1) == 1 )
832 if ( !dev->atEnd() )
833 dev->ungetch( cbuf[--rlen] );
834 uint i = 0;
835 if ( networkOrder ) {
836 while( i < rlen ) {
837 *buf = QChar( cbuf[i+1], cbuf[i] );
838 buf++;
839 i+=2;
840 }
841 } else {
842 while( i < rlen ) {
843 *buf = QChar( cbuf[i], cbuf[i+1] );
844 buf++;
845 i+=2;
846 }
847 }
848 rnum += i/2;
849 }
850 delete[] cbuf;
851 }
852 }
853 return rnum;
854}
855
856/*!
857 Tries to read one line, but at most len characters from the stream
858 and stores them in \a buf.
859
860 Returns the number of characters really read. Newlines are not
861 stripped.
862
863 There will be a QEOF appended if the read reaches the end of file;
864 this is different to ts_getbuf().
865
866 This function works only if a newline (as byte) is also a newline
867 (as resulting character) since it uses QIODevice::readLine(). So
868 use it only for such codecs where this is true!
869
870 This function is (almost) a no-op for UTF 16. Don't use it if
871 doUnicodeHeader is TRUE!
872*/
873uint QTextStream::ts_getline( QChar* buf )
874{
875 uint rnum=0; // the number of QChars really read
876 char cbuf[ getline_buf_size+1 ];
877
878 if ( d && d->ungetcBuf.length() ) {
879 while( rnum < getline_buf_size && rnum < d->ungetcBuf.length() ) {
880 buf[rnum] = d->ungetcBuf.constref(rnum);
881 rnum++;
882 }
883 d->ungetcBuf = d->ungetcBuf.mid( rnum );
884 if ( rnum >= getline_buf_size )
885 return rnum;
886 }
887
888#ifndef QT_NO_TEXTCODEC
889 if ( mapper ) {
890 if ( !d->decoder )
891 d->decoder = mapper->makeDecoder();
892 QString s;
893 bool readBlock = TRUE;
894 for (;;) {
895 // for efficiency: try to read a line
896 if ( readBlock ) {
897 int rlen = getline_buf_size - rnum;
898 rlen = dev->readLine( cbuf, rlen+1 );
899 if ( rlen == -1 )
900 rlen = 0;
901 s += d->decoder->toUnicode( cbuf, rlen );
902 readBlock = FALSE;
903 }
904 if ( dev->atEnd()
905 || s.at( s.length()-1 ) == '\n'
906 || s.at( s.length()-1 ) == '\r'
907 ) {
908 break;
909 } else {
910 // get stream (and codec) in sync
911 int c;
912 c = dev->getch();
913 if ( c == EOF ) {
914 break;
915 }
916 char b = c;
917 uint lengthBefore = s.length();
918 s += d->decoder->toUnicode( &b, 1 );
919 if ( s.length() > lengthBefore )
920 break; // it seems we are in sync now
921 }
922 }
923 uint i = 0;
924 while( rnum < getline_buf_size && i < s.length() )
925 buf[rnum++] = s.constref(i++);
926 if ( s.length() > i )
927 // could be = but append is clearer
928 d->ungetcBuf.append( s.mid( i ) );
929 if ( rnum < getline_buf_size && dev->atEnd() )
930 buf[rnum++] = QEOF;
931 } else
932#endif
933 if ( latin1 ) {
934 int rlen = getline_buf_size - rnum;
935 rlen = dev->readLine( cbuf, rlen+1 );
936 if ( rlen == -1 )
937 rlen = 0;
938 char *end = cbuf+rlen;
939 char *it = cbuf;
940 buf +=rnum;
941 while ( it != end ) {
942 buf->setCell( *(it++) );
943 buf->setRow( 0 );
944 buf++;
945 }
946 rnum += rlen;
947 if ( rnum < getline_buf_size && dev->atEnd() )
948 buf[1] = QEOF;
949 }
950 return rnum;
951}
952
953
954/*!
955 Puts one character into the stream.
956*/
957void QTextStream::ts_putc( QChar c )
958{
959#ifndef QT_NO_TEXTCODEC
960 if ( mapper ) {
961 if ( !d->encoder )
962 d->encoder = mapper->makeEncoder();
963 int len = 1;
964 QString s = c;
965 QCString block = d->encoder->fromUnicode( s, len );
966 dev->writeBlock( block, len );
967 } else
968#endif
969 if ( latin1 ) {
970 if ( c.row() )
971 dev->putch( '?' ); // unknown character
972 else
973 dev->putch( c.cell() );
974 } else {
975 if ( doUnicodeHeader ) {
976 doUnicodeHeader = FALSE;
977 ts_putc( QChar::byteOrderMark );
978 }
979 if ( internalOrder ) {
980 // this case is needed by QStringBuffer
981 dev->writeBlock( (char*)&c, sizeof(QChar) );
982 } else if ( networkOrder ) {
983 dev->putch( c.row() );
984 dev->putch( c.cell() );
985 } else {
986 dev->putch( c.cell() );
987 dev->putch( c.row() );
988 }
989 }
990}
991
992/*!
993 Puts one character into the stream.
994*/
995void QTextStream::ts_putc( int ch )
996{
997 ts_putc( QChar((ushort)ch) );
998}
999
1000bool QTextStream::ts_isdigit( QChar c )
1001{
1002 return c.isDigit();
1003}
1004
1005bool QTextStream::ts_isspace( QChar c )
1006{
1007 return c.isSpace();
1008}
1009
1010void QTextStream::ts_ungetc( QChar c )
1011{
1012 if ( c.unicode() == 0xffff )
1013 return;
1014
1015 d->ungetcBuf.prepend( c );
1016}
1017
1018
1019
1020/*!
1021 Reads \a len bytes from the stream into \a s and returns a
1022 reference to the stream.
1023
1024 The buffer \a s must be preallocated.
1025
1026 Note that no encoding is done by this function.
1027
1028 \warning The behavior of this function is undefined unless the
1029 stream's encoding is set to Unicode or Latin1.
1030
1031 \sa QIODevice::readBlock()
1032*/
1033
1034QTextStream &QTextStream::readRawBytes( char *s, uint len )
1035{
1036 dev->readBlock( s, len );
1037 return *this;
1038}
1039
1040/*!
1041 Writes the \a len bytes from \a s to the stream and returns a
1042 reference to the stream.
1043
1044 Note that no encoding is done by this function.
1045
1046 \sa QIODevice::writeBlock()
1047*/
1048
1049QTextStream &QTextStream::writeRawBytes( const char* s, uint len )
1050{
1051 dev->writeBlock( s, len );
1052 return *this;
1053}
1054
1055
1056QTextStream &QTextStream::writeBlock( const char* p, uint len )
1057{
1058 if ( doUnicodeHeader ) {
1059 doUnicodeHeader = FALSE;
1060 if ( !mapper && !latin1 )
1061 ts_putc( QChar::byteOrderMark );
1062 }
1063 // QCString and const char * are treated as Latin-1
1064 if ( !mapper && latin1 ) {
1065 dev->writeBlock( p, len );
1066 } else if ( !mapper && internalOrder ) {
1067 QChar *u = new QChar[len];
1068 for ( uint i = 0; i < len; i++ )
1069 u[i] = p[i];
1070 dev->writeBlock( (char*)u, len * sizeof(QChar) );
1071 delete [] u;
1072 } else {
1073 for ( uint i = 0; i < len; i++ )
1074 ts_putc( (uchar)p[i] );
1075 }
1076 return *this;
1077}
1078
1079QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
1080{
1081#ifndef QT_NO_TEXTCODEC
1082 if ( mapper ) {
1083 if ( !d->encoder )
1084 d->encoder = mapper->makeEncoder();
1085 QConstString s( p, len );
1086 int l = len;
1087 QCString block = d->encoder->fromUnicode( s.string(), l );
1088 dev->writeBlock( block, l );
1089 } else
1090#endif
1091 if ( latin1 ) {
1092 char *str = QString::unicodeToAscii( p, len );
1093 dev->writeBlock( str, len );
1094 delete [] str;
1095 } else if ( internalOrder ) {
1096 if ( doUnicodeHeader ) {
1097 doUnicodeHeader = FALSE;
1098 ts_putc( QChar::byteOrderMark );
1099 }
1100 dev->writeBlock( (char*)p, sizeof(QChar)*len );
1101 } else {
1102 for (uint i=0; i<len; i++)
1103 ts_putc( p[i] );
1104 }
1105 return *this;
1106}
1107
1108/*!
1109 Resets the text stream.
1110
1111 \list
1112 \i All flags are set to 0.
1113 \i The field width is set to 0.
1114 \i The fill character is set to ' ' (Space).
1115 \i The precision is set to 6.
1116 \endlist
1117
1118 \sa setf(), width(), fill(), precision()
1119*/
1120
1121void QTextStream::reset()
1122{
1123 fflags = 0;
1124 fwidth = 0;
1125 fillchar = ' ';
1126 fprec = 6;
1127}
1128
1129/*!
1130 \fn QIODevice *QTextStream::device() const
1131
1132 Returns the IO device currently set.
1133
1134 \sa setDevice(), unsetDevice()
1135*/
1136
1137/*!
1138 Sets the IO device to \a iod.
1139
1140 \sa device(), unsetDevice()
1141*/
1142
1143void QTextStream::setDevice( QIODevice *iod )
1144{
1145 if ( owndev ) {
1146 delete dev;
1147 owndev = FALSE;
1148 }
1149 dev = iod;
1150 d->sourceType = QTextStreamPrivate::IODevice;
1151}
1152
1153/*!
1154 Unsets the IO device. Equivalent to setDevice( 0 ).
1155
1156 \sa device(), setDevice()
1157*/
1158
1159void QTextStream::unsetDevice()
1160{
1161 setDevice( 0 );
1162 d->sourceType = QTextStreamPrivate::NotSet;
1163}
1164
1165/*!
1166 \fn bool QTextStream::atEnd() const
1167
1168 Returns TRUE if the IO device has reached the end position (end of
1169 the stream or file) or if there is no IO device set; otherwise
1170 returns FALSE.
1171
1172 \sa QIODevice::atEnd()
1173*/
1174
1175/*!\fn bool QTextStream::eof() const
1176
1177 \obsolete
1178
1179 This function has been renamed to atEnd().
1180
1181 \sa QIODevice::atEnd()
1182*/
1183
1184/*****************************************************************************
1185 QTextStream read functions
1186 *****************************************************************************/
1187
1188
1189/*!
1190 \overload
1191
1192 Reads a char \a c from the stream and returns a reference to the
1193 stream. Note that whitespace is skipped.
1194*/
1195
1196QTextStream &QTextStream::operator>>( char &c )
1197{
1198 CHECK_STREAM_PRECOND
1199 c = eat_ws();
1200 return *this;
1201}
1202
1203/*!
1204 Reads a char \a c from the stream and returns a reference to the
1205 stream. Note that whitespace is \e not skipped.
1206*/
1207
1208QTextStream &QTextStream::operator>>( QChar &c )
1209{
1210 CHECK_STREAM_PRECOND
1211 c = ts_getc();
1212 return *this;
1213}
1214
1215
1216ulong QTextStream::input_bin()
1217{
1218 ulong val = 0;
1219 QChar ch = eat_ws();
1220 int dv = ch.digitValue();
1221 while ( dv == 0 || dv == 1 ) {
1222 val = ( val << 1 ) + dv;
1223 ch = ts_getc();
1224 dv = ch.digitValue();
1225 }
1226 if ( ch != QEOF )
1227 ts_ungetc( ch );
1228 return val;
1229}
1230
1231ulong QTextStream::input_oct()
1232{
1233 ulong val = 0;
1234 QChar ch = eat_ws();
1235 int dv = ch.digitValue();
1236 while ( dv >= 0 && dv <= 7 ) {
1237 val = ( val << 3 ) + dv;
1238 ch = ts_getc();
1239 dv = ch.digitValue();
1240 }
1241 if ( dv == 8 || dv == 9 ) {
1242 while ( ts_isdigit(ch) )
1243 ch = ts_getc();
1244 }
1245 if ( ch != QEOF )
1246 ts_ungetc( ch );
1247 return val;
1248}
1249
1250ulong QTextStream::input_dec()
1251{
1252 ulong val = 0;
1253 QChar ch = eat_ws();
1254 int dv = ch.digitValue();
1255 while ( ts_isdigit(ch) ) {
1256 val = val * 10 + dv;
1257 ch = ts_getc();
1258 dv = ch.digitValue();
1259 }
1260 if ( ch != QEOF )
1261 ts_ungetc( ch );
1262 return val;
1263}
1264
1265ulong QTextStream::input_hex()
1266{
1267 ulong val = 0;
1268 QChar ch = eat_ws();
1269 char c = ch;
1270 while ( isxdigit((uchar) c) ) {
1271 val <<= 4;
1272 if ( ts_isdigit(c) )
1273 val += c - '0';
1274 else
1275 val += 10 + tolower( (uchar) c ) - 'a';
1276 c = ch = ts_getc();
1277 }
1278 if ( ch != QEOF )
1279 ts_ungetc( ch );
1280 return val;
1281}
1282
1283long QTextStream::input_int()
1284{
1285 long val;
1286 QChar ch;
1287 char c;
1288 switch ( flags() & basefield ) {
1289 case bin:
1290 val = (long)input_bin();
1291 break;
1292 case oct:
1293 val = (long)input_oct();
1294 break;
1295 case dec:
1296 c = ch = eat_ws();
1297 if ( ch == QEOF ) {
1298 val = 0;
1299 } else {
1300 if ( !(c == '-' || c == '+') )
1301 ts_ungetc( ch );
1302 if ( c == '-' ) {
1303 ulong v = input_dec();
1304 if ( v ) { // ensure that LONG_MIN can be read
1305 v--;
1306 val = -((long)v) - 1;
1307 } else {
1308 val = 0;
1309 }
1310 } else {
1311 val = (long)input_dec();
1312 }
1313 }
1314 break;
1315 case hex:
1316 val = (long)input_hex();
1317 break;
1318 default:
1319 val = 0;
1320 c = ch = eat_ws();
1321 if ( c == '0' ) { // bin, oct or hex
1322 c = ch = ts_getc();
1323 if ( tolower((uchar) c) == 'x' )
1324 val = (long)input_hex();
1325 else if ( tolower((uchar) c) == 'b' )
1326 val = (long)input_bin();
1327 else { // octal
1328 ts_ungetc( ch );
1329 if ( c >= '0' && c <= '7' ) {
1330 val = (long)input_oct();
1331 } else {
1332 val = 0;
1333 }
1334 }
1335 } else if ( ts_isdigit(ch) ) {
1336 ts_ungetc( ch );
1337 val = (long)input_dec();
1338 } else if ( c == '-' || c == '+' ) {
1339 ulong v = input_dec();
1340 if ( c == '-' ) {
1341 if ( v ) { // ensure that LONG_MIN can be read
1342 v--;
1343 val = -((long)v) - 1;
1344 } else {
1345 val = 0;
1346 }
1347 } else {
1348 val = (long)v;
1349 }
1350 }
1351 }
1352 return val;
1353}
1354
1355//
1356// We use a table-driven FSM to parse floating point numbers
1357// strtod() cannot be used directly since we're reading from a QIODevice
1358//
1359
1360double QTextStream::input_double()
1361{
1362 const int Init = 0; // states
1363 const int Sign = 1;
1364 const int Mantissa = 2;
1365 const int Dot = 3;
1366 const int Abscissa = 4;
1367 const int ExpMark = 5;
1368 const int ExpSign = 6;
1369 const int Exponent = 7;
1370 const int Done = 8;
1371
1372 const int InputSign = 1; // input tokens
1373 const int InputDigit = 2;
1374 const int InputDot = 3;
1375 const int InputExp = 4;
1376
1377 static const uchar table[8][5] = {
1378 /* None InputSign InputDigit InputDot InputExp */
1379 { 0, Sign, Mantissa, Dot, 0, }, // Init
1380 { 0, 0, Mantissa, Dot, 0, }, // Sign
1381 { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa
1382 { 0, 0, Abscissa, 0, 0, }, // Dot
1383 { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa
1384 { 0, ExpSign, Exponent, 0, 0, }, // ExpMark
1385 { 0, 0, Exponent, 0, 0, }, // ExpSign
1386 { Done, Done, Exponent, Done, Done } // Exponent
1387 };
1388
1389 int state = Init; // parse state
1390 int input; // input token
1391
1392 char buf[256];
1393 int i = 0;
1394 QChar c = eat_ws();
1395
1396 for (;;) {
1397
1398 switch ( c ) {
1399 case '+':
1400 case '-':
1401 input = InputSign;
1402 break;
1403 case '0': case '1': case '2': case '3': case '4':
1404 case '5': case '6': case '7': case '8': case '9':
1405 input = InputDigit;
1406 break;
1407 case '.':
1408 input = InputDot;
1409 break;
1410 case 'e':
1411 case 'E':
1412 input = InputExp;
1413 break;
1414 default:
1415 input = 0;
1416 break;
1417 }
1418
1419 state = table[state][input];
1420
1421 if ( state == 0 || state == Done || i > 250 ) {
1422 if ( i > 250 ) { // ignore rest of digits
1423 do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );
1424 }
1425 if ( c != QEOF )
1426 ts_ungetc( c );
1427 buf[i] = '\0';
1428 char *end;
1429 return strtod( buf, &end );
1430 }
1431
1432 buf[i++] = c;
1433 c = ts_getc();
1434 }
1435
1436#if !defined(Q_CC_EDG)
1437 return 0.0;
1438#endif
1439}
1440
1441
1442/*!
1443 \overload
1444
1445 Reads a signed \c short integer \a i from the stream and returns a
1446 reference to the stream. See flags() for an explanation of the
1447 expected input format.
1448*/
1449
1450QTextStream &QTextStream::operator>>( signed short &i )
1451{
1452 CHECK_STREAM_PRECOND
1453 i = (signed short)input_int();
1454 return *this;
1455}
1456
1457
1458/*!
1459 \overload
1460
1461 Reads an unsigned \c short integer \a i from the stream and
1462 returns a reference to the stream. See flags() for an explanation
1463 of the expected input format.
1464*/
1465
1466QTextStream &QTextStream::operator>>( unsigned short &i )
1467{
1468 CHECK_STREAM_PRECOND
1469 i = (unsigned short)input_int();
1470 return *this;
1471}
1472
1473
1474/*!
1475 \overload
1476
1477 Reads a signed \c int \a i from the stream and returns a reference
1478 to the stream. See flags() for an explanation of the expected
1479 input format.
1480*/
1481
1482QTextStream &QTextStream::operator>>( signed int &i )
1483{
1484 CHECK_STREAM_PRECOND
1485 i = (signed int)input_int();
1486 return *this;
1487}
1488
1489
1490/*!
1491 \overload
1492
1493 Reads an unsigned \c int \a i from the stream and returns a
1494 reference to the stream. See flags() for an explanation of the
1495 expected input format.
1496*/
1497
1498QTextStream &QTextStream::operator>>( unsigned int &i )
1499{
1500 CHECK_STREAM_PRECOND
1501 i = (unsigned int)input_int();
1502 return *this;
1503}
1504
1505
1506/*!
1507 \overload
1508
1509 Reads a signed \c long int \a i from the stream and returns a
1510 reference to the stream. See flags() for an explanation of the
1511 expected input format.
1512*/
1513
1514QTextStream &QTextStream::operator>>( signed long &i )
1515{
1516 CHECK_STREAM_PRECOND
1517 i = (signed long)input_int();
1518 return *this;
1519}
1520
1521
1522/*!
1523 \overload
1524
1525 Reads an unsigned \c long int \a i from the stream and returns a
1526 reference to the stream. See flags() for an explanation of the
1527 expected input format.
1528*/
1529
1530QTextStream &QTextStream::operator>>( unsigned long &i )
1531{
1532 CHECK_STREAM_PRECOND
1533 i = (unsigned long)input_int();
1534 return *this;
1535}
1536
1537
1538/*!
1539 \overload
1540
1541 Reads a \c float \a f from the stream and returns a reference to
1542 the stream. See flags() for an explanation of the expected input
1543 format.
1544*/
1545
1546QTextStream &QTextStream::operator>>( float &f )
1547{
1548 CHECK_STREAM_PRECOND
1549 f = (float)input_double();
1550 return *this;
1551}
1552
1553
1554/*!
1555 \overload
1556
1557 Reads a \c double \a f from the stream and returns a reference to
1558 the stream. See flags() for an explanation of the expected input
1559 format.
1560*/
1561
1562QTextStream &QTextStream::operator>>( double &f )
1563{
1564 CHECK_STREAM_PRECOND
1565 f = input_double();
1566 return *this;
1567}
1568
1569
1570/*!
1571 \overload
1572
1573 Reads a "word" from the stream into \a s and returns a reference
1574 to the stream.
1575
1576 A word consists of characters for which isspace() returns FALSE.
1577*/
1578
1579QTextStream &QTextStream::operator>>( char *s )
1580{
1581 CHECK_STREAM_PRECOND
1582 int maxlen = width( 0 );
1583 QChar c = eat_ws();
1584 if ( !maxlen )
1585 maxlen = -1;
1586 while ( c != QEOF ) {
1587 if ( ts_isspace(c) || maxlen-- == 0 ) {
1588 ts_ungetc( c );
1589 break;
1590 }
1591 *s++ = c;
1592 c = ts_getc();
1593 }
1594
1595 *s = '\0';
1596 return *this;
1597}
1598
1599/*!
1600 \overload
1601
1602 Reads a "word" from the stream into \a str and returns a reference
1603 to the stream.
1604
1605 A word consists of characters for which isspace() returns FALSE.
1606*/
1607
1608QTextStream &QTextStream::operator>>( QString &str )
1609{
1610 CHECK_STREAM_PRECOND
1611 str=QString::fromLatin1("");
1612 QCharc = eat_ws();
1613
1614 while ( c != QEOF ) {
1615 if ( ts_isspace(c) ) {
1616 ts_ungetc( c );
1617 break;
1618 }
1619 str += c;
1620 c = ts_getc();
1621 }
1622 return *this;
1623}
1624
1625/*!
1626 \overload
1627
1628 Reads a "word" from the stream into \a str and returns a reference
1629 to the stream.
1630
1631 A word consists of characters for which isspace() returns FALSE.
1632*/
1633
1634QTextStream &QTextStream::operator>>( QCString &str )
1635{
1636 CHECK_STREAM_PRECOND
1637 QCString *dynbuf = 0;
1638 const int buflen = 256;
1639 char buffer[buflen];
1640 char *s = buffer;
1641 int i = 0;
1642 QChar c = eat_ws();
1643
1644 while ( c != QEOF ) {
1645 if ( ts_isspace(c) ) {
1646 ts_ungetc( c );
1647 break;
1648 }
1649 if ( i >= buflen-1 ) {
1650 if ( !dynbuf ) { // create dynamic buffer
1651 dynbuf = new QCString(buflen*2);
1652 memcpy( dynbuf->data(), s, i );// copy old data
1653 } else if ( i >= (int)dynbuf->size()-1 ) {
1654 dynbuf->resize( dynbuf->size()*2 );
1655 }
1656 s = dynbuf->data();
1657 }
1658 s[i++] = c;
1659 c = ts_getc();
1660 }
1661 str.resize( i+1 );
1662 memcpy( str.data(), s, i );
1663 delete dynbuf;
1664 return *this;
1665}
1666
1667
1668/*!
1669 Reads a line from the stream and returns a string containing the
1670 text.
1671
1672 The returned string does not contain any trailing newline or
1673 carriage return. Note that this is different from
1674 QIODevice::readLine(), which does not strip the newline at the end
1675 of the line.
1676
1677 On EOF you will get a QString that is null. On reading an empty
1678 line the returned QString is empty but not null.
1679
1680 \sa QIODevice::readLine()
1681*/
1682
1683QString QTextStream::readLine()
1684{
1685#if defined(QT_CHECK_STATE)
1686 if ( !dev ) {
1687 qWarning( "QTextStream::readLine: No device" );
1688 return QString::null;
1689 }
1690#endif
1691 bool readCharByChar = TRUE;
1692 QString result;
1693#if 0
1694 if ( !doUnicodeHeader && (
1695 (latin1) ||
1696 (mapper != 0 && mapper->mibEnum() == 106 ) // UTF 8
1697 ) ) {
1698 readCharByChar = FALSE;
1699 // use optimized read line
1700 QChar c[getline_buf_size];
1701 int pos = 0;
1702 bool eof = FALSE;
1703
1704 for (;;) {
1705 pos = ts_getline( c );
1706 if ( pos == 0 ) {
1707 // something went wrong; try fallback
1708 readCharByChar = TRUE;
1709 //dev->resetStatus();
1710 break;
1711 }
1712 if ( c[pos-1] == QEOF || c[pos-1] == '\n' ) {
1713 if ( pos>2 && c[pos-1]==QEOF && c[pos-2]=='\n' ) {
1714 result += QString( c, pos-2 );
1715 } else if ( pos > 1 ) {
1716 result += QString( c, pos-1 );
1717 }
1718 if ( pos == 1 && c[pos-1] == QEOF )
1719 eof = TRUE;
1720 break;
1721 } else {
1722 result += QString( c, pos );
1723 }
1724 }
1725 if ( eof && result.isEmpty() )
1726 return QString::null;
1727 }
1728#endif
1729 if ( readCharByChar ) {
1730 // read character by character
1731 const int buf_size = 256;
1732 QChar c[buf_size];
1733 int pos = 0;
1734
1735 c[pos] = ts_getc();
1736 if ( c[pos] == QEOF ) {
1737 return QString::null;
1738 }
1739
1740 while ( c[pos] != QEOF && c[pos] != '\n' ) {
1741 if ( c[pos] == '\r' ) { // ( handle mac and dos )
1742 QChar nextc = ts_getc();
1743 if ( nextc != '\n' )
1744 ts_ungetc( nextc );
1745 break;
1746 }
1747 pos++;
1748 if ( pos >= buf_size ) {
1749 result += QString( c, pos );
1750 pos = 0;
1751 }
1752 c[pos] = ts_getc();
1753 }
1754 result += QString( c, pos );
1755 }
1756
1757 return result;
1758}
1759
1760
1761/*!
1762 Reads the entire stream and returns a string containing the text.
1763
1764 \sa QIODevice::readLine()
1765*/
1766
1767QString QTextStream::read()
1768{
1769#if defined(QT_CHECK_STATE)
1770 if ( !dev ) {
1771 qWarning( "QTextStream::read: No device" );
1772 return QString::null;
1773 }
1774#endif
1775 QString result;
1776 const uint bufsize = 512;
1777 QChar buf[bufsize];
1778 uint i, num, start;
1779 bool skipped_cr = FALSE;
1780
1781 for (;;) {
1782 num = ts_getbuf(buf,bufsize);
1783 // convert dos (\r\n) and mac (\r) style eol to unix style (\n)
1784 start = 0;
1785 for ( i=0; i<num; i++ ) {
1786 if ( buf[i] == '\r' ) {
1787 // Only skip single cr's preceding lf's
1788 if ( skipped_cr ) {
1789 result += buf[i];
1790 start++;
1791 } else {
1792 result += QString( &buf[start], i-start );
1793 start = i+1;
1794 skipped_cr = TRUE;
1795 }
1796 } else {
1797 if ( skipped_cr ) {
1798 if ( buf[i] != '\n' ) {
1799 // Should not have skipped it
1800 result += '\n';
1801 }
1802 skipped_cr = FALSE;
1803 }
1804 }
1805 }
1806 if ( start < num )
1807 result += QString( &buf[start], i-start );
1808 if ( num != bufsize ) // if ( EOF )
1809 break;
1810 }
1811 return result;
1812}
1813
1814
1815
1816/*****************************************************************************
1817 QTextStream write functions
1818 *****************************************************************************/
1819
1820/*!
1821 Writes character \c char to the stream and returns a reference to
1822 the stream.
1823
1824 The character \a c is assumed to be Latin1 encoded independent of
1825 the Encoding set for the QTextStream.
1826*/
1827QTextStream &QTextStream::operator<<( QChar c )
1828{
1829 CHECK_STREAM_PRECOND
1830 ts_putc( c );
1831 return *this;
1832}
1833
1834/*!
1835 \overload
1836
1837 Writes character \a c to the stream and returns a reference to the
1838 stream.
1839*/
1840QTextStream &QTextStream::operator<<( char c )
1841{
1842 CHECK_STREAM_PRECOND
1843 unsigned char uc = (unsigned char) c;
1844 ts_putc( uc );
1845 return *this;
1846}
1847
1848QTextStream &QTextStream::output_int( int format, ulong n, bool neg )
1849{
1850 static const char hexdigits_lower[] = "0123456789abcdef";
1851 static const char hexdigits_upper[] = "0123456789ABCDEF";
1852 CHECK_STREAM_PRECOND
1853 char buf[76];
1854 register char *p;
1855 int len;
1856 const char *hexdigits;
1857
1858 switch ( flags() & I_BASE_MASK ) {
1859
1860 case I_BASE_2: // output binary number
1861 switch ( format & I_TYPE_MASK ) {
1862 case I_SHORT: len=16; break;
1863 case I_INT: len=sizeof(int)*8; break;
1864 case I_LONG: len=32; break;
1865 default: len = 0;
1866 }
1867 p = &buf[74]; // go reverse order
1868 *p = '\0';
1869 while ( len-- ) {
1870 *--p = (char)(n&1) + '0';
1871 n >>= 1;
1872 if ( !n )
1873 break;
1874 }
1875 if ( flags() & showbase ) { // show base
1876 *--p = (flags() & uppercase) ? 'B' : 'b';
1877 *--p = '0';
1878 }
1879 break;
1880
1881 case I_BASE_8: // output octal number
1882 p = &buf[74];
1883 *p = '\0';
1884 do {
1885 *--p = (char)(n&7) + '0';
1886 n >>= 3;
1887 } while ( n );
1888 if ( flags() & showbase )
1889 *--p = '0';
1890 break;
1891
1892 case I_BASE_16: // output hexadecimal number
1893 p = &buf[74];
1894 *p = '\0';
1895 hexdigits = (flags() & uppercase) ?
1896 hexdigits_upper : hexdigits_lower;
1897 do {
1898 *--p = hexdigits[(int)n&0xf];
1899 n >>= 4;
1900 } while ( n );
1901 if ( flags() & showbase ) {
1902 *--p = (flags() & uppercase) ? 'X' : 'x';
1903 *--p = '0';
1904 }
1905 break;
1906
1907 default: // decimal base is default
1908 p = &buf[74];
1909 *p = '\0';
1910 if ( neg )
1911 n = (ulong)(-(long)n);
1912 do {
1913 *--p = ((int)(n%10)) + '0';
1914 n /= 10;
1915 } while ( n );
1916 if ( neg )
1917 *--p = '-';
1918 else if ( flags() & showpos )
1919 *--p = '+';
1920 if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
1921 ts_putc( *p ); // special case for internal
1922 ++p; // padding
1923 fwidth--;
1924 return *this << (const char*)p;
1925 }
1926 }
1927 if ( fwidth ) { // adjustment required
1928 if ( !(flags() & left) ) { // but NOT left adjustment
1929 len = qstrlen(p);
1930 int padlen = fwidth - len;
1931 if ( padlen <= 0 ) { // no padding required
1932 writeBlock( p, len );
1933 } else if ( padlen < (int)(p-buf) ) { // speeds up padding
1934 memset( p-padlen, (char)fillchar, padlen );
1935 writeBlock( p-padlen, padlen+len );
1936 }
1937 else // standard padding
1938 *this << (const char*)p;
1939 }
1940 else
1941 *this << (const char*)p;
1942 fwidth = 0; // reset field width
1943 }
1944 else
1945 writeBlock( p, qstrlen(p) );
1946 return *this;
1947}
1948
1949
1950/*!
1951 \overload
1952
1953 Writes a \c short integer \a i to the stream and returns a
1954 reference to the stream.
1955*/
1956
1957QTextStream &QTextStream::operator<<( signed short i )
1958{
1959 return output_int( I_SHORT | I_SIGNED, i, i < 0 );
1960}
1961
1962
1963/*!
1964 \overload
1965
1966 Writes an \c unsigned \c short integer \a i to the stream and
1967 returns a reference to the stream.
1968*/
1969
1970QTextStream &QTextStream::operator<<( unsigned short i )
1971{
1972 return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
1973}
1974
1975
1976/*!
1977 \overload
1978
1979 Writes an \c int \a i to the stream and returns a reference to the
1980 stream.
1981*/
1982
1983QTextStream &QTextStream::operator<<( signed int i )
1984{
1985 return output_int( I_INT | I_SIGNED, i, i < 0 );
1986}
1987
1988
1989/*!
1990 \overload
1991
1992 Writes an \c unsigned \c int \a i to the stream and returns a
1993 reference to the stream.
1994*/
1995
1996QTextStream &QTextStream::operator<<( unsigned int i )
1997{
1998 return output_int( I_INT | I_UNSIGNED, i, FALSE );
1999}
2000
2001
2002/*!
2003 \overload
2004
2005 Writes a \c long \c int \a i to the stream and returns a reference
2006 to the stream.
2007*/
2008
2009QTextStream &QTextStream::operator<<( signed long i )
2010{
2011 return output_int( I_LONG | I_SIGNED, i, i < 0 );
2012}
2013
2014
2015/*!
2016 \overload
2017
2018 Writes an \c unsigned \c long \c int \a i to the stream and
2019 returns a reference to the stream.
2020*/
2021
2022QTextStream &QTextStream::operator<<( unsigned long i )
2023{
2024 return output_int( I_LONG | I_UNSIGNED, i, FALSE );
2025}
2026
2027
2028/*!
2029 \overload
2030
2031 Writes a \c float \a f to the stream and returns a reference to
2032 the stream.
2033*/
2034
2035QTextStream &QTextStream::operator<<( float f )
2036{
2037 return *this << (double)f;
2038}
2039
2040
2041/*!
2042 \overload
2043
2044 Writes a \c double \a f to the stream and returns a reference to
2045 the stream.
2046*/
2047
2048QTextStream &QTextStream::operator<<( double f )
2049{
2050 CHECK_STREAM_PRECOND
2051 char buf[64];
2052 char f_char;
2053 char format[16];
2054 if ( (flags()&floatfield) == fixed )
2055 f_char = 'f';
2056 else if ( (flags()&floatfield) == scientific )
2057 f_char = (flags() & uppercase) ? 'E' : 'e';
2058 else
2059 f_char = (flags() & uppercase) ? 'G' : 'g';
2060 register char *fs = format; // generate format string
2061 *fs++ = '%'; // "%.<prec>l<f_char>"
2062 *fs++ = '.';
2063 int prec = precision();
2064 if ( prec > 99 )
2065 prec = 99;
2066 if ( prec >= 10 ) {
2067 *fs++ = prec / 10 + '0';
2068 *fs++ = prec % 10 + '0';
2069 } else {
2070 *fs++ = prec + '0';
2071 }
2072 *fs++ = 'l';
2073 *fs++ = f_char;
2074 *fs = '\0';
2075 sprintf( buf, format, f ); // convert to text
2076 if ( fwidth ) // padding
2077 *this << (const char*)buf;
2078 else // just write it
2079 writeBlock( buf, qstrlen(buf) );
2080 return *this;
2081}
2082
2083
2084/*!
2085 \overload
2086
2087 Writes a string to the stream and returns a reference to the
2088 stream.
2089
2090 The string \a s is assumed to be Latin1 encoded independent of the
2091 Encoding set for the QTextStream.
2092*/
2093
2094QTextStream &QTextStream::operator<<( const char* s )
2095{
2096 CHECK_STREAM_PRECOND
2097 char padbuf[48];
2098 uint len = qstrlen( s ); // don't write null terminator
2099 if ( fwidth ) { // field width set
2100 int padlen = fwidth - len;
2101 fwidth = 0; // reset width
2102 if ( padlen > 0 ) {
2103 char *ppad;
2104 if ( padlen > 46 ) { // create extra big fill buffer
2105 ppad = new char[padlen];
2106 Q_CHECK_PTR( ppad );
2107 } else {
2108 ppad = padbuf;
2109 }
2110 memset( ppad, (char)fillchar, padlen );// fill with fillchar
2111 if ( !(flags() & left) ) {
2112 writeBlock( ppad, padlen );
2113 padlen = 0;
2114 }
2115 writeBlock( s, len );
2116 if ( padlen )
2117 writeBlock( ppad, padlen );
2118 if ( ppad != padbuf ) // delete extra big fill buf
2119 delete[] ppad;
2120 return *this;
2121 }
2122 }
2123 writeBlock( s, len );
2124 return *this;
2125}
2126
2127/*!
2128 \overload
2129
2130 Writes \a s to the stream and returns a reference to the stream.
2131
2132 The string \a s is assumed to be Latin1 encoded independent of the
2133 Encoding set for the QTextStream.
2134*/
2135
2136QTextStream &QTextStream::operator<<( const QCString & s )
2137{
2138 return operator<<(s.data());
2139}
2140
2141/*!
2142 \overload
2143
2144 Writes \a s to the stream and returns a reference to the stream.
2145*/
2146
2147QTextStream &QTextStream::operator<<( const QString& s )
2148{
2149 if ( !mapper && latin1 )
2150 return operator<<(s.latin1());
2151 CHECK_STREAM_PRECOND
2152 QString s1 = s;
2153 if ( fwidth ) { // field width set
2154 if ( !(flags() & left) ) {
2155 s1 = s.rightJustify(fwidth, (char)fillchar);
2156 } else {
2157 s1 = s.leftJustify(fwidth, (char)fillchar);
2158 }
2159 fwidth = 0; // reset width
2160 }
2161 writeBlock( s1.unicode(), s1.length() );
2162 return *this;
2163}
2164
2165
2166/*!
2167 \overload
2168
2169 Writes a pointer to the stream and returns a reference to the
2170 stream.
2171
2172 The \a ptr is output as an unsigned long hexadecimal integer.
2173*/
2174
2175QTextStream &QTextStream::operator<<( void *ptr )
2176{
2177 int f = flags();
2178 setf( hex, basefield );
2179 setf( showbase );
2180 unsetf( uppercase );
2181 output_int( I_LONG | I_UNSIGNED, (ulong)ptr, FALSE );
2182 flags( f );
2183 return *this;
2184}
2185
2186
2187/*!
2188 \fn int QTextStream::flags() const
2189
2190 Returns the current stream flags. The default value is 0.
2191
2192 \table
2193 \header \i Flag \i Meaning
2194 \row \i \c skipws \i Not currently used; whitespace always skipped
2195 \row \i \c left \i Numeric fields are left-aligned
2196 \row \i \c right
2197 \i Not currently used (by default, numerics are right-aligned)
2198 \row \i \c internal \i Puts any padding spaces between +/- and value
2199 \row \i \c bin \i Output \e and input only in binary
2200 \row \i \c oct \i Output \e and input only in octal
2201 \row \i \c dec \i Output \e and input only in decimal
2202 \row \i \c hex \i Output \e and input only in hexadecimal
2203 \row \i \c showbase
2204 \i Annotates numeric outputs with 0b, 0, or 0x if in \c bin,
2205 \c oct, or \c hex format
2206 \row \i \c showpoint \i Not currently used
2207 \row \i \c uppercase \i Uses 0B and 0X rather than 0b and 0x
2208 \row \i \c showpos \i Shows + for positive numeric values
2209 \row \i \c scientific \i Uses scientific notation for floating point values
2210 \row \i \c fixed \i Uses fixed-point notation for floating point values
2211 \endtable
2212
2213 Note that unless \c bin, \c oct, \c dec, or \c hex is set, the
2214 input base is octal if the value starts with 0, hexadecimal if it
2215 starts with 0x, binary if it starts with 0b, and decimal
2216 otherwise.
2217
2218 \sa setf(), unsetf()
2219*/
2220
2221/*!
2222 \fn int QTextStream::flags( int f )
2223
2224 \overload
2225
2226 Sets the stream flags to \a f. Returns the previous stream flags.
2227
2228 \sa setf(), unsetf(), flags()
2229*/
2230
2231/*!
2232 \fn int QTextStream::setf( int bits )
2233
2234 Sets the stream flag bits \a bits. Returns the previous stream
2235 flags.
2236
2237 Equivalent to \c{flags( flags() | bits )}.
2238
2239 \sa setf(), unsetf()
2240*/
2241
2242/*!
2243 \fn int QTextStream::setf( int bits, int mask )
2244
2245 \overload
2246
2247 Sets the stream flag bits \a bits with a bit mask \a mask. Returns
2248 the previous stream flags.
2249
2250 Equivalent to \c{flags( (flags() & ~mask) | (bits & mask) )}.
2251
2252 \sa setf(), unsetf()
2253*/
2254
2255/*!
2256 \fn int QTextStream::unsetf( int bits )
2257
2258 Clears the stream flag bits \a bits. Returns the previous stream
2259 flags.
2260
2261 Equivalent to \c{flags( flags() & ~mask )}.
2262
2263 \sa setf()
2264*/
2265
2266/*!
2267 \fn int QTextStream::width() const
2268
2269 Returns the field width. The default value is 0.
2270*/
2271
2272/*!
2273 \fn int QTextStream::width( int w )
2274
2275 \overload
2276
2277 Sets the field width to \a w. Returns the previous field width.
2278*/
2279
2280/*!
2281 \fn int QTextStream::fill() const
2282
2283 Returns the fill character. The default value is ' ' (space).
2284*/
2285
2286/*!
2287 \overload int QTextStream::fill( int f )
2288
2289 Sets the fill character to \a f. Returns the previous fill character.
2290*/
2291
2292/*!
2293 \fn int QTextStream::precision() const
2294
2295 Returns the precision. The default value is 6.
2296*/
2297
2298/*!
2299 \fn int QTextStream::precision( int p )
2300
2301 \overload
2302
2303 Sets the precision to \a p. Returns the previous precision setting.
2304*/
2305
2306
2307 /*****************************************************************************
2308 QTextStream manipulators
2309 *****************************************************************************/
2310
2311QTextStream &bin( QTextStream &s )
2312{
2313 s.setf(QTS::bin,QTS::basefield);
2314 return s;
2315}
2316
2317QTextStream &oct( QTextStream &s )
2318{
2319 s.setf(QTS::oct,QTS::basefield);
2320 return s;
2321}
2322
2323QTextStream &dec( QTextStream &s )
2324{
2325 s.setf(QTS::dec,QTS::basefield);
2326 return s;
2327}
2328
2329QTextStream &hex( QTextStream &s )
2330{
2331 s.setf(QTS::hex,QTS::basefield);
2332 return s;
2333}
2334
2335QTextStream &endl( QTextStream &s )
2336{
2337 return s << '\n';
2338}
2339
2340QTextStream &flush( QTextStream &s )
2341{
2342 if ( s.device() )
2343 s.device()->flush();
2344 return s;
2345}
2346
2347QTextStream &ws( QTextStream &s )
2348{
2349 s.skipWhiteSpace();
2350 return s;
2351}
2352
2353QTextStream &reset( QTextStream &s )
2354{
2355 s.reset();
2356 return s;
2357}
2358
2359
2360/*!
2361 \class QTextIStream qtextstream.h
2362 \reentrant
2363 \brief The QTextIStream class is a convenience class for input streams.
2364
2365 \ingroup io
2366 \ingroup text
2367
2368 This class provides a shorthand for creating simple input
2369 \l{QTextStream}s without having to pass a \e mode argument to the
2370 constructor.
2371
2372 This class makes it easy, for example, to write things like this:
2373 \code
2374 QString data = "123 456";
2375 int a, b;
2376 QTextIStream(&data) >> a >> b;
2377 \endcode
2378
2379 \sa QTextOStream
2380*/
2381
2382/*!
2383 \fn QTextIStream::QTextIStream( const QString *s )
2384
2385 Constructs a stream to read from the string \a s.
2386*/
2387/*!
2388 \fn QTextIStream::QTextIStream( QByteArray ba )
2389
2390 Constructs a stream to read from the array \a ba.
2391*/
2392/*!
2393 \fn QTextIStream::QTextIStream( FILE *f )
2394
2395 Constructs a stream to read from the file \a f.
2396*/
2397
2398
2399/*!
2400 \class QTextOStream
2401 \reentrant
2402 \brief The QTextOStream class is a convenience class for output streams.
2403
2404 \ingroup io
2405 \ingroup text
2406
2407 This class provides a shorthand for creating simple output
2408 \l{QTextStream}s without having to pass a \e mode argument to the
2409 constructor.
2410
2411 This makes it easy for example, to write things like this:
2412 \code
2413 QString result;
2414 QTextOStream(&result) << "pi = " << 3.14;
2415 \endcode
2416*/
2417
2418/*!
2419 \fn QTextOStream::QTextOStream( QString *s )
2420
2421 Constructs a stream to write to string \a s.
2422*/
2423/*!
2424 \fn QTextOStream::QTextOStream( QByteArray ba )
2425
2426 Constructs a stream to write to the array \a ba.
2427*/
2428/*!
2429 \fn QTextOStream::QTextOStream( FILE *f )
2430
2431 Constructs a stream to write to the file \a f.
2432*/
2433
2434
2435
2436/*!
2437 Sets the encoding of this stream to \a e, where \a e is one of the
2438 following values:
2439 \table
2440 \header \i Encoding \i Meaning
2441 \row \i Locale
2442 \i Uses local file format (Latin1 if locale is not set), but
2443 autodetecting Unicode(utf16) on input.
2444 \row \i Unicode
2445 \i Uses Unicode(utf16) for input and output. Output will be
2446 written in the order most efficient for the current platform
2447 (i.e. the order used internally in QString).
2448 \row \i UnicodeUTF8
2449 \i Using Unicode(utf8) for input and output. If you use it for
2450 input it will autodetect utf16 and use it instead of utf8.
2451 \row \i Latin1
2452 \i ISO-8859-1. Will not autodetect utf16.
2453 \row \i UnicodeNetworkOrder
2454 \i Uses network order Unicode(utf16) for input and output.
2455 Useful when reading Unicode data that does not start with the
2456 byte order marker.
2457 \row \i UnicodeReverse
2458 \i Uses reverse network order Unicode(utf16) for input and
2459 output. Useful when reading Unicode data that does not start
2460 with the byte order marker or when writing data that should be
2461 read by buggy Windows applications.
2462 \row \i RawUnicode
2463 \i Like Unicode, but does not write the byte order marker nor
2464 does it auto-detect the byte order. Useful only when writing to
2465 non-persistent storage used by a single process.
2466 \endtable
2467
2468 \c Locale and all Unicode encodings, except \c RawUnicode, will look
2469 at the first two bytes in an input stream to determine the byte
2470 order. The initial byte order marker will be stripped off before
2471 data is read.
2472
2473 Note that this function should be called before any data is read to
2474 or written from the stream.
2475
2476 \sa setCodec()
2477*/
2478
2479void QTextStream::setEncoding( Encoding e )
2480{
2481 if ( d->sourceType == QTextStreamPrivate::String )
2482 return;
2483
2484 switch ( e ) {
2485 case Unicode:
2486 mapper = 0;
2487 latin1 = FALSE;
2488 doUnicodeHeader = TRUE;
2489 internalOrder = TRUE;
2490 networkOrder = QChar::networkOrdered();
2491 break;
2492 case UnicodeUTF8:
2493#ifndef QT_NO_TEXTCODEC
2494 mapper = QTextCodec::codecForMib( 106 );
2495 latin1 = FALSE;
2496 doUnicodeHeader = TRUE;
2497 internalOrder = TRUE;
2498 networkOrder = QChar::networkOrdered();
2499#else
2500 mapper = 0;
2501 latin1 = TRUE;
2502 doUnicodeHeader = TRUE;
2503#endif
2504 break;
2505 case UnicodeNetworkOrder:
2506 mapper = 0;
2507 latin1 = FALSE;
2508 doUnicodeHeader = TRUE;
2509 internalOrder = QChar::networkOrdered();
2510 networkOrder = TRUE;
2511 break;
2512 case UnicodeReverse:
2513 mapper = 0;
2514 latin1 = FALSE;
2515 doUnicodeHeader = TRUE;
2516 internalOrder = !QChar::networkOrdered();
2517 networkOrder = FALSE;
2518 break;
2519 case RawUnicode:
2520 mapper = 0;
2521 latin1 = FALSE;
2522 doUnicodeHeader = FALSE;
2523 internalOrder = TRUE;
2524 networkOrder = QChar::networkOrdered();
2525 break;
2526 case Locale:
2527 latin1 = TRUE; // fallback to Latin-1
2528#ifndef QT_NO_TEXTCODEC
2529 mapper = QTextCodec::codecForLocale();
2530 // optimized Latin-1 processing
2531#if defined(Q_OS_WIN32)
2532 if ( GetACP() == 1252 )
2533 mapper = 0;
2534#endif
2535 if ( mapper && mapper->mibEnum() == 4 )
2536#endif
2537 mapper = 0;
2538
2539 doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
2540 break;
2541 case Latin1:
2542 mapper = 0;
2543 doUnicodeHeader = FALSE;
2544 latin1 = TRUE;
2545 break;
2546 }
2547}
2548
2549
2550#ifndef QT_NO_TEXTCODEC
2551/*!
2552 Sets the codec for this stream to \a codec. Will not try to
2553 autodetect Unicode.
2554
2555 Note that this function should be called before any data is read
2556 to/written from the stream.
2557
2558 \sa setEncoding(), codec()
2559*/
2560
2561void QTextStream::setCodec( QTextCodec *codec )
2562{
2563 if ( d->sourceType == QTextStreamPrivate::String )
2564 return; // QString does not need any codec
2565 mapper = codec;
2566 latin1 = ( codec->mibEnum() == 4 );
2567 if ( latin1 )
2568 mapper = 0;
2569 doUnicodeHeader = FALSE;
2570}
2571
2572/*!
2573 Returns the codec actually used for this stream.
2574
2575 If Unicode is automatically detected in input, a codec with \link
2576 QTextCodec::name() name() \endlink "ISO-10646-UCS-2" is returned.
2577
2578 \sa setCodec()
2579*/
2580
2581QTextCodec *QTextStream::codec()
2582{
2583 if ( mapper ) {
2584 return mapper;
2585 } else {
2586 // 4 is "ISO 8859-1", 1000 is "ISO-10646-UCS-2"
2587 return QTextCodec::codecForMib( latin1 ? 4 : 1000 );
2588 }
2589}
2590
2591#endif
2592
2593#endif // QT_NO_TEXTSTREAM