00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 static const int QTEXTSTREAM_BUFFERSIZE = 16384;
00026
00212 #include "qtextstream.h"
00213 #include "qbuffer.h"
00214 #include "qfile.h"
00215 #ifndef QT_NO_TEXTCODEC
00216 #include "qtextcodec.h"
00217 #endif
00218 #ifndef Q_OS_TEMP
00219 #include <locale.h>
00220 #endif
00221
00222 #include <stdlib.h>
00223
00224 #if defined QTEXTSTREAM_DEBUG
00225 #include <ctype.h>
00226
00227
00228
00229 static QByteArray qt_prettyDebug(const char *data, int len, int maxSize)
00230 {
00231 if (!data) return "(null)";
00232 QByteArray out;
00233 for (int i = 0; i < len; ++i) {
00234 char c = data[i];
00235 if (isprint(c)) {
00236 out += c;
00237 } else switch (c) {
00238 case '\n': out += "\\n"; break;
00239 case '\r': out += "\\r"; break;
00240 case '\t': out += "\\t"; break;
00241 default:
00242 QString tmp;
00243 tmp.sprintf("\\x%x", (unsigned int)(unsigned char)c);
00244 out += tmp.toLatin1();
00245 }
00246 }
00247
00248 if (len < maxSize)
00249 out += "...";
00250
00251 return out;
00252 }
00253 #endif
00254
00255
00256 #define Q_VOID
00257 #define CHECK_VALID_STREAM(x) do { \
00258 if (!d->string && !d->device) { \
00259 qWarning("QTextStream: No device"); \
00260 return x; \
00261 } } while (0)
00262
00263
00264 #define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(type) do { \
00265 Q_D(QTextStream); \
00266 CHECK_VALID_STREAM(*this); \
00267 qulonglong tmp; \
00268 switch (d->getNumber(&tmp)) { \
00269 case QTextStreamPrivate::npsOk: \
00270 i = (type)tmp; \
00271 break; \
00272 case QTextStreamPrivate::npsMissingDigit: \
00273 case QTextStreamPrivate::npsInvalidPrefix: \
00274 i = (type)0; \
00275 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
00276 break; \
00277 } \
00278 return *this; } while (0)
00279
00280 #define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(type) do { \
00281 Q_D(QTextStream); \
00282 CHECK_VALID_STREAM(*this); \
00283 double tmp; \
00284 if (d->getReal(&tmp)) { \
00285 f = (type)tmp; \
00286 } else { \
00287 f = (type)0; \
00288 setStatus(atEnd() ? QTextStream::ReadPastEnd : QTextStream::ReadCorruptData); \
00289 } \
00290 return *this; } while (0)
00291
00292 #ifndef QT_NO_QOBJECT
00293 class QDeviceClosedNotifier : public QObject
00294 {
00295 Q_OBJECT
00296 public:
00297 inline QDeviceClosedNotifier()
00298 { }
00299
00300 inline void setupDevice(QTextStream *stream, QIODevice *device)
00301 {
00302 disconnect();
00303 if (device)
00304 connect(device, SIGNAL(aboutToClose()), this, SLOT(flushStream()));
00305 this->stream = stream;
00306 }
00307
00308 public slots:
00309 inline void flushStream() { stream->flush(); }
00310
00311 private:
00312 QTextStream *stream;
00313 };
00314 #endif
00315
00316
00317 class QTextStreamPrivate
00318 {
00319 Q_DECLARE_PUBLIC(QTextStream)
00320 public:
00321 QTextStreamPrivate(QTextStream *q_ptr);
00322 ~QTextStreamPrivate();
00323 void reset();
00324
00325
00326 QIODevice *device;
00327 #ifndef QT_NO_QOBJECT
00328 QDeviceClosedNotifier deviceClosedNotifier;
00329 #endif
00330 bool deleteDevice;
00331
00332
00333 QString *string;
00334 int stringOffset;
00335 QIODevice::OpenMode stringOpenMode;
00336
00337 #ifndef QT_NO_TEXTCODEC
00338
00339 QTextCodec *codec;
00340 QTextCodec::ConverterState readConverterState;
00341 QTextCodec::ConverterState writeConverterState;
00342 bool autoDetectUnicode;
00343 #endif
00344
00345
00346 enum TokenDelimiter {
00347 Space,
00348 NotSpace,
00349 EndOfLine,
00350 EndOfFile
00351 };
00352
00353 bool scan(const QChar **ptr, int *tokenLength,
00354 int maxlen, TokenDelimiter delimiter);
00355 inline const QChar *readPtr() const;
00356 inline void consumeLastToken();
00357 inline void consume(int nchars);
00358 int lastTokenSize;
00359
00360
00361 enum NumberParsingStatus {
00362 npsOk,
00363 npsMissingDigit,
00364 npsInvalidPrefix
00365 };
00366
00367 inline bool write(const QString &data);
00368 inline bool getChar(QChar *ch);
00369 inline void ungetChar(const QChar &ch);
00370 NumberParsingStatus getNumber(qulonglong *l);
00371 bool getReal(double *f);
00372
00373 bool putNumber(qulonglong number, bool negative);
00374 inline bool putString(const QString &ch);
00375
00376
00377 bool fillReadBuffer(qint64 maxBytes = -1);
00378 bool flushWriteBuffer();
00379 QString writeBuffer;
00380 QString readBuffer;
00381 int readBufferOffset;
00382 qint64 readBufferStartDevicePos;
00383 QString endOfBufferState;
00384 #ifndef QT_NO_TEXTCODEC
00385 QTextCodec::ConverterState readBufferStartReadConverterState;
00386 #endif
00387 QString readBufferStartEndOfBufferState;
00388
00389
00390 int realNumberPrecision;
00391 int integerBase;
00392 int fieldWidth;
00393 QChar padChar;
00394 QTextStream::FieldAlignment fieldAlignment;
00395 QTextStream::RealNumberNotation realNumberNotation;
00396 QTextStream::NumberFlags numberFlags;
00397
00398
00399 QTextStream::Status status;
00400
00401 QTextStream *q_ptr;
00402 };
00403
00406 QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
00407 {
00408 this->q_ptr = q_ptr;
00409 reset();
00410 }
00411
00414 QTextStreamPrivate::~QTextStreamPrivate()
00415 {
00416 if (deleteDevice)
00417 delete device;
00418 }
00419
00420 #ifndef QT_NO_TEXTCODEC
00421 static void resetCodecConverterState(QTextCodec::ConverterState *state) {
00422 state->flags = QTextCodec::DefaultConversion;
00423 state->remainingChars = state->invalidChars =
00424 state->state_data[0] = state->state_data[1] = state->state_data[2] = 0;
00425 if (state->d) qFree(state->d);
00426 state->d = 0;
00427 }
00428
00429 static void copyConverterState(QTextCodec::ConverterState *dest, const QTextCodec::ConverterState *src)
00430 {
00431
00432
00433 dest->flags = src->flags;
00434 dest->invalidChars = src->invalidChars;
00435 dest->state_data[0] = src->state_data[0];
00436 dest->state_data[1] = src->state_data[1];
00437 dest->state_data[2] = src->state_data[2];
00438 dest->d = src->d;
00439 }
00440 #endif
00441
00444 void QTextStreamPrivate::reset()
00445 {
00446 realNumberPrecision = 6;
00447 integerBase = 0;
00448 fieldWidth = 0;
00449 padChar = QLatin1Char(' ');
00450 fieldAlignment = QTextStream::AlignRight;
00451 realNumberNotation = QTextStream::SmartNotation;
00452 numberFlags = 0;
00453
00454 device = 0;
00455 deleteDevice = false;
00456 string = 0;
00457 stringOffset = 0;
00458 stringOpenMode = QIODevice::NotOpen;
00459
00460 readBufferOffset = 0;
00461 readBufferStartDevicePos = 0;
00462 endOfBufferState.clear();
00463 lastTokenSize = 0;
00464
00465 #ifndef QT_NO_TEXTCODEC
00466 codec = QTextCodec::codecForLocale();
00467 ::resetCodecConverterState(&readConverterState);
00468 ::resetCodecConverterState(&writeConverterState);
00469 ::resetCodecConverterState(&readBufferStartReadConverterState);
00470 writeConverterState.flags |= QTextCodec::IgnoreHeader;
00471 autoDetectUnicode = true;
00472 #endif
00473 }
00474
00477 bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
00478 {
00479
00480
00481 Q_ASSERT(!string);
00482 Q_ASSERT(device);
00483
00484
00485 bool textModeEnabled = device->isTextModeEnabled();
00486 if (textModeEnabled)
00487 device->setTextModeEnabled(false);
00488
00489 #ifndef QT_NO_TEXTCODEC
00490
00491
00492 if (!codec || autoDetectUnicode) {
00493 autoDetectUnicode = false;
00494
00495 char bomBuffer[2];
00496 if (device->peek(bomBuffer, 2) == 2 && (uchar(bomBuffer[0]) == 0xff && uchar(bomBuffer[1]) == 0xfe
00497 || uchar(bomBuffer[0]) == 0xfe && uchar(bomBuffer[1]) == 0xff)) {
00498 codec = QTextCodec::codecForName("UTF-16");
00499 } else if (!codec) {
00500 codec = QTextCodec::codecForLocale();
00501 writeConverterState.flags |= QTextCodec::IgnoreHeader;
00502 }
00503 }
00504 #if defined (QTEXTSTREAM_DEBUG)
00505 qDebug("QTextStreamPrivate::fillReadBuffer(), using %s codec",
00506 codec->name().constData());
00507 #endif
00508 #endif
00509
00510
00511 char buf[QTEXTSTREAM_BUFFERSIZE];
00512 qint64 bytesRead = 0;
00513 #if defined(Q_OS_WIN)
00514
00515
00516
00517 QFile *file = 0;
00518 Q_UNUSED(file);
00519 if (device->isSequential()
00520 #if !defined(QT_NO_QOBJECT)
00521 && (file = qobject_cast<QFile *>(device)) && file->handle() == 0
00522 #endif
00523 ) {
00524 if (maxBytes != -1)
00525 bytesRead = device->readLine(buf, qMin<qint64>(sizeof(buf), maxBytes));
00526 else
00527 bytesRead = device->readLine(buf, sizeof(buf));
00528 } else
00529 #endif
00530 {
00531 if (maxBytes != -1)
00532 bytesRead = device->read(buf, qMin<qint64>(sizeof(buf), maxBytes));
00533 else
00534 bytesRead = device->read(buf, sizeof(buf));
00535 }
00536
00537 #if defined (QTEXTSTREAM_DEBUG)
00538 qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
00539 qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), sizeof(buf), int(bytesRead));
00540 #endif
00541 if (bytesRead <= 0)
00542 return false;
00543
00544 int oldReadBufferSize = readBuffer.size();
00545 readBuffer += endOfBufferState;
00546 #ifndef QT_NO_TEXTCODEC
00547
00548 readBuffer += codec->toUnicode(buf, bytesRead, &readConverterState);
00549 #else
00550 readBuffer += QString(QByteArray(buf, bytesRead));
00551 #endif
00552
00553
00554 if (textModeEnabled)
00555 device->setTextModeEnabled(true);
00556
00557
00558 if (readBuffer.size() > oldReadBufferSize && textModeEnabled) {
00559 QChar CR = QLatin1Char('\r');
00560 QChar LF = QLatin1Char('\n');
00561 QChar *writePtr = readBuffer.data();
00562 QChar *readPtr = readBuffer.data();
00563 QChar *endPtr = readBuffer.data() + readBuffer.size();
00564
00565 int n = 0;
00566 while (readPtr < endPtr) {
00567 if (readPtr + 1 < endPtr && *readPtr == CR && *(readPtr + 1) == LF) {
00568 *writePtr = LF;
00569 if (n < readBufferOffset)
00570 --readBufferOffset;
00571 ++readPtr;
00572 } else if (readPtr != writePtr) {
00573 *writePtr = *readPtr;
00574 }
00575
00576 ++n;
00577 ++writePtr;
00578 ++readPtr;
00579 }
00580 readBuffer.resize(writePtr - readBuffer.data());
00581
00582 if (readBuffer.endsWith(QLatin1Char('\r')) && !device->atEnd()) {
00583 endOfBufferState = QLatin1String("\r");
00584 readBuffer.chop(1);
00585 } else {
00586 endOfBufferState.clear();
00587 }
00588 }
00589
00590 #if defined (QTEXTSTREAM_DEBUG)
00591 qDebug("QTextStreamPrivate::fillReadBuffer() read %d bytes from device. readBuffer = [%s]", int(bytesRead),
00592 qt_prettyDebug(readBuffer.toLatin1(), readBuffer.size(), readBuffer.size()).data());
00593 #endif
00594 return true;
00595 }
00596
00599 bool QTextStreamPrivate::flushWriteBuffer()
00600 {
00601
00602
00603 if (string || !device)
00604 return false;
00605 if (writeBuffer.isEmpty())
00606 return true;
00607
00608 #if defined (Q_OS_WIN)
00609
00610 bool textModeEnabled = device->isTextModeEnabled();
00611 if (textModeEnabled) {
00612 device->setTextModeEnabled(false);
00613 writeBuffer.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
00614 }
00615 #endif
00616
00617 #ifndef QT_NO_TEXTCODEC
00618 if (!codec)
00619 codec = QTextCodec::codecForLocale();
00620 #if defined (QTEXTSTREAM_DEBUG)
00621 qDebug("QTextStreamPrivate::flushWriteBuffer(), using %s codec (%s generating BOM)",
00622 codec->name().constData(), writeConverterState.flags & QTextCodec::IgnoreHeader ? "not" : "");
00623 #endif
00624
00625
00626 QByteArray data = codec->fromUnicode(writeBuffer.data(), writeBuffer.size(), &writeConverterState);
00627 #else
00628 QByteArray data = writeBuffer.toLocal8Bit();
00629 #endif
00630 writeBuffer.clear();
00631
00632
00633 qint64 bytesWritten = device->write(data);
00634 #if defined (QTEXTSTREAM_DEBUG)
00635 qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d",
00636 qt_prettyDebug(data.constData(), qMin(data.size(),32), data.size()).constData(), int(bytesWritten));
00637 #endif
00638 if (bytesWritten <= 0)
00639 return false;
00640
00641 #if defined (Q_OS_WIN)
00642
00643 if (textModeEnabled)
00644 device->setTextModeEnabled(true);
00645 #endif
00646
00647
00648 #ifndef QT_NO_QOBJECT
00649 QFile *file = qobject_cast<QFile *>(device);
00650 bool flushed = file && file->flush();
00651 #else
00652 bool flushed = true;
00653 #endif
00654
00655 #if defined (QTEXTSTREAM_DEBUG)
00656 qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes",
00657 int(bytesWritten));
00658 #endif
00659 return flushed && bytesWritten == qint64(data.size());
00660 }
00661
00668 bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenDelimiter delimiter)
00669 {
00670 int totalSize = 0;
00671 int delimSize = 0;
00672 bool consumeDelimiter = false;
00673 bool foundToken = false;
00674 int startOffset = device ? readBufferOffset : stringOffset;
00675 QChar lastChar;
00676
00677 bool canStillReadFromDevice = true;
00678 do {
00679 int endOffset;
00680 const QChar *chPtr;
00681 if (device) {
00682 chPtr = readBuffer.constData();
00683 endOffset = readBuffer.size();
00684 } else {
00685 chPtr = string->constData();
00686 endOffset = string->size();
00687 }
00688 chPtr += startOffset;
00689
00690 for (; !foundToken && startOffset < endOffset && (!maxlen || totalSize < maxlen); ++startOffset) {
00691 const QChar ch = *chPtr++;
00692 ++totalSize;
00693
00694 if (delimiter == Space && ch.isSpace()) {
00695 foundToken = true;
00696 delimSize = 1;
00697 } else if (delimiter == NotSpace && !ch.isSpace()) {
00698 foundToken = true;
00699 delimSize = 1;
00700 } else if (delimiter == EndOfLine && ch == QLatin1Char('\n')) {
00701 foundToken = true;
00702 delimSize = (lastChar == QLatin1Char('\r')) ? 2 : 1;
00703 consumeDelimiter = true;
00704 }
00705
00706 lastChar = ch;
00707 }
00708 } while (!foundToken
00709 && (!maxlen || totalSize < maxlen)
00710 && (device && (canStillReadFromDevice = fillReadBuffer())));
00711
00712
00713
00714
00715 if (!foundToken && (!maxlen || totalSize < maxlen)
00716 && (totalSize == 0
00717 || (string && stringOffset + totalSize < string->size())
00718 || (device && !device->atEnd() && canStillReadFromDevice))) {
00719 #if defined (QTEXTSTREAM_DEBUG)
00720 qDebug("QTextStreamPrivate::scan() did not find the token.");
00721 #endif
00722 return false;
00723 }
00724
00725
00726
00727 if (totalSize > 0 && !foundToken && delimiter == EndOfLine) {
00728 if (((string && stringOffset + totalSize == string->size()) || (device && device->atEnd()))
00729 && lastChar == QLatin1Char('\r')) {
00730 consumeDelimiter = true;
00731 ++delimSize;
00732 }
00733 }
00734
00735
00736 if (length)
00737 *length = totalSize - delimSize;
00738 if (ptr)
00739 *ptr = readPtr();
00740
00741
00742
00743 lastTokenSize = totalSize;
00744 if (!consumeDelimiter)
00745 lastTokenSize -= delimSize;
00746
00747 #if defined (QTEXTSTREAM_DEBUG)
00748 qDebug("QTextStreamPrivate::scan(%p, %p, %d, %x) token length = %d, delimiter = %d",
00749 ptr, length, maxlen, (int)delimiter, totalSize - delimSize, delimSize);
00750 #endif
00751 return true;
00752 }
00753
00756 inline const QChar *QTextStreamPrivate::readPtr() const
00757 {
00758 Q_ASSERT(readBufferOffset <= readBuffer.size());
00759 if (string)
00760 return string->constData() + stringOffset;
00761 return readBuffer.constData() + readBufferOffset;
00762 }
00763
00766 inline void QTextStreamPrivate::consumeLastToken()
00767 {
00768 if (lastTokenSize)
00769 consume(lastTokenSize);
00770 lastTokenSize = 0;
00771 }
00772
00775 inline void QTextStreamPrivate::consume(int size)
00776 {
00777 #if defined (QTEXTSTREAM_DEBUG)
00778 qDebug("QTextStreamPrivate::consume(%d)", size);
00779 #endif
00780 if (string) {
00781 stringOffset += size;
00782 if (stringOffset > string->size())
00783 stringOffset = string->size();
00784 } else {
00785 readBufferOffset += size;
00786 if (readBufferOffset >= readBuffer.size()) {
00787 readBufferOffset = 0;
00788 readBuffer.clear();
00789 readBufferStartDevicePos = device->pos();
00790 #ifndef QT_NO_TEXTCODEC
00791 copyConverterState(&readBufferStartReadConverterState, &readConverterState);
00792 #endif
00793 readBufferStartEndOfBufferState = endOfBufferState;
00794 }
00795 }
00796 }
00797
00800 inline bool QTextStreamPrivate::write(const QString &data)
00801 {
00802 if (string) {
00803
00804 string->append(data);
00805 } else {
00806 writeBuffer += data;
00807 if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
00808 return flushWriteBuffer();
00809 }
00810 return true;
00811 }
00812
00815 inline bool QTextStreamPrivate::getChar(QChar *ch)
00816 {
00817 if ((string && stringOffset == string->size())
00818 || (device && readBuffer.isEmpty() && !fillReadBuffer())) {
00819 if (ch)
00820 *ch = 0;
00821 return false;
00822 }
00823 if (ch)
00824 *ch = *readPtr();
00825 consume(1);
00826 return true;
00827 }
00828
00831 inline void QTextStreamPrivate::ungetChar(const QChar &ch)
00832 {
00833 if (string) {
00834 if (stringOffset == 0)
00835 string->prepend(ch);
00836 else
00837 (*string)[--stringOffset] = ch;
00838 return;
00839 }
00840
00841 if (readBufferOffset == 0) {
00842 readBuffer.prepend(ch);
00843 return;
00844 }
00845
00846 readBuffer[--readBufferOffset] = ch;
00847 }
00848
00851 inline bool QTextStreamPrivate::putString(const QString &s)
00852 {
00853 QString tmp = s;
00854
00855
00856 int padSize = fieldWidth - s.size();
00857 if (padSize > 0) {
00858 QString pad(padSize > 0 ? padSize : 0, padChar);
00859 if (fieldAlignment == QTextStream::AlignLeft) {
00860 tmp.append(QString(padSize, padChar));
00861 } else if (fieldAlignment == QTextStream::AlignRight) {
00862 tmp.prepend(QString(padSize, padChar));
00863 } else if (fieldAlignment == QTextStream::AlignCenter) {
00864 tmp.prepend(QString(padSize/2, padChar));
00865 tmp.append(QString(padSize - padSize/2, padChar));
00866 }
00867 }
00868
00869 #if defined (QTEXTSTREAM_DEBUG)
00870 QByteArray a = s.toUtf8();
00871 QByteArray b = tmp.toUtf8();
00872 qDebug("QTextStreamPrivate::putString(\"%s\") calls write(\"%s\")",
00873 qt_prettyDebug(a.constData(), a.size(), qMax(16, a.size())).constData(),
00874 qt_prettyDebug(b.constData(), b.size(), qMax(16, b.size())).constData());
00875 #endif
00876 return write(tmp);
00877 }
00878
00885 QTextStream::QTextStream()
00886 : d_ptr(new QTextStreamPrivate(this))
00887 {
00888 #if defined (QTEXTSTREAM_DEBUG)
00889 qDebug("QTextStream::QTextStream()");
00890 #endif
00891 Q_D(QTextStream);
00892 d->status = Ok;
00893 }
00894
00898 QTextStream::QTextStream(QIODevice *device)
00899 : d_ptr(new QTextStreamPrivate(this))
00900 {
00901 #if defined (QTEXTSTREAM_DEBUG)
00902 qDebug("QTextStream::QTextStream(QIODevice *device == *%p)",
00903 device);
00904 #endif
00905 Q_D(QTextStream);
00906 d->device = device;
00907 #ifndef QT_NO_QOBJECT
00908 d->deviceClosedNotifier.setupDevice(this, d->device);
00909 #endif
00910 d->status = Ok;
00911 }
00912
00917 QTextStream::QTextStream(QString *string, QIODevice::OpenMode openMode)
00918 : d_ptr(new QTextStreamPrivate(this))
00919 {
00920 #if defined (QTEXTSTREAM_DEBUG)
00921 qDebug("QTextStream::QTextStream(QString *string == *%p, openMode = %d)",
00922 string, int(openMode));
00923 #endif
00924 Q_D(QTextStream);
00925 d->string = string;
00926 d->stringOpenMode = openMode;
00927 d->status = Ok;
00928 }
00929
00935 QTextStream::QTextStream(QByteArray *array, QIODevice::OpenMode openMode)
00936 : d_ptr(new QTextStreamPrivate(this))
00937 {
00938 #if defined (QTEXTSTREAM_DEBUG)
00939 qDebug("QTextStream::QTextStream(QByteArray *array == *%p, openMode = %d)",
00940 array, int(openMode));
00941 #endif
00942 Q_D(QTextStream);
00943 d->device = new QBuffer(array);
00944 d->device->open(openMode);
00945 d->deleteDevice = true;
00946 #ifndef QT_NO_QOBJECT
00947 d->deviceClosedNotifier.setupDevice(this, d->device);
00948 #endif
00949 d->status = Ok;
00950 }
00951
00973 QTextStream::QTextStream(const QByteArray &array, QIODevice::OpenMode openMode)
00974 : d_ptr(new QTextStreamPrivate(this))
00975 {
00976 #if defined (QTEXTSTREAM_DEBUG)
00977 qDebug("QTextStream::QTextStream(const QByteArray &array == *(%p), openMode = %d)",
00978 &array, int(openMode));
00979 #endif
00980 QBuffer *buffer = new QBuffer;
00981 buffer->setData(array);
00982 buffer->open(openMode);
00983
00984 Q_D(QTextStream);
00985 d->device = buffer;
00986 d->deleteDevice = true;
00987 #ifndef QT_NO_QOBJECT
00988 d->deviceClosedNotifier.setupDevice(this, d->device);
00989 #endif
00990 d->status = Ok;
00991 }
00992
01008 QTextStream::QTextStream(FILE *fileHandle, QIODevice::OpenMode openMode)
01009 : d_ptr(new QTextStreamPrivate(this))
01010 {
01011 #if defined (QTEXTSTREAM_DEBUG)
01012 qDebug("QTextStream::QTextStream(FILE *fileHandle = %p, openMode = %d)",
01013 fileHandle, int(openMode));
01014 #endif
01015 QFile *file = new QFile;
01016 file->open(fileHandle, openMode);
01017
01018 Q_D(QTextStream);
01019 d->device = file;
01020 d->deleteDevice = true;
01021 #ifndef QT_NO_QOBJECT
01022 d->deviceClosedNotifier.setupDevice(this, d->device);
01023 #endif
01024 d->status = Ok;
01025 }
01026
01033 QTextStream::~QTextStream()
01034 {
01035 Q_D(QTextStream);
01036 #if defined (QTEXTSTREAM_DEBUG)
01037 qDebug("QTextStream::~QTextStream()");
01038 #endif
01039 if (!d->writeBuffer.isEmpty())
01040 d->flushWriteBuffer();
01041
01042 delete d;
01043 d_ptr = 0;
01044 }
01045
01051 void QTextStream::reset()
01052 {
01053 Q_D(QTextStream);
01054
01055 d->realNumberPrecision = 6;
01056 d->integerBase = 0;
01057 d->fieldWidth = 0;
01058 d->padChar = QLatin1Char(' ');
01059 d->fieldAlignment = QTextStream::AlignRight;
01060 d->realNumberNotation = QTextStream::SmartNotation;
01061 d->numberFlags = 0;
01062 }
01063
01069 void QTextStream::flush()
01070 {
01071 Q_D(QTextStream);
01072 d->flushWriteBuffer();
01073 }
01074
01079 bool QTextStream::seek(qint64 pos)
01080 {
01081 Q_D(QTextStream);
01082 d->lastTokenSize = 0;
01083
01084 if (d->device) {
01085
01086 d->flushWriteBuffer();
01087 if (!d->device->seek(pos))
01088 return false;
01089 d->readBuffer.clear();
01090 d->readBufferOffset = 0;
01091 d->endOfBufferState.clear();
01092 d->readBufferStartDevicePos = d->device->pos();
01093 d->readBufferStartEndOfBufferState.clear();
01094
01095 #ifndef QT_NO_TEXTCODEC
01096
01097 ::resetCodecConverterState(&d->readConverterState);
01098 ::resetCodecConverterState(&d->readBufferStartReadConverterState);
01099 ::resetCodecConverterState(&d->writeConverterState);
01100 #endif
01101 return true;
01102 }
01103
01104
01105 if (d->string && pos <= d->string->size()) {
01106 d->stringOffset = int(pos);
01107 return true;
01108 }
01109 return false;
01110 }
01111
01125 qint64 QTextStream::pos() const
01126 {
01127 Q_D(const QTextStream);
01128 if (d->device) {
01129
01130 if (d->readBuffer.isEmpty() && d->endOfBufferState.isEmpty())
01131 return d->device->pos();
01132 if (d->device->isSequential())
01133 return 0;
01134
01135
01136 if (!d->device->seek(d->readBufferStartDevicePos))
01137 return qint64(-1);
01138
01139
01140 QTextStreamPrivate *thatd = const_cast<QTextStreamPrivate *>(d);
01141 thatd->readBuffer.clear();
01142
01143
01144
01145 #ifndef QT_NO_TEXTCODEC
01146 ::copyConverterState(&thatd->readConverterState, &d->readBufferStartReadConverterState);
01147 #endif
01148 thatd->endOfBufferState = d->readBufferStartEndOfBufferState;
01149 #ifndef QT_NO_TEXTCODEC
01150 if (d->readBufferStartDevicePos == 0)
01151 thatd->autoDetectUnicode = true;
01152 #endif
01153
01154
01155
01156 int oldReadBufferOffset = d->readBufferOffset;
01157 while (d->readBuffer.size() < oldReadBufferOffset) {
01158 if (!thatd->fillReadBuffer(1))
01159 return qint64(-1);
01160 }
01161 thatd->readBufferOffset = oldReadBufferOffset;
01162
01163
01164 return d->device->pos();
01165 }
01166
01167 if (d->string)
01168 return d->stringOffset;
01169
01170 qWarning("QTextStream::pos: no device");
01171 return qint64(-1);
01172 }
01173
01185 void QTextStream::skipWhiteSpace()
01186 {
01187 Q_D(QTextStream);
01188 CHECK_VALID_STREAM(Q_VOID);
01189 d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
01190 d->consumeLastToken();
01191 }
01192
01200 void QTextStream::setDevice(QIODevice *device)
01201 {
01202 Q_D(QTextStream);
01203 flush();
01204 if (d->deleteDevice) {
01205 #ifndef QT_NO_QOBJECT
01206 d->deviceClosedNotifier.disconnect();
01207 #endif
01208 delete d->device;
01209 d->deleteDevice = false;
01210 }
01211 d->device = device;
01212 d->string = 0;
01213 #ifndef QT_NO_QOBJECT
01214 d->deviceClosedNotifier.setupDevice(this, d->device);
01215 #endif
01216 }
01217
01224 QIODevice *QTextStream::device() const
01225 {
01226 Q_D(const QTextStream);
01227 return d->device;
01228 }
01229
01237 void QTextStream::setString(QString *string, QIODevice::OpenMode openMode)
01238 {
01239 Q_D(QTextStream);
01240 flush();
01241 if (d->deleteDevice) {
01242 #ifndef QT_NO_QOBJECT
01243 d->deviceClosedNotifier.disconnect();
01244 #endif
01245 delete d->device;
01246 d->deleteDevice = false;
01247 }
01248 d->string = string;
01249 d->device = 0;
01250 d->stringOpenMode = openMode;
01251 }
01252
01259 QString *QTextStream::string() const
01260 {
01261 Q_D(const QTextStream);
01262 return d->string;
01263 }
01264
01273 void QTextStream::setFieldAlignment(FieldAlignment mode)
01274 {
01275 Q_D(QTextStream);
01276 d->fieldAlignment = mode;
01277 }
01278
01284 QTextStream::FieldAlignment QTextStream::fieldAlignment() const
01285 {
01286 Q_D(const QTextStream);
01287 return d->fieldAlignment;
01288 }
01289
01314 void QTextStream::setPadChar(QChar ch)
01315 {
01316 Q_D(QTextStream);
01317 d->padChar = ch;
01318 }
01319
01325 QChar QTextStream::padChar() const
01326 {
01327 Q_D(const QTextStream);
01328 return d->padChar;
01329 }
01330
01338 void QTextStream::setFieldWidth(int width)
01339 {
01340 Q_D(QTextStream);
01341 d->fieldWidth = width;
01342 }
01343
01349 int QTextStream::fieldWidth() const
01350 {
01351 Q_D(const QTextStream);
01352 return d->fieldWidth;
01353 }
01354
01363 void QTextStream::setNumberFlags(NumberFlags flags)
01364 {
01365 Q_D(QTextStream);
01366 d->numberFlags = flags;
01367 }
01368
01374 QTextStream::NumberFlags QTextStream::numberFlags() const
01375 {
01376 Q_D(const QTextStream);
01377 return d->numberFlags;
01378 }
01379
01390 void QTextStream::setIntegerBase(int base)
01391 {
01392 Q_D(QTextStream);
01393 d->integerBase = base;
01394 }
01395
01402 int QTextStream::integerBase() const
01403 {
01404 Q_D(const QTextStream);
01405 return d->integerBase;
01406 }
01407
01416 void QTextStream::setRealNumberNotation(RealNumberNotation notation)
01417 {
01418 Q_D(QTextStream);
01419 d->realNumberNotation = notation;
01420 }
01421
01427 QTextStream::RealNumberNotation QTextStream::realNumberNotation() const
01428 {
01429 Q_D(const QTextStream);
01430 return d->realNumberNotation;
01431 }
01432
01440 void QTextStream::setRealNumberPrecision(int precision)
01441 {
01442 Q_D(QTextStream);
01443 d->realNumberPrecision = precision;
01444 }
01445
01452 int QTextStream::realNumberPrecision() const
01453 {
01454 Q_D(const QTextStream);
01455 return d->realNumberPrecision;
01456 }
01457
01464 QTextStream::Status QTextStream::status() const
01465 {
01466 Q_D(const QTextStream);
01467 return d->status;
01468 }
01469
01477 void QTextStream::resetStatus()
01478 {
01479 Q_D(QTextStream);
01480 d->status = Ok;
01481 }
01482
01490 void QTextStream::setStatus(Status status)
01491 {
01492 Q_D(QTextStream);
01493 if (d->status == Ok)
01494 d->status = status;
01495 }
01496
01503 bool QTextStream::atEnd() const
01504 {
01505 Q_D(const QTextStream);
01506 CHECK_VALID_STREAM(true);
01507
01508 if (d->string)
01509 return d->string->size() == d->stringOffset;
01510 return d->readBuffer.isEmpty() && d->device->atEnd();
01511 }
01512
01523 QString QTextStream::readAll()
01524 {
01525 Q_D(QTextStream);
01526 CHECK_VALID_STREAM(QString());
01527
01528 const QChar *readPtr;
01529 int length;
01530 if (!d->scan(&readPtr, &length, 0, QTextStreamPrivate::EndOfFile))
01531 return QString();
01532
01533 QString tmp = QString(readPtr, length);
01534 d->consumeLastToken();
01535 return tmp;
01536 }
01537
01556 QString QTextStream::readLine(qint64 maxlen)
01557 {
01558 Q_D(QTextStream);
01559 CHECK_VALID_STREAM(QString());
01560
01561 const QChar *readPtr;
01562 int length;
01563 if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine))
01564 return QString();
01565
01566 QString tmp = QString(readPtr, length);
01567 d->consumeLastToken();
01568 return tmp;
01569 }
01570
01579 QString QTextStream::read(qint64 maxlen)
01580 {
01581 Q_D(QTextStream);
01582 CHECK_VALID_STREAM(QString());
01583
01584 if (maxlen <= 0)
01585 return QString::fromLatin1("");
01586
01587 const QChar *readPtr;
01588 int length;
01589 if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfFile))
01590 return QString();
01591
01592 QString tmp = QString(readPtr, length);
01593 d->consumeLastToken();
01594 return tmp;
01595 }
01596
01599 QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret)
01600 {
01601 scan(0, 0, 0, NotSpace);
01602 consumeLastToken();
01603
01604
01605 int base = integerBase;
01606 if (base == 0) {
01607 QChar ch;
01608 if (!getChar(&ch))
01609 return npsInvalidPrefix;
01610 if (ch == QLatin1Char('0')) {
01611 QChar ch2;
01612 if (!getChar(&ch2)) {
01613
01614 *ret = 0;
01615 return npsOk;
01616 }
01617 ch2 = ch2.toLower();
01618
01619 if (ch2 == QLatin1Char('x')) {
01620 base = 16;
01621 } else if (ch2 == QLatin1Char('b')) {
01622 base = 2;
01623 } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) {
01624 base = 8;
01625 } else {
01626 base = 10;
01627 }
01628 ungetChar(ch2);
01629 } else if (ch == QLatin1Char('-') || ch == QLatin1Char('+') || ch.isDigit()) {
01630 base = 10;
01631 } else {
01632 ungetChar(ch);
01633 return npsInvalidPrefix;
01634 }
01635 ungetChar(ch);
01636
01637
01638
01639 }
01640
01641 qulonglong val=0;
01642 switch (base) {
01643 case 2: {
01644 QChar pf1, pf2, dig;
01645
01646 if (!getChar(&pf1) || pf1 != QLatin1Char('0'))
01647 return npsInvalidPrefix;
01648 if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('b'))
01649 return npsInvalidPrefix;
01650
01651 int ndigits = 0;
01652 while (getChar(&dig)) {
01653 int n = dig.toLower().unicode();
01654 if (n == '0' || n == '1') {
01655 val <<= 1;
01656 val += n - '0';
01657 } else {
01658 ungetChar(dig);
01659 break;
01660 }
01661 ndigits++;
01662 }
01663 if (ndigits == 0) {
01664
01665 ungetChar(pf2);
01666 ungetChar(pf1);
01667 return npsMissingDigit;
01668 }
01669 break;
01670 }
01671 case 8: {
01672 QChar pf, dig;
01673
01674 if (!getChar(&pf) || pf != QLatin1Char('0'))
01675 return npsInvalidPrefix;
01676
01677 int ndigits = 0;
01678 while (getChar(&dig)) {
01679 int n = dig.toLower().unicode();
01680 if (n >= '0' && n <= '7') {
01681 val *= 8;
01682 val += n - '0';
01683 } else {
01684 ungetChar(dig);
01685 break;
01686 }
01687 ndigits++;
01688 }
01689 if (ndigits == 0) {
01690
01691 ungetChar(pf);
01692 return npsMissingDigit;
01693 }
01694 break;
01695 }
01696 case 10: {
01697
01698 QChar sign;
01699 int ndigits = 0;
01700 if (!getChar(&sign))
01701 return npsMissingDigit;
01702 if (sign != QLatin1Char('-') && sign != QLatin1Char('+')) {
01703 if (!sign.isDigit()) {
01704 ungetChar(sign);
01705 return npsMissingDigit;
01706 }
01707 val += sign.digitValue();
01708 ndigits++;
01709 }
01710
01711 QChar ch;
01712 while (getChar(&ch)) {
01713 if (ch.isDigit()) {
01714 val *= 10;
01715 val += ch.digitValue();
01716 } else {
01717 ungetChar(ch);
01718 break;
01719 }
01720 ndigits++;
01721 }
01722 if (ndigits == 0)
01723 return npsMissingDigit;
01724 if (sign == QLatin1Char('-')) {
01725 qlonglong ival = qlonglong(val);
01726 if (ival > 0)
01727 ival = -ival;
01728 val = qulonglong(ival);
01729 }
01730 break;
01731 }
01732 case 16: {
01733 QChar pf1, pf2, dig;
01734
01735 if (!getChar(&pf1) || pf1 != QLatin1Char('0'))
01736 return npsInvalidPrefix;
01737 if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('x'))
01738 return npsInvalidPrefix;
01739
01740 int ndigits = 0;
01741 while (getChar(&dig)) {
01742 int n = dig.toLower().unicode();
01743 if (n >= '0' && n <= '9') {
01744 val <<= 4;
01745 val += n - '0';
01746 } else if (n >= 'a' && n <= 'f') {
01747 val <<= 4;
01748 val += 10 + (n - 'a');
01749 } else {
01750 ungetChar(dig);
01751 break;
01752 }
01753 ndigits++;
01754 }
01755 if (ndigits == 0) {
01756 return npsMissingDigit;
01757 }
01758 break;
01759 }
01760 default:
01761
01762 return npsInvalidPrefix;
01763 }
01764
01765 if (ret)
01766 *ret = val;
01767 return npsOk;
01768 }
01769
01773 bool QTextStreamPrivate::getReal(double *f)
01774 {
01775
01776
01777
01778 enum ParserState {
01779 Init = 0,
01780 Sign = 1,
01781 Mantissa = 2,
01782 Dot = 3,
01783 Abscissa = 4,
01784 ExpMark = 5,
01785 ExpSign = 6,
01786 Exponent = 7,
01787 Done = 8
01788 };
01789 enum InputToken {
01790 None = 0,
01791 InputSign = 1,
01792 InputDigit = 2,
01793 InputDot = 3,
01794 InputExp = 4
01795 };
01796
01797 static uchar table[8][5] = {
01798
01799 { 0, Sign, Mantissa, Dot, 0 },
01800 { 0, 0, Mantissa, Dot, 0 },
01801 { Done, Done, Mantissa, Dot, ExpMark },
01802 { 0, 0, Abscissa, 0, 0 },
01803 { Done, Done, Abscissa, Done, ExpMark },
01804 { 0, ExpSign, Exponent, 0, 0 },
01805 { 0, 0, Exponent, 0, 0 },
01806 { Done, Done, Exponent, Done, Done }
01807 };
01808
01809 ParserState state = Init;
01810 InputToken input = None;
01811
01812 scan(0, 0, 0, NotSpace);
01813 consumeLastToken();
01814
01815 const int BufferSize = 128;
01816 char buf[BufferSize];
01817 int i = 0;
01818
01819 QChar c;
01820 while (getChar(&c)) {
01821 switch (c.unicode()) {
01822 case '+':
01823 case '-':
01824 input = InputSign;
01825 break;
01826 case '0': case '1': case '2': case '3': case '4':
01827 case '5': case '6': case '7': case '8': case '9':
01828 input = InputDigit;
01829 break;
01830 case '.':
01831 input = InputDot;
01832 break;
01833 case 'e':
01834 case 'E':
01835 input = InputExp;
01836 break;
01837 default:
01838 input = None;
01839 break;
01840 }
01841
01842 state = ParserState(table[state][input]);
01843
01844 if (state == Init || state == Done || i > (BufferSize - 5)) {
01845 ungetChar(c);
01846 if (i > (BufferSize - 5)) {
01847 while (getChar(&c)) {
01848 if (!c.isDigit()) {
01849 ungetChar(c);
01850 break;
01851 }
01852 }
01853 }
01854 break;
01855 }
01856
01857 buf[i++] = c.toLatin1();
01858 }
01859
01860 if (i == 0)
01861 return false;
01862
01863 buf[i] = '\0';
01864
01865 if (f)
01866 *f = strtod(buf, 0);
01867 return true;
01868 }
01869
01884 QTextStream &QTextStream::operator>>(QChar &c)
01885 {
01886 Q_D(QTextStream);
01887 CHECK_VALID_STREAM(*this);
01888 d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
01889 if (!d->getChar(&c))
01890 setStatus(ReadPastEnd);
01891 return *this;
01892 }
01893
01903 QTextStream &QTextStream::operator>>(char &c)
01904 {
01905 QChar ch;
01906 *this >> ch;
01907 c = ch.toLatin1();
01908 return *this;
01909 }
01910
01935 QTextStream &QTextStream::operator>>(signed short &i)
01936 {
01937 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed short);
01938 }
01939
01945 QTextStream &QTextStream::operator>>(unsigned short &i)
01946 {
01947 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned short);
01948 }
01949
01955 QTextStream &QTextStream::operator>>(signed int &i)
01956 {
01957 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed int);
01958 }
01959
01965 QTextStream &QTextStream::operator>>(unsigned int &i)
01966 {
01967 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned int);
01968 }
01969
01975 QTextStream &QTextStream::operator>>(signed long &i)
01976 {
01977 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(signed long);
01978 }
01979
01985 QTextStream &QTextStream::operator>>(unsigned long &i)
01986 {
01987 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(unsigned long);
01988 }
01989
01995 QTextStream &QTextStream::operator>>(qlonglong &i)
01996 {
01997 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(qlonglong);
01998 }
01999
02005 QTextStream &QTextStream::operator>>(qulonglong &i)
02006 {
02007 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR(qulonglong);
02008 }
02009
02018 QTextStream &QTextStream::operator>>(float &f)
02019 {
02020 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(float);
02021 }
02022
02028 QTextStream &QTextStream::operator>>(double &f)
02029 {
02030 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR(double);
02031 }
02032
02040 QTextStream &QTextStream::operator>>(QString &str)
02041 {
02042 Q_D(QTextStream);
02043 CHECK_VALID_STREAM(*this);
02044
02045 str.clear();
02046 d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
02047 d->consumeLastToken();
02048
02049 const QChar *ptr;
02050 int length;
02051 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
02052 setStatus(ReadPastEnd);
02053 return *this;
02054 }
02055
02056 str = QString(ptr, length);
02057 d->consumeLastToken();
02058 return *this;
02059 }
02060
02068 QTextStream &QTextStream::operator>>(QByteArray &array)
02069 {
02070 Q_D(QTextStream);
02071 CHECK_VALID_STREAM(*this);
02072
02073 array.clear();
02074 d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
02075 d->consumeLastToken();
02076
02077 const QChar *ptr;
02078 int length;
02079 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
02080 setStatus(ReadPastEnd);
02081 return *this;
02082 }
02083
02084 for (int i = 0; i < length; ++i)
02085 array += ptr[i].toLatin1();
02086
02087 d->consumeLastToken();
02088 return *this;
02089 }
02090
02104 QTextStream &QTextStream::operator>>(char *c)
02105 {
02106 Q_D(QTextStream);
02107 *c = 0;
02108 CHECK_VALID_STREAM(*this);
02109 d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
02110 d->consumeLastToken();
02111
02112 const QChar *ptr;
02113 int length;
02114 if (!d->scan(&ptr, &length, 0, QTextStreamPrivate::Space)) {
02115 setStatus(ReadPastEnd);
02116 return *this;
02117 }
02118
02119 for (int i = 0; i < length; ++i)
02120 *c++ = ptr[i].toLatin1();
02121 *c = '\0';
02122 d->consumeLastToken();
02123 return *this;
02124 }
02125
02128 bool QTextStreamPrivate::putNumber(qulonglong number, bool negative)
02129 {
02130 QString tmp;
02131 if (negative)
02132 tmp = QLatin1Char('-');
02133 else if (numberFlags & QTextStream::ForceSign)
02134 tmp = QLatin1Char('+');
02135
02136 if (numberFlags & QTextStream::ShowBase) {
02137 switch (integerBase) {
02138 case 2: tmp += QLatin1String("0b"); break;
02139 case 8: tmp += QLatin1String("0"); break;
02140 case 16: tmp += QLatin1String("0x"); break;
02141 default: break;
02142 }
02143 }
02144
02145 tmp += QString::number(number, integerBase ? integerBase : 10);
02146 if (numberFlags & QTextStream::UppercaseBase)
02147 tmp = tmp.toUpper();
02148
02149 return putString(tmp);
02150 }
02151
02156 QTextStream &QTextStream::operator<<(QBool b)
02157 {
02158 return *this << bool(b);
02159 }
02160
02167 QTextStream &QTextStream::operator<<(QChar c)
02168 {
02169 Q_D(QTextStream);
02170 CHECK_VALID_STREAM(*this);
02171 d->putString(QString(c));
02172 return *this;
02173 }
02174
02180 QTextStream &QTextStream::operator<<(char c)
02181 {
02182 Q_D(QTextStream);
02183 CHECK_VALID_STREAM(*this);
02184 d->putString(QString(QChar::fromAscii(c)));
02185 return *this;
02186 }
02187
02196 QTextStream &QTextStream::operator<<(signed short i)
02197 {
02198 Q_D(QTextStream);
02199 CHECK_VALID_STREAM(*this);
02200 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
02201 return *this;
02202 }
02203
02209 QTextStream &QTextStream::operator<<(unsigned short i)
02210 {
02211 Q_D(QTextStream);
02212 CHECK_VALID_STREAM(*this);
02213 d->putNumber((qulonglong)i, false);
02214 return *this;
02215 }
02216
02222 QTextStream &QTextStream::operator<<(signed int i)
02223 {
02224 Q_D(QTextStream);
02225 CHECK_VALID_STREAM(*this);
02226 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
02227 return *this;
02228 }
02229
02235 QTextStream &QTextStream::operator<<(unsigned int i)
02236 {
02237 Q_D(QTextStream);
02238 CHECK_VALID_STREAM(*this);
02239 d->putNumber((qulonglong)i, false);
02240 return *this;
02241 }
02242
02248 QTextStream &QTextStream::operator<<(signed long i)
02249 {
02250 Q_D(QTextStream);
02251 CHECK_VALID_STREAM(*this);
02252 d->putNumber((qulonglong)qAbs(qlonglong(i)), i < 0);
02253 return *this;
02254 }
02255
02261 QTextStream &QTextStream::operator<<(unsigned long i)
02262 {
02263 Q_D(QTextStream);
02264 CHECK_VALID_STREAM(*this);
02265 d->putNumber((qulonglong)i, false);
02266 return *this;
02267 }
02268
02274 QTextStream &QTextStream::operator<<(qlonglong i)
02275 {
02276 Q_D(QTextStream);
02277 CHECK_VALID_STREAM(*this);
02278 d->putNumber((qulonglong)qAbs(i), i < 0);
02279 return *this;
02280 }
02281
02287 QTextStream &QTextStream::operator<<(qulonglong i)
02288 {
02289 Q_D(QTextStream);
02290 CHECK_VALID_STREAM(*this);
02291 d->putNumber(i, false);
02292 return *this;
02293 }
02294
02306 QTextStream &QTextStream::operator<<(float f)
02307 {
02308 return *this << double(f);
02309 }
02310
02316 QTextStream &QTextStream::operator<<(double f)
02317 {
02318 Q_D(QTextStream);
02319 CHECK_VALID_STREAM(*this);
02320
02321 char f_char;
02322 char format[16];
02323 if (d->realNumberNotation == FixedNotation)
02324 f_char = 'f';
02325 else if (d->realNumberNotation == ScientificNotation)
02326 f_char = (d->numberFlags & UppercaseBase) ? 'E' : 'e';
02327 else
02328 f_char = (d->numberFlags & UppercaseBase) ? 'G' : 'g';
02329
02330
02331 register char *fs = format;
02332
02333
02334 *fs++ = '%';
02335 if (d->numberFlags & QTextStream::ForcePoint)
02336 *fs++ = '#';
02337 *fs++ = '.';
02338 int prec = d->realNumberPrecision;
02339 if (prec > 99)
02340 prec = 99;
02341 if (prec >= 10) {
02342 *fs++ = prec / 10 + '0';
02343 *fs++ = prec % 10 + '0';
02344 } else {
02345 *fs++ = prec + '0';
02346 }
02347 *fs++ = 'l';
02348 *fs++ = f_char;
02349 *fs = '\0';
02350 QString num;
02351 num.sprintf(format, f);
02352
02353 if (f > 0.0 && (d->numberFlags & ForceSign))
02354 num.prepend(QLatin1Char('+'));
02355
02356 d->putString(num);
02357 return *this;
02358 }
02359
02368 QTextStream &QTextStream::operator<<(const QString &string)
02369 {
02370 Q_D(QTextStream);
02371 CHECK_VALID_STREAM(*this);
02372 d->putString(string);
02373 return *this;
02374 }
02375
02382 QTextStream &QTextStream::operator<<(const QByteArray &array)
02383 {
02384 Q_D(QTextStream);
02385 CHECK_VALID_STREAM(*this);
02386 d->putString(QString::fromAscii(array.constData(), array.length()));
02387 return *this;
02388 }
02389
02406 QTextStream &QTextStream::operator<<(const char *string)
02407 {
02408 Q_D(QTextStream);
02409 CHECK_VALID_STREAM(*this);
02410 d->putString(QLatin1String(string));
02411 return *this;
02412 }
02413
02419 QTextStream &QTextStream::operator<<(const void *ptr)
02420 {
02421 Q_D(QTextStream);
02422 CHECK_VALID_STREAM(*this);
02423 int oldBase = d->integerBase;
02424 NumberFlags oldFlags = d->numberFlags;
02425 d->integerBase = 16;
02426 d->numberFlags |= ShowBase;
02427 d->putNumber(reinterpret_cast<quintptr>(ptr), false);
02428 d->integerBase = oldBase;
02429 d->numberFlags = oldFlags;
02430 return *this;
02431 }
02432
02441 QTextStream &bin(QTextStream &stream)
02442 {
02443 stream.setIntegerBase(2);
02444 return stream;
02445 }
02446
02455 QTextStream &oct(QTextStream &stream)
02456 {
02457 stream.setIntegerBase(8);
02458 return stream;
02459 }
02460
02469 QTextStream &dec(QTextStream &stream)
02470 {
02471 stream.setIntegerBase(10);
02472 return stream;
02473 }
02474
02483 QTextStream &hex(QTextStream &stream)
02484 {
02485 stream.setIntegerBase(16);
02486 return stream;
02487 }
02488
02497 QTextStream &showbase(QTextStream &stream)
02498 {
02499 stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase);
02500 return stream;
02501 }
02502
02511 QTextStream &forcesign(QTextStream &stream)
02512 {
02513 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign);
02514 return stream;
02515 }
02516
02525 QTextStream &forcepoint(QTextStream &stream)
02526 {
02527 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForcePoint);
02528 return stream;
02529 }
02530
02539 QTextStream &noshowbase(QTextStream &stream)
02540 {
02541 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ShowBase);
02542 return stream;
02543 }
02544
02553 QTextStream &noforcesign(QTextStream &stream)
02554 {
02555 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForceSign);
02556 return stream;
02557 }
02558
02567 QTextStream &noforcepoint(QTextStream &stream)
02568 {
02569 stream.setNumberFlags(stream.numberFlags() &= ~QTextStream::ForcePoint);
02570 return stream;
02571 }
02572
02581 QTextStream &uppercasebase(QTextStream &stream)
02582 {
02583 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseBase);
02584 return stream;
02585 }
02586
02595 QTextStream &uppercasedigits(QTextStream &stream)
02596 {
02597 stream.setNumberFlags(stream.numberFlags() | QTextStream::UppercaseDigits);
02598 return stream;
02599 }
02600
02609 QTextStream &lowercasebase(QTextStream &stream)
02610 {
02611 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseBase);
02612 return stream;
02613 }
02614
02623 QTextStream &lowercasedigits(QTextStream &stream)
02624 {
02625 stream.setNumberFlags(stream.numberFlags() & ~QTextStream::UppercaseDigits);
02626 return stream;
02627 }
02628
02637 QTextStream &fixed(QTextStream &stream)
02638 {
02639 stream.setRealNumberNotation(QTextStream::FixedNotation);
02640 return stream;
02641 }
02642
02651 QTextStream &scientific(QTextStream &stream)
02652 {
02653 stream.setRealNumberNotation(QTextStream::ScientificNotation);
02654 return stream;
02655 }
02656
02665 QTextStream &left(QTextStream &stream)
02666 {
02667 stream.setFieldAlignment(QTextStream::AlignLeft);
02668 return stream;
02669 }
02670
02679 QTextStream &right(QTextStream &stream)
02680 {
02681 stream.setFieldAlignment(QTextStream::AlignRight);
02682 return stream;
02683 }
02684
02693 QTextStream ¢er(QTextStream &stream)
02694 {
02695 stream.setFieldAlignment(QTextStream::AlignCenter);
02696 return stream;
02697 }
02698
02715 QTextStream &endl(QTextStream &stream)
02716 {
02717 return stream << QLatin1Char('\n') << flush;
02718 }
02719
02727 QTextStream &flush(QTextStream &stream)
02728 {
02729 stream.flush();
02730 return stream;
02731 }
02732
02740 QTextStream &reset(QTextStream &stream)
02741 {
02742 stream.reset();
02743 return stream;
02744 }
02745
02753 QTextStream &ws(QTextStream &stream)
02754 {
02755 stream.skipWhiteSpace();
02756 return stream;
02757 }
02758
02780 #ifndef QT_NO_TEXTCODEC
02781
02789 QTextStream &bom(QTextStream &stream)
02790 {
02791 stream.setGenerateByteOrderMark(true);
02792 return stream;
02793 }
02794
02806 void QTextStream::setCodec(QTextCodec *codec)
02807 {
02808 Q_D(QTextStream);
02809 d->codec = codec;
02810 }
02811
02827 void QTextStream::setCodec(const char *codecName)
02828 {
02829 Q_D(QTextStream);
02830 QTextCodec *codec = QTextCodec::codecForName(codecName);
02831 if (codec)
02832 d->codec = codec;
02833 }
02834
02840 QTextCodec *QTextStream::codec() const
02841 {
02842 Q_D(const QTextStream);
02843 return d->codec;
02844 }
02845
02857 void QTextStream::setAutoDetectUnicode(bool enabled)
02858 {
02859 Q_D(QTextStream);
02860 d->autoDetectUnicode = enabled;
02861 }
02862
02869 bool QTextStream::autoDetectUnicode() const
02870 {
02871 Q_D(const QTextStream);
02872 return d->autoDetectUnicode;
02873 }
02874
02883 void QTextStream::setGenerateByteOrderMark(bool generate)
02884 {
02885 Q_D(QTextStream);
02886 if (d->writeBuffer.isEmpty()) {
02887 if (generate)
02888 d->writeConverterState.flags &= ~QTextCodec::IgnoreHeader;
02889 else
02890 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
02891 }
02892 }
02893
02900 bool QTextStream::generateByteOrderMark() const
02901 {
02902 Q_D(const QTextStream);
02903 return (d->writeConverterState.flags & QTextCodec::IgnoreHeader) == 0;
02904 }
02905
02906 #endif
02907
02908 #ifdef QT3_SUPPORT
02909
02967 int QTextStream::flagsInternal() const
02968 {
02969 Q_D(const QTextStream);
02970
02971 int f = 0;
02972 switch (d->fieldAlignment) {
02973 case AlignLeft: f |= left; break;
02974 case AlignRight: f |= right; break;
02975 case AlignCenter: f |= internal; break;
02976 default:
02977 break;
02978 }
02979 switch (d->integerBase) {
02980 case 2: f |= bin; break;
02981 case 8: f |= oct; break;
02982 case 10: f |= dec; break;
02983 case 16: f |= hex; break;
02984 default:
02985 break;
02986 }
02987 switch (d->realNumberNotation) {
02988 case FixedNotation: f |= fixed; break;
02989 case ScientificNotation: f |= scientific; break;
02990 default:
02991 break;
02992 }
02993 if (d->numberFlags & ShowBase)
02994 f |= showbase;
02995 if (d->numberFlags & ForcePoint)
02996 f |= showpoint;
02997 if (d->numberFlags & ForceSign)
02998 f |= showpos;
02999 if (d->numberFlags & UppercaseBase)
03000 f |= uppercase;
03001 return f;
03002 }
03003
03006 int QTextStream::flagsInternal(int newFlags)
03007 {
03008 int oldFlags = flagsInternal();
03009
03010 if (newFlags & left)
03011 setFieldAlignment(AlignLeft);
03012 else if (newFlags & right)
03013 setFieldAlignment(AlignRight);
03014 else if (newFlags & internal)
03015 setFieldAlignment(AlignCenter);
03016
03017 if (newFlags & bin)
03018 setIntegerBase(2);
03019 else if (newFlags & oct)
03020 setIntegerBase(8);
03021 else if (newFlags & dec)
03022 setIntegerBase(10);
03023 else if (newFlags & hex)
03024 setIntegerBase(16);
03025
03026 if (newFlags & showbase)
03027 setNumberFlags(numberFlags() | ShowBase);
03028 if (newFlags & showpos)
03029 setNumberFlags(numberFlags() | ForceSign);
03030 if (newFlags & showpoint)
03031 setNumberFlags(numberFlags() | ForcePoint);
03032 if (newFlags & uppercase)
03033 setNumberFlags(numberFlags() | UppercaseBase);
03034
03035 if (newFlags & fixed)
03036 setRealNumberNotation(FixedNotation);
03037 else if (newFlags & scientific)
03038 setRealNumberNotation(ScientificNotation);
03039
03040 return oldFlags;
03041 }
03042
03043 #ifndef QT_NO_TEXTCODEC
03044
03047 void QTextStream::setEncoding(Encoding encoding)
03048 {
03049 Q_D(QTextStream);
03050 ::resetCodecConverterState(&d->readConverterState);
03051 ::resetCodecConverterState(&d->writeConverterState);
03052
03053 switch (encoding) {
03054 case Locale:
03055 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03056 setCodec(QTextCodec::codecForLocale());
03057 d->autoDetectUnicode = true;
03058 break;
03059 case Latin1:
03060 d->readConverterState.flags |= QTextCodec::IgnoreHeader;
03061 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03062 setCodec(QTextCodec::codecForName("ISO-8859-1"));
03063 d->autoDetectUnicode = false;
03064 break;
03065 case Unicode:
03066 setCodec(QTextCodec::codecForName("UTF-16"));
03067 d->autoDetectUnicode = false;
03068 break;
03069 case RawUnicode:
03070 d->readConverterState.flags |= QTextCodec::IgnoreHeader;
03071 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03072 setCodec(QTextCodec::codecForName("UTF-16"));
03073 d->autoDetectUnicode = false;
03074 break;
03075 case UnicodeNetworkOrder:
03076 d->readConverterState.flags |= QTextCodec::IgnoreHeader;
03077 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03078 setCodec(QTextCodec::codecForName("UTF-16BE"));
03079 d->autoDetectUnicode = false;
03080 break;
03081 case UnicodeReverse:
03082 d->readConverterState.flags |= QTextCodec::IgnoreHeader;
03083 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03084 setCodec(QTextCodec::codecForName("UTF-16LE"));
03085 d->autoDetectUnicode = false;
03086 break;
03087 case UnicodeUTF8:
03088 d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
03089 setCodec(QTextCodec::codecForName("UTF-8"));
03090 d->autoDetectUnicode = true;
03091 break;
03092 }
03093 }
03094 #endif
03095
03208 #endif
03209
03210 #ifndef QT_NO_QOBJECT
03211 #include "qtextstream.moc"
03212 #endif