Root/
Source at commit 1322 created 12 years 8 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 ) {␉␉␉␉\␊ |
161 | ␉␉␉␉qWarning( "QTextStream: No device" );␉\␊ |
162 | ␉␉␉␉return *this; }␊ |
163 | #else␊ |
164 | #define CHECK_STREAM_PRECOND␊ |
165 | #endif␊ |
166 | ␊ |
167 | ␊ |
168 | #define I_SHORT␉␉0x0010␊ |
169 | #define I_INT␉␉0x0020␊ |
170 | #define I_LONG␉␉0x0030␊ |
171 | #define I_TYPE_MASK␉0x00f0␊ |
172 | ␊ |
173 | #define I_BASE_2␉QTS::bin␊ |
174 | #define I_BASE_8␉QTS::oct␊ |
175 | #define I_BASE_10␉QTS::dec␊ |
176 | #define I_BASE_16␉QTS::hex␊ |
177 | #define I_BASE_MASK␉(QTS::bin | QTS::oct | QTS::dec | QTS::hex)␊ |
178 | ␊ |
179 | #define I_SIGNED␉0x0100␊ |
180 | #define I_UNSIGNED␉0x0200␊ |
181 | #define I_SIGN_MASK␉0x0f00␊ |
182 | ␊ |
183 | ␊ |
184 | static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.␊ |
185 | ␊ |
186 | const int QTextStream::basefield = I_BASE_MASK;␊ |
187 | const int QTextStream::adjustfield = ( QTextStream::left |␊ |
188 | ␉␉␉␉ QTextStream::right |␊ |
189 | ␉␉␉␉ QTextStream::internal );␊ |
190 | const int QTextStream::floatfield = ( QTextStream::scientific |␊ |
191 | ␉␉␉␉ QTextStream::fixed );␊ |
192 | ␊ |
193 | ␊ |
194 | class QTextStreamPrivate {␊ |
195 | public:␊ |
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␊ |
212 | QChar QTextStream::eat_ws()␊ |
213 | {␊ |
214 | QChar c;␊ |
215 | do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );␊ |
216 | return c;␊ |
217 | }␊ |
218 | ␊ |
219 | void 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 | ␊ |
235 | QTextStream::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 | ␊ |
247 | QTextStream::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.␊ |
258 | class QStringBuffer : public QIODevice {␊ |
259 | public:␊ |
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 );␊ |
273 | protected:␊ |
274 | QString* s;␊ |
275 | ␊ |
276 | private: // Disabled copy constructor and operator=␊ |
277 | QStringBuffer( const QStringBuffer & );␊ |
278 | QStringBuffer &operator=( const QStringBuffer & );␊ |
279 | };␊ |
280 | ␊ |
281 | ␊ |
282 | QStringBuffer::QStringBuffer( QString* str )␊ |
283 | {␊ |
284 | s = str;␊ |
285 | }␊ |
286 | ␊ |
287 | QStringBuffer::~QStringBuffer()␊ |
288 | {␊ |
289 | }␊ |
290 | ␊ |
291 | ␊ |
292 | bool QStringBuffer::open( int m )␊ |
293 | {␊ |
294 | if ( !s ) {␊ |
295 | #if defined(CHECK_STATE)␊ |
296 | ␉qWarning( "QStringBuffer::open: No string" );␊ |
297 | #endif␊ |
298 | ␉return FALSE;␊ |
299 | }␊ |
300 | if ( isOpen() ) { // buffer already open␊ |
301 | #if defined(CHECK_STATE)␊ |
302 | ␉qWarning( "QStringBuffer::open: Buffer already open" );␊ |
303 | #endif␊ |
304 | ␉return FALSE;␊ |
305 | }␊ |
306 | setMode( m );␊ |
307 | if ( m & IO_Truncate ) { // truncate buffer␊ |
308 | ␉s->truncate( 0 );␊ |
309 | }␊ |
310 | if ( m & IO_Append ) { // append to end of buffer␊ |
311 | ␉ioIndex = s->length()*sizeof(QChar);␊ |
312 | } else {␊ |
313 | ␉ioIndex = 0;␊ |
314 | }␊ |
315 | setState( IO_Open );␊ |
316 | setStatus( 0 );␊ |
317 | return TRUE;␊ |
318 | }␊ |
319 | ␊ |
320 | void QStringBuffer::close()␊ |
321 | {␊ |
322 | if ( isOpen() ) {␊ |
323 | ␉setFlags( IO_Direct );␊ |
324 | ␉ioIndex = 0;␊ |
325 | }␊ |
326 | }␊ |
327 | ␊ |
328 | void QStringBuffer::flush()␊ |
329 | {␊ |
330 | }␊ |
331 | ␊ |
332 | uint QStringBuffer::size() const␊ |
333 | {␊ |
334 | return s ? s->length()*sizeof(QChar) : 0;␊ |
335 | }␊ |
336 | ␊ |
337 | int QStringBuffer::at() const␊ |
338 | {␊ |
339 | return ioIndex;␊ |
340 | }␊ |
341 | ␊ |
342 | bool QStringBuffer::at( int pos )␊ |
343 | {␊ |
344 | #if defined(CHECK_STATE)␊ |
345 | if ( !isOpen() ) {␊ |
346 | ␉qWarning( "QStringBuffer::at: Buffer is not open" );␊ |
347 | ␉return FALSE;␊ |
348 | }␊ |
349 | #endif␊ |
350 | if ( (uint)pos >= s->length()*2 ) {␊ |
351 | #if defined(CHECK_RANGE)␊ |
352 | ␉qWarning( "QStringBuffer::at: Index %d out of range", pos );␊ |
353 | #endif␊ |
354 | ␉return FALSE;␊ |
355 | }␊ |
356 | ioIndex = pos;␊ |
357 | return TRUE;␊ |
358 | }␊ |
359 | ␊ |
360 | ␊ |
361 | int QStringBuffer::readBlock( char *p, uint len )␊ |
362 | {␊ |
363 | #if defined(CHECK_STATE)␊ |
364 | CHECK_PTR( p );␊ |
365 | if ( !isOpen() ) { // buffer not open␊ |
366 | ␉qWarning( "QStringBuffer::readBlock: Buffer not open" );␊ |
367 | ␉return -1;␊ |
368 | }␊ |
369 | if ( !isReadable() ) { // reading not permitted␊ |
370 | ␉qWarning( "QStringBuffer::readBlock: Read operation not permitted" );␊ |
371 | ␉return -1;␊ |
372 | }␊ |
373 | #endif␊ |
374 | if ( (uint)ioIndex + len > s->length()*sizeof(QChar) ) {␊ |
375 | ␉// overflow␊ |
376 | ␉if ( (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 | ␊ |
388 | int QStringBuffer::writeBlock( const char *p, uint len )␊ |
389 | {␊ |
390 | #if defined(CHECK_NULL)␊ |
391 | if ( p == 0 && len != 0 )␊ |
392 | ␉qWarning( "QStringBuffer::writeBlock: Null pointer error" );␊ |
393 | #endif␊ |
394 | #if defined(CHECK_STATE)␊ |
395 | if ( !isOpen() ) { // buffer not open␊ |
396 | ␉qWarning( "QStringBuffer::writeBlock: Buffer not open" );␊ |
397 | ␉return -1;␊ |
398 | }␊ |
399 | if ( !isWritable() ) { // writing not permitted␊ |
400 | ␉qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );␊ |
401 | ␉return -1;␊ |
402 | }␊ |
403 | if ( ioIndex&1 ) {␊ |
404 | ␉qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );␊ |
405 | ␉return -1;␊ |
406 | }␊ |
407 | if ( len&1 ) {␊ |
408 | ␉qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );␊ |
409 | ␉return -1;␊ |
410 | }␊ |
411 | #endif␊ |
412 | s->replace(ioIndex/2, len/2, (QChar*)p, len/2);␊ |
413 | ioIndex += len;␊ |
414 | return len;␊ |
415 | }␊ |
416 | ␊ |
417 | int QStringBuffer::getch()␊ |
418 | {␊ |
419 | #if defined(CHECK_STATE)␊ |
420 | if ( !isOpen() ) { // buffer not open␊ |
421 | ␉qWarning( "QStringBuffer::getch: Buffer not open" );␊ |
422 | ␉return -1;␊ |
423 | }␊ |
424 | if ( !isReadable() ) { // reading not permitted␊ |
425 | ␉qWarning( "QStringBuffer::getch: Read operation not permitted" );␊ |
426 | ␉return -1;␊ |
427 | }␊ |
428 | #endif␊ |
429 | if ( (uint)ioIndex >= s->length()*2 ) { // overflow␊ |
430 | ␉setStatus( IO_ReadError );␊ |
431 | ␉return -1;␊ |
432 | }␊ |
433 | return *((char*)s->unicode() + ioIndex++);␊ |
434 | }␊ |
435 | ␊ |
436 | int QStringBuffer::putch( int ch )␊ |
437 | {␊ |
438 | char c = ch;␊ |
439 | if ( writeBlock(&c,1) < 0 )␊ |
440 | ␉return -1;␊ |
441 | else␊ |
442 | ␉return ch;␊ |
443 | }␊ |
444 | ␊ |
445 | int QStringBuffer::ungetch( int ch )␊ |
446 | {␊ |
447 | #if defined(CHECK_STATE)␊ |
448 | if ( !isOpen() ) { // buffer not open␊ |
449 | ␉qWarning( "QStringBuffer::ungetch: Buffer not open" );␊ |
450 | ␉return -1;␊ |
451 | }␊ |
452 | if ( !isReadable() ) { // reading not permitted␊ |
453 | ␉qWarning( "QStringBuffer::ungetch: Read operation not permitted" );␊ |
454 | ␉return -1;␊ |
455 | }␊ |
456 | #endif␊ |
457 | if ( ch != -1 ) { // something to do with eof␊ |
458 | ␉if ( ioIndex )␊ |
459 | ␉ ioIndex--;␊ |
460 | ␉else␊ |
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 | ␊ |
494 | QTextStream::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 | ␊ |
513 | QTextStream::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 | ␊ |
550 | QTextStream::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 | ␊ |
573 | QTextStream::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 | ␊ |
590 | QTextStream::~QTextStream()␊ |
591 | {␊ |
592 | if ( owndev )␊ |
593 | ␉delete dev;␊ |
594 | delete d;␊ |
595 | }␊ |
596 | ␊ |
597 | /*!␊ |
598 | Positions the read pointer at the first non-whitespace character.␊ |
599 | */␊ |
600 | void 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 | */␊ |
620 | uint QTextStream::ts_getbuf( QChar* buf, uint len )␊ |
621 | {␊ |
622 | if( len<1 )␊ |
623 | ␉return 0;␊ |
624 | ␊ |
625 | uint rnum=0; // the number of QChars really read␊ |
626 | ␊ |
627 | if ( d && d->ungetcBuf.length() ) {␊ |
628 | ␉while( rnum < len && rnum < d->ungetcBuf.length() ) {␊ |
629 | ␉ buf[rnum] = d->ungetcBuf.constref(rnum);␊ |
630 | ␉ rnum++;␊ |
631 | ␉}␊ |
632 | ␉d->ungetcBuf = d->ungetcBuf.mid( rnum );␊ |
633 | ␉if ( 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 ) {␊ |
642 | ␉doUnicodeHeader = FALSE; //only at the top␊ |
643 | ␉int c1 = dev->getch();␊ |
644 | ␉if ( c1 == EOF )␊ |
645 | ␉ return rnum;␊ |
646 | ␉int c2 = dev->getch();␊ |
647 | ␉if ( 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 );␊ |
658 | ␉␉ungetHack = 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 ) {␊ |
673 | ␉bool shortRead = FALSE;␊ |
674 | ␉if ( !d->decoder )␊ |
675 | ␉ d->decoder = mapper->makeDecoder();␊ |
676 | ␉while( rnum < len ) {␊ |
677 | ␉ QString s;␊ |
678 | ␉ bool readBlock = !( len == 1+rnum );␊ |
679 | ␉ while ( TRUE ) {␊ |
680 | ␉␉// for efficiency: normally read a whole block␊ |
681 | ␉␉if ( 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 ) {␊ |
692 | ␉␉␉rlen = 1+dev->readBlock( cbuf+1, rlen-1 );␊ |
693 | ␉␉␉cbuf[0] = (char)ungetHack;␊ |
694 | ␉␉␉ungetHack = EOF;␊ |
695 | ␉␉ } else {␊ |
696 | ␉␉␉rlen = 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␊ |
706 | ␉␉int c;␊ |
707 | ␉␉if ( ungetHack == EOF ) {␊ |
708 | ␉␉ c = dev->getch();␊ |
709 | ␉␉} else {␊ |
710 | ␉␉ c = ungetHack;␊ |
711 | ␉␉ ungetHack = EOF;␊ |
712 | ␉␉}␊ |
713 | ␉␉if ( c == EOF ) {␊ |
714 | ␉␉ shortRead = TRUE;␊ |
715 | ␉␉ break;␊ |
716 | ␉␉}␊ |
717 | ␉␉char b = c;␊ |
718 | ␉␉uint lengthBefore = s.length();␊ |
719 | ␉␉s += d->decoder->toUnicode( &b, 1 );␊ |
720 | ␉␉if ( s.length() > lengthBefore )␊ |
721 | ␉␉ break; // it seems we are in sync now␊ |
722 | ␉ }␊ |
723 | ␉ uint i = 0;␊ |
724 | ␉ while( rnum < len && i < s.length() )␊ |
725 | ␉␉buf[rnum++] = s.constref(i++);␊ |
726 | ␉ if ( s.length() > i )␊ |
727 | ␉␉// could be = but append is clearer␊ |
728 | ␉␉d->ungetcBuf.append( s.mid( i ) );␊ |
729 | ␉ if ( shortRead )␊ |
730 | ␉␉return rnum;␊ |
731 | ␉}␊ |
732 | } else␊ |
733 | #endif␊ |
734 | if ( latin1 ) {␊ |
735 | ␉if ( 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 )␊ |
740 | ␉␉buf[rnum++] = (char)c;␊ |
741 | ␉} else {␊ |
742 | ␉ if ( ungetHack != EOF ) {␊ |
743 | ␉␉buf[rnum++] = (char)ungetHack;␊ |
744 | ␉␉ungetHack = EOF;␊ |
745 | ␉ }␊ |
746 | ␉ char *cbuf = new char[len - rnum];␊ |
747 | ␉ while ( !dev->atEnd() && rnum < len ) {␊ |
748 | ␉␉uint rlen = len - rnum;␊ |
749 | ␉␉rlen = dev->readBlock( cbuf, rlen );␊ |
750 | ␉␉uint i = 0;␊ |
751 | ␉␉while( i < rlen )␊ |
752 | ␉␉ buf[rnum++] = cbuf[i++];␊ |
753 | ␉ }␊ |
754 | ␉ delete[] cbuf;␊ |
755 | ␉}␊ |
756 | } else { // UCS-2 or UTF-16␊ |
757 | ␉if ( len == 1+rnum ) {␊ |
758 | ␉ int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;␊ |
759 | ␉ if ( c1 == EOF )␊ |
760 | ␉␉return rnum;␊ |
761 | ␉ int c2 = dev->getch();␊ |
762 | ␉ if ( c2 == EOF )␊ |
763 | ␉␉return rnum;␊ |
764 | ␉ if ( isNetworkOrder() )␊ |
765 | ␉␉buf[rnum++] = QChar( c2, c1 );␊ |
766 | ␉ else␊ |
767 | ␉␉buf[rnum++] = QChar( c1, c2 );␊ |
768 | ␉} else {␊ |
769 | ␉ char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible␊ |
770 | ␉ while ( !dev->atEnd() && rnum < len ) {␊ |
771 | ␉␉uint rlen = 2 * ( len-rnum );␊ |
772 | ␉␉if ( 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...␊ |
783 | ␉␉if ( (rlen & 1) == 1 )␊ |
784 | ␉␉ if ( !dev->atEnd() )␊ |
785 | ␉␉␉dev->ungetch( cbuf[--rlen] );␊ |
786 | ␉␉uint i = 0;␊ |
787 | ␉␉if ( isNetworkOrder() ) {␊ |
788 | ␉␉ while( i < rlen ) {␊ |
789 | ␉␉␉buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );␊ |
790 | ␉␉␉i+=2;␊ |
791 | ␉␉ }␊ |
792 | ␉␉} else {␊ |
793 | ␉␉ while( i < rlen ) {␊ |
794 | ␉␉␉buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );␊ |
795 | ␉␉␉i+=2;␊ |
796 | ␉␉ }␊ |
797 | ␉␉}␊ |
798 | ␉ }␊ |
799 | ␉ delete[] cbuf;␊ |
800 | ␉}␊ |
801 | }␊ |
802 | return rnum;␊ |
803 | }␊ |
804 | ␊ |
805 | ␊ |
806 | /*!␊ |
807 | Puts one character to the stream.␊ |
808 | */␊ |
809 | void QTextStream::ts_putc( QChar c )␊ |
810 | {␊ |
811 | #ifndef QT_NO_TEXTCODEC␊ |
812 | if ( mapper ) {␊ |
813 | ␉int len = 1;␊ |
814 | ␉QString s = c;␊ |
815 | ␉QCString block = mapper->fromUnicode( s, len );␊ |
816 | ␉dev->writeBlock( block, len );␊ |
817 | } else␊ |
818 | #endif␊ |
819 | if ( latin1 ) {␊ |
820 | ␉if( c.row() )␊ |
821 | ␉ dev->putch( '?' ); //######unknown character???␊ |
822 | ␉else␊ |
823 | ␉ dev->putch( c.cell() );␊ |
824 | } else {␊ |
825 | ␉if ( doUnicodeHeader ) {␊ |
826 | ␉ doUnicodeHeader = FALSE;␊ |
827 | ␉ ts_putc( QChar::byteOrderMark );␊ |
828 | ␉}␊ |
829 | ␉if ( 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 | */␊ |
844 | void QTextStream::ts_putc(int ch)␊ |
845 | {␊ |
846 | ts_putc(QChar((ushort)ch));␊ |
847 | }␊ |
848 | ␊ |
849 | bool QTextStream::ts_isdigit(QChar c)␊ |
850 | {␊ |
851 | return c.isDigit();␊ |
852 | }␊ |
853 | ␊ |
854 | bool QTextStream::ts_isspace( QChar c )␊ |
855 | {␊ |
856 | return c.isSpace();␊ |
857 | }␊ |
858 | ␊ |
859 | void QTextStream::ts_ungetc( QChar c )␊ |
860 | {␊ |
861 | if ( c.unicode() == 0xffff )␊ |
862 | ␉return;␊ |
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 | ␊ |
883 | QTextStream &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 | ␊ |
898 | QTextStream &QTextStream::writeRawBytes( const char* s, uint len )␊ |
899 | {␊ |
900 | dev->writeBlock( s, len );␊ |
901 | return *this;␊ |
902 | }␊ |
903 | ␊ |
904 | ␊ |
905 | QTextStream &QTextStream::writeBlock( const char* p, uint len )␊ |
906 | {␊ |
907 | if ( doUnicodeHeader ) {␊ |
908 | ␉doUnicodeHeader = FALSE;␊ |
909 | ␉if ( !mapper && !latin1 )␊ |
910 | ␉ ts_putc( QChar::byteOrderMark );␊ |
911 | }␊ |
912 | //All QCStrings and const char* are defined to be in Latin1␊ |
913 | if ( !mapper && latin1 ) {␊ |
914 | ␉dev->writeBlock( p, len );␊ |
915 | } else if ( !mapper && internalOrder ) {␊ |
916 | ␉QChar *u = new QChar[len];␊ |
917 | ␉for (uint i=0; i<len; i++)␊ |
918 | ␉ u[i] = p[i];␊ |
919 | ␉dev->writeBlock( (char*)u, len*sizeof(QChar) );␊ |
920 | ␉delete [] u;␊ |
921 | } else {␊ |
922 | ␉for (uint i=0; i<len; i++)␊ |
923 | ␉ ts_putc( (uchar)p[i] );␊ |
924 | }␊ |
925 | return *this;␊ |
926 | }␊ |
927 | ␊ |
928 | QTextStream &QTextStream::writeBlock( const QChar* p, uint len )␊ |
929 | {␊ |
930 | if ( !mapper && !latin1 && internalOrder ) {␊ |
931 | ␉if ( doUnicodeHeader ) {␊ |
932 | ␉ doUnicodeHeader = FALSE;␊ |
933 | ␉ ts_putc( QChar::byteOrderMark );␊ |
934 | ␉}␊ |
935 | ␉dev->writeBlock( (char*)p, sizeof(QChar)*len );␊ |
936 | } else {␊ |
937 | ␉for (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 | ␊ |
958 | void 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 | ␊ |
978 | void QTextStream::setDevice( QIODevice *iod )␊ |
979 | {␊ |
980 | if ( owndev ) {␊ |
981 | ␉delete dev;␊ |
982 | ␉owndev = 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 | ␊ |
993 | void 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 | ␊ |
1029 | QTextStream &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 | ␊ |
1041 | QTextStream &QTextStream::operator>>( QChar &c )␊ |
1042 | {␊ |
1043 | CHECK_STREAM_PRECOND␊ |
1044 | c = ts_getc();␊ |
1045 | return *this;␊ |
1046 | }␊ |
1047 | ␊ |
1048 | ␊ |
1049 | ulong QTextStream::input_bin()␊ |
1050 | {␊ |
1051 | ulong val = 0;␊ |
1052 | QChar ch = eat_ws();␊ |
1053 | int dv = ch.digitValue();␊ |
1054 | while ( dv == 0 || dv == 1 ) {␊ |
1055 | ␉val = ( val << 1 ) + dv;␊ |
1056 | ␉ch = ts_getc();␊ |
1057 | ␉dv = ch.digitValue();␊ |
1058 | }␊ |
1059 | if ( ch != QEOF )␊ |
1060 | ␉ts_ungetc( ch );␊ |
1061 | return val;␊ |
1062 | }␊ |
1063 | ␊ |
1064 | ulong QTextStream::input_oct()␊ |
1065 | {␊ |
1066 | ulong val = 0;␊ |
1067 | QChar ch = eat_ws();␊ |
1068 | int dv = ch.digitValue();␊ |
1069 | while ( dv >= 0 && dv <= 7 ) {␊ |
1070 | ␉val = ( val << 3 ) + dv;␊ |
1071 | ␉ch = ts_getc();␊ |
1072 | ␉dv = ch.digitValue();␊ |
1073 | }␊ |
1074 | if ( dv == 8 || dv == 9 ) {␊ |
1075 | ␉while ( ts_isdigit(ch) )␊ |
1076 | ␉ ch = ts_getc();␊ |
1077 | }␊ |
1078 | if ( ch != QEOF )␊ |
1079 | ␉ts_ungetc( ch );␊ |
1080 | return val;␊ |
1081 | }␊ |
1082 | ␊ |
1083 | ulong QTextStream::input_dec()␊ |
1084 | {␊ |
1085 | ulong val = 0;␊ |
1086 | QChar ch = eat_ws();␊ |
1087 | int dv = ch.digitValue();␊ |
1088 | while ( ts_isdigit(ch) ) {␊ |
1089 | ␉val = val * 10 + dv;␊ |
1090 | ␉ch = ts_getc();␊ |
1091 | ␉dv = ch.digitValue();␊ |
1092 | }␊ |
1093 | if ( ch != QEOF )␊ |
1094 | ␉ts_ungetc( ch );␊ |
1095 | return val;␊ |
1096 | }␊ |
1097 | ␊ |
1098 | ulong QTextStream::input_hex()␊ |
1099 | {␊ |
1100 | ulong val = 0;␊ |
1101 | QChar ch = eat_ws();␊ |
1102 | char c = ch;␊ |
1103 | while ( isxdigit(c) ) {␊ |
1104 | ␉val <<= 4;␊ |
1105 | ␉if ( ts_isdigit(c) )␊ |
1106 | ␉ val += c - '0';␊ |
1107 | ␉else␊ |
1108 | ␉ val += 10 + tolower(c) - 'a';␊ |
1109 | ␉c = ch = ts_getc();␊ |
1110 | }␊ |
1111 | if ( ch != QEOF )␊ |
1112 | ␉ts_ungetc( ch );␊ |
1113 | return val;␊ |
1114 | }␊ |
1115 | ␊ |
1116 | long QTextStream::input_int()␊ |
1117 | {␊ |
1118 | long val;␊ |
1119 | QChar ch;␊ |
1120 | char c;␊ |
1121 | switch ( flags() & basefield ) {␊ |
1122 | case bin:␊ |
1123 | ␉val = (long)input_bin();␊ |
1124 | ␉break;␊ |
1125 | case oct:␊ |
1126 | ␉val = (long)input_oct();␊ |
1127 | ␉break;␊ |
1128 | case dec:␊ |
1129 | ␉c = ch = eat_ws();␊ |
1130 | ␉if ( ch == QEOF ) {␊ |
1131 | ␉ val = 0;␊ |
1132 | ␉} else {␊ |
1133 | ␉ if ( !(c == '-' || c == '+') )␊ |
1134 | ␉␉ts_ungetc( ch );␊ |
1135 | ␉ if ( c == '-' ) {␊ |
1136 | ␉␉ulong v = input_dec();␊ |
1137 | ␉␉if ( v ) {␉␉// ensure that LONG_MIN can be read␊ |
1138 | ␉␉ v--;␊ |
1139 | ␉␉ val = -((long)v) - 1;␊ |
1140 | ␉␉} else {␊ |
1141 | ␉␉ val = 0;␊ |
1142 | ␉␉}␊ |
1143 | ␉ } else {␊ |
1144 | ␉␉val = (long)input_dec();␊ |
1145 | ␉ }␊ |
1146 | ␉}␊ |
1147 | ␉break;␊ |
1148 | case hex:␊ |
1149 | ␉val = (long)input_hex();␊ |
1150 | ␉break;␊ |
1151 | default:␊ |
1152 | ␉val = 0;␊ |
1153 | ␉c = ch = eat_ws();␊ |
1154 | ␉if ( c == '0' ) {␉␉// bin, oct or hex␊ |
1155 | ␉ c = ch = ts_getc();␊ |
1156 | ␉ if ( tolower(c) == 'x' )␊ |
1157 | ␉␉val = (long)input_hex();␊ |
1158 | ␉ else if ( tolower(c) == 'b' )␊ |
1159 | ␉␉val = (long)input_bin();␊ |
1160 | ␉ else {␉␉␉// octal␊ |
1161 | ␉␉ts_ungetc( ch );␊ |
1162 | ␉␉if ( 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 == '-' ) {␊ |
1174 | ␉␉if ( v ) {␉␉// ensure that LONG_MIN can be read␊ |
1175 | ␉␉ v--;␊ |
1176 | ␉␉ val = -((long)v) - 1;␊ |
1177 | ␉␉} else {␊ |
1178 | ␉␉ val = 0;␊ |
1179 | ␉␉}␊ |
1180 | ␉ } else {␊ |
1181 | ␉␉val = (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 | ␊ |
1193 | double 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 | ␊ |
1231 | ␉switch ( c ) {␊ |
1232 | ␉ case '+':␊ |
1233 | ␉ case '-':␊ |
1234 | ␉␉input = InputSign;␊ |
1235 | ␉␉break;␊ |
1236 | ␉ case '0': case '1': case '2': case '3': case '4':␊ |
1237 | ␉ case '5': case '6': case '7': case '8': case '9':␊ |
1238 | ␉␉input = InputDigit;␊ |
1239 | ␉␉break;␊ |
1240 | ␉ case '.':␊ |
1241 | ␉␉input = InputDot;␊ |
1242 | ␉␉break;␊ |
1243 | ␉ case 'e':␊ |
1244 | ␉ case 'E':␊ |
1245 | ␉␉input = InputExp;␊ |
1246 | ␉␉break;␊ |
1247 | ␉ default:␊ |
1248 | ␉␉input = 0;␊ |
1249 | ␉␉break;␊ |
1250 | ␉}␊ |
1251 | ␊ |
1252 | ␉state = table[state][input];␊ |
1253 | ␊ |
1254 | ␉if ( state == 0 || state == Done || i > 250 ) {␊ |
1255 | ␉ if ( i > 250 ) {␉␉␉// ignore rest of digits␊ |
1256 | ␉␉do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );␊ |
1257 | ␉ }␊ |
1258 | ␉ if ( c != QEOF )␊ |
1259 | ␉␉ts_ungetc( c );␊ |
1260 | ␉ buf[i] = '\0';␊ |
1261 | ␉ char *end;␊ |
1262 | ␉ return strtod( buf, &end );␊ |
1263 | ␉}␊ |
1264 | ␊ |
1265 | ␉buf[i++] = c;␊ |
1266 | ␉c = 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 | ␊ |
1280 | QTextStream &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 | ␊ |
1293 | QTextStream &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 | ␊ |
1306 | QTextStream &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 | ␊ |
1319 | QTextStream &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 | ␊ |
1332 | QTextStream &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 | ␊ |
1345 | QTextStream &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 | ␊ |
1358 | QTextStream &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 | ␊ |
1371 | QTextStream &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 | ␊ |
1383 | QTextStream &QTextStream::operator>>( char *s )␊ |
1384 | {␊ |
1385 | CHECK_STREAM_PRECOND␊ |
1386 | int maxlen = width( 0 );␊ |
1387 | QChar c = eat_ws();␊ |
1388 | if ( !maxlen )␊ |
1389 | ␉maxlen = -1;␊ |
1390 | while ( c != QEOF ) {␊ |
1391 | ␉if ( ts_isspace(c) || maxlen-- == 0 ) {␊ |
1392 | ␉ ts_ungetc( c );␊ |
1393 | ␉ break;␊ |
1394 | ␉}␊ |
1395 | ␉*s++ = c;␊ |
1396 | ␉c = 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 | ␊ |
1407 | QTextStream &QTextStream::operator>>( QString &str )␊ |
1408 | {␊ |
1409 | CHECK_STREAM_PRECOND␊ |
1410 | str=QString::fromLatin1("");␊ |
1411 | QChar␉c = eat_ws();␊ |
1412 | ␊ |
1413 | while ( c != QEOF ) {␊ |
1414 | ␉if ( ts_isspace(c) ) {␊ |
1415 | ␉ ts_ungetc( c );␊ |
1416 | ␉ break;␊ |
1417 | ␉}␊ |
1418 | ␉str += c;␊ |
1419 | ␉c = 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 | ␊ |
1428 | QTextStream &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 ) {␊ |
1439 | ␉if ( ts_isspace(c) ) {␊ |
1440 | ␉ ts_ungetc( c );␊ |
1441 | ␉ break;␊ |
1442 | ␉}␊ |
1443 | ␉if ( i >= buflen-1 ) {␊ |
1444 | ␉ if ( !dynbuf ) {␉␉␉// create dynamic buffer␊ |
1445 | ␉␉dynbuf = new QCString(buflen*2);␊ |
1446 | ␉␉memcpy( dynbuf->data(), s, i );␉// copy old data␊ |
1447 | ␉ } else if ( i >= (int)dynbuf->size()-1 ) {␊ |
1448 | ␉␉dynbuf->resize( dynbuf->size()*2 );␊ |
1449 | ␉ }␊ |
1450 | ␉ s = dynbuf->data();␊ |
1451 | ␉}␊ |
1452 | ␉s[i++] = c;␊ |
1453 | ␉c = 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 | ␊ |
1475 | QString QTextStream::readLine()␊ |
1476 | {␊ |
1477 | #if defined(CHECK_STATE)␊ |
1478 | if ( !dev ) {␊ |
1479 | ␉qWarning( "QTextStream::readLine: No device" );␊ |
1480 | ␉return 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 )␊ |
1490 | ␉return QString::null;␊ |
1491 | ␊ |
1492 | while ( c[pos] != QEOF && c[pos] != '\n' ) {␊ |
1493 | ␉pos++;␊ |
1494 | ␉if ( pos >= buf_size ) {␊ |
1495 | ␉ result += QString( c, pos );␊ |
1496 | ␉ pos = 0;␊ |
1497 | ␉}␊ |
1498 | ␉c[pos] = ts_getc();␊ |
1499 | }␊ |
1500 | result += QString( c, pos );␊ |
1501 | ␊ |
1502 | int len = (int)result.length();␊ |
1503 | if ( len && result[len-1] == '\r' )␊ |
1504 | ␉result.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 | ␊ |
1516 | QString QTextStream::read()␊ |
1517 | {␊ |
1518 | #if defined(CHECK_STATE)␊ |
1519 | if ( !dev ) {␊ |
1520 | ␉qWarning( "QTextStream::read: No device" );␊ |
1521 | ␉return 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 ) {␊ |
1531 | ␉num = ts_getbuf(buf,bufsize);␊ |
1532 | ␉// do a s/\r\n/\n␊ |
1533 | ␉start = 0;␊ |
1534 | ␉for ( i=0; i<num; i++ ) {␊ |
1535 | ␉ if ( buf[i] == '\r' ) {␊ |
1536 | ␉␉// Only skip single cr's preceding lf's␊ |
1537 | ␉␉if ( 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 {␊ |
1546 | ␉␉if ( skipped_cr ) {␊ |
1547 | ␉␉ if ( buf[i] != '\n' ) {␊ |
1548 | ␉␉␉// Should not have skipped it␊ |
1549 | ␉␉␉result += '\r';␊ |
1550 | ␉␉ }␊ |
1551 | ␉␉ skipped_cr = FALSE;␊ |
1552 | ␉␉}␊ |
1553 | ␉ }␊ |
1554 | ␉}␊ |
1555 | ␉if ( start < num )␊ |
1556 | ␉ result += QString( &buf[start], i-start );␊ |
1557 | ␉if ( 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 | */␊ |
1575 | QTextStream &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 | */␊ |
1585 | QTextStream &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 | ␊ |
1593 | QTextStream &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 | ␊ |
1605 | ␉case I_BASE_2:␉␉␉␉// output binary number␊ |
1606 | ␉ switch ( format & I_TYPE_MASK ) {␊ |
1607 | ␉␉case I_SHORT: len=16; break;␊ |
1608 | ␉␉case I_INT: len=sizeof(int)*8; break;␊ |
1609 | ␉␉case I_LONG: len=32; break;␊ |
1610 | ␉␉default: len = 0;␊ |
1611 | ␉ }␊ |
1612 | ␉ p = &buf[74];␉␉␉// go reverse order␊ |
1613 | ␉ *p = '\0';␊ |
1614 | ␉ while ( len-- ) {␊ |
1615 | ␉␉*--p = (char)(n&1) + '0';␊ |
1616 | ␉␉n >>= 1;␊ |
1617 | ␉␉if ( !n )␊ |
1618 | ␉␉ break;␊ |
1619 | ␉ }␊ |
1620 | ␉ if ( flags() & showbase ) {␉␉// show base␊ |
1621 | ␉␉*--p = (flags() & uppercase) ? 'B' : 'b';␊ |
1622 | ␉␉*--p = '0';␊ |
1623 | ␉ }␊ |
1624 | ␉ break;␊ |
1625 | ␊ |
1626 | ␉case I_BASE_8:␉␉␉␉// output octal number␊ |
1627 | ␉ p = &buf[74];␊ |
1628 | ␉ *p = '\0';␊ |
1629 | ␉ do {␊ |
1630 | ␉␉*--p = (char)(n&7) + '0';␊ |
1631 | ␉␉n >>= 3;␊ |
1632 | ␉ } while ( n );␊ |
1633 | ␉ if ( flags() & showbase )␊ |
1634 | ␉␉*--p = '0';␊ |
1635 | ␉ break;␊ |
1636 | ␊ |
1637 | ␉case I_BASE_16:␉␉␉␉// output hexadecimal number␊ |
1638 | ␉ p = &buf[74];␊ |
1639 | ␉ *p = '\0';␊ |
1640 | ␉ hexdigits = (flags() & uppercase) ?␊ |
1641 | ␉␉hexdigits_upper : hexdigits_lower;␊ |
1642 | ␉ do {␊ |
1643 | ␉␉*--p = hexdigits[(int)n&0xf];␊ |
1644 | ␉␉n >>= 4;␊ |
1645 | ␉ } while ( n );␊ |
1646 | ␉ if ( flags() & showbase ) {␊ |
1647 | ␉␉*--p = (flags() & uppercase) ? 'X' : 'x';␊ |
1648 | ␉␉*--p = '0';␊ |
1649 | ␉ }␊ |
1650 | ␉ break;␊ |
1651 | ␊ |
1652 | ␉default:␉␉␉␉// decimal base is default␊ |
1653 | ␉ p = &buf[74];␊ |
1654 | ␉ *p = '\0';␊ |
1655 | ␉ if ( neg )␊ |
1656 | ␉␉n = (ulong)(-(long)n);␊ |
1657 | ␉ do {␊ |
1658 | ␉␉*--p = ((int)(n%10)) + '0';␊ |
1659 | ␉␉n /= 10;␊ |
1660 | ␉ } while ( n );␊ |
1661 | ␉ if ( neg )␊ |
1662 | ␉␉*--p = '-';␊ |
1663 | ␉ else if ( flags() & showpos )␊ |
1664 | ␉␉*--p = '+';␊ |
1665 | ␉ if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {␊ |
1666 | ␉␉ts_putc( *p );␉␉␉// special case for internal␊ |
1667 | ␉␉++p;␉␉␉␉// padding␊ |
1668 | ␉␉fwidth--;␊ |
1669 | ␉␉return *this << (const char*)p;␊ |
1670 | ␉ }␊ |
1671 | }␊ |
1672 | if ( fwidth ) {␉␉␉␉// adjustment required␊ |
1673 | ␉if ( !(flags() & left) ) {␉␉// but NOT left adjustment␊ |
1674 | ␉ len = qstrlen(p);␊ |
1675 | ␉ int padlen = fwidth - len;␊ |
1676 | ␉ if ( padlen <= 0 ) {␉␉// no padding required␊ |
1677 | ␉␉writeBlock( p, len );␊ |
1678 | ␉ } else if ( padlen < (int)(p-buf) ) { // speeds up padding␊ |
1679 | ␉␉memset( p-padlen, (char)fillchar, padlen );␊ |
1680 | ␉␉writeBlock( p-padlen, padlen+len );␊ |
1681 | ␉ }␊ |
1682 | ␉ else␉␉␉␉// standard padding␊ |
1683 | ␉␉*this << (const char*)p;␊ |
1684 | ␉}␊ |
1685 | ␉else␊ |
1686 | ␉ *this << (const char*)p;␊ |
1687 | ␉fwidth = 0;␉␉␉␉// reset field width␊ |
1688 | }␊ |
1689 | else␊ |
1690 | ␉writeBlock( 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 | ␊ |
1700 | QTextStream &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 | ␊ |
1711 | QTextStream &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 | ␊ |
1722 | QTextStream &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 | ␊ |
1733 | QTextStream &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 | ␊ |
1744 | QTextStream &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 | ␊ |
1755 | QTextStream &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 | ␊ |
1765 | QTextStream &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 | ␊ |
1775 | QTextStream &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 )␊ |
1782 | ␉f_char = 'f';␊ |
1783 | else if ( (flags()&floatfield) == scientific )␊ |
1784 | ␉f_char = (flags() & uppercase) ? 'E' : 'e';␊ |
1785 | else␊ |
1786 | ␉f_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 )␊ |
1792 | ␉prec = 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␊ |
1806 | ␉writeBlock( 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 | ␊ |
1818 | QTextStream &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␊ |
1824 | ␉int padlen = fwidth - len;␊ |
1825 | ␉fwidth = 0;␉␉␉␉// reset width␊ |
1826 | ␉if ( padlen > 0 ) {␊ |
1827 | ␉ char *ppad;␊ |
1828 | ␉ if ( padlen > 46 ) {␉␉// create extra big fill buffer␊ |
1829 | ␉␉ppad = new char[padlen];␊ |
1830 | ␉␉CHECK_PTR( ppad );␊ |
1831 | ␉ } else {␊ |
1832 | ␉␉ppad = padbuf;␊ |
1833 | ␉ }␊ |
1834 | ␉ memset( ppad, (char)fillchar, padlen );␉// fill with fillchar␊ |
1835 | ␉ if ( !(flags() & left) ) {␊ |
1836 | ␉␉writeBlock( ppad, padlen );␊ |
1837 | ␉␉padlen = 0;␊ |
1838 | ␉ }␊ |
1839 | ␉ writeBlock( s, len );␊ |
1840 | ␉ if ( padlen )␊ |
1841 | ␉␉writeBlock( ppad, padlen );␊ |
1842 | ␉ if ( ppad != padbuf )␉␉// delete extra big fill buf␊ |
1843 | ␉␉delete[] 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 | ␊ |
1858 | QTextStream &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 | ␊ |
1867 | QTextStream &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␊ |
1873 | ␉if ( !(flags() & left) ) {␊ |
1874 | ␉ s1 = s.rightJustify(fwidth, (char)fillchar);␊ |
1875 | ␉} else {␊ |
1876 | ␉ s1 = s.leftJustify(fwidth, (char)fillchar);␊ |
1877 | ␉}␊ |
1878 | ␉fwidth = 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 | ␊ |
1891 | QTextStream &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 | ␊ |
2006 | QTextStream &bin( QTextStream &s )␊ |
2007 | {␊ |
2008 | s.setf(QTS::bin,QTS::basefield);␊ |
2009 | return s;␊ |
2010 | }␊ |
2011 | ␊ |
2012 | QTextStream &oct( QTextStream &s )␊ |
2013 | {␊ |
2014 | s.setf(QTS::oct,QTS::basefield);␊ |
2015 | return s;␊ |
2016 | }␊ |
2017 | ␊ |
2018 | QTextStream &dec( QTextStream &s )␊ |
2019 | {␊ |
2020 | s.setf(QTS::dec,QTS::basefield);␊ |
2021 | return s;␊ |
2022 | }␊ |
2023 | ␊ |
2024 | QTextStream &hex( QTextStream &s )␊ |
2025 | {␊ |
2026 | s.setf(QTS::hex,QTS::basefield);␊ |
2027 | return s;␊ |
2028 | }␊ |
2029 | ␊ |
2030 | QTextStream &endl( QTextStream &s )␊ |
2031 | {␊ |
2032 | return s << '\n';␊ |
2033 | }␊ |
2034 | ␊ |
2035 | QTextStream &flush( QTextStream &s )␊ |
2036 | {␊ |
2037 | if ( s.device() )␊ |
2038 | ␉s.device()->flush();␊ |
2039 | return s;␊ |
2040 | }␊ |
2041 | ␊ |
2042 | QTextStream &ws( QTextStream &s )␊ |
2043 | {␊ |
2044 | s.skipWhiteSpace();␊ |
2045 | return s;␊ |
2046 | }␊ |
2047 | ␊ |
2048 | QTextStream &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 | ␊ |
2155 | void QTextStream::setEncoding( Encoding e )␊ |
2156 | {␊ |
2157 | if ( d->sourceType == QTextStreamPrivate::String )␊ |
2158 | ␉return; // QString does not need any encoding␊ |
2159 | switch ( e ) {␊ |
2160 | case Unicode:␊ |
2161 | ␉mapper = 0;␊ |
2162 | ␉latin1 = FALSE;␊ |
2163 | ␉doUnicodeHeader = TRUE;␊ |
2164 | ␉internalOrder = TRUE;␊ |
2165 | ␉break;␊ |
2166 | case UnicodeUTF8:␊ |
2167 | #ifndef QT_NO_CODECS␊ |
2168 | ␉mapper = QTextCodec::codecForMib( 106 );␊ |
2169 | ␉latin1 = FALSE;␊ |
2170 | ␉doUnicodeHeader = TRUE;␊ |
2171 | ␉internalOrder = TRUE;␊ |
2172 | #else␊ |
2173 | ␉mapper = 0;␊ |
2174 | ␉latin1 = TRUE;␊ |
2175 | ␉doUnicodeHeader = TRUE;␊ |
2176 | #endif␊ |
2177 | ␉break;␊ |
2178 | case UnicodeNetworkOrder:␊ |
2179 | ␉mapper = 0;␊ |
2180 | ␉latin1 = FALSE;␊ |
2181 | ␉doUnicodeHeader = TRUE;␊ |
2182 | ␉internalOrder = QChar::networkOrdered();␊ |
2183 | ␉break;␊ |
2184 | case UnicodeReverse:␊ |
2185 | ␉mapper = 0;␊ |
2186 | ␉latin1 = FALSE;␊ |
2187 | ␉doUnicodeHeader = TRUE;␊ |
2188 | ␉internalOrder = !QChar::networkOrdered(); //reverse network ordered␊ |
2189 | ␉break;␊ |
2190 | case RawUnicode:␊ |
2191 | ␉mapper = 0;␊ |
2192 | ␉latin1 = FALSE;␊ |
2193 | ␉doUnicodeHeader = FALSE;␊ |
2194 | ␉internalOrder = TRUE;␊ |
2195 | ␉break;␊ |
2196 | case Locale:␊ |
2197 | ␉latin1 = TRUE; ␉␉␉␉// fallback to Latin 1␊ |
2198 | #ifndef QT_NO_TEXTCODEC␊ |
2199 | ␉mapper = QTextCodec::codecForLocale();␊ |
2200 | #if defined(_OS_WIN32_)␊ |
2201 | ␉if ( GetACP() == 1252 )␊ |
2202 | ␉ mapper = 0;␉␉␉␉// Optimized latin1 processing␊ |
2203 | #endif␊ |
2204 | ␉if ( mapper && mapper->mibEnum() == 4 )␊ |
2205 | #endif␊ |
2206 | ␉ mapper = 0;␉␉␉␉// Optimized latin1 processing␊ |
2207 | ␉doUnicodeHeader = TRUE; // If it reads as Unicode, accept it␊ |
2208 | ␉break;␊ |
2209 | case Latin1:␊ |
2210 | ␉mapper = 0;␊ |
2211 | ␉doUnicodeHeader = FALSE;␊ |
2212 | ␉latin1 = TRUE;␊ |
2213 | ␉break;␊ |
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 | ␊ |
2228 | void QTextStream::setCodec( QTextCodec *codec )␊ |
2229 | {␊ |
2230 | if ( d->sourceType == QTextStreamPrivate::String )␊ |
2231 | ␉return; // QString does not need any codec␊ |
2232 | mapper = codec;␊ |
2233 | doUnicodeHeader = FALSE;␊ |
2234 | }␊ |
2235 | #endif␊ |
2236 | ␊ |
2237 | #endif // QT_NO_TEXTSTREAM␊ |
2238 |