source: vendor/trolltech/current/src/tools/qtextstream.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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