Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 1322