diff options
Diffstat (limited to 'src/corelib/io/qtextstream.cpp')
-rw-r--r-- | src/corelib/io/qtextstream.cpp | 169 |
1 files changed, 118 insertions, 51 deletions
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 571875c508..6149a04a74 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -233,6 +233,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; #if defined QTEXTSTREAM_DEBUG #include <ctype.h> +#include "private/qtools_p.h" QT_BEGIN_NAMESPACE @@ -250,10 +251,16 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxSize) case '\n': out += "\\n"; break; case '\r': out += "\\r"; break; case '\t': out += "\\t"; break; - default: - QString tmp; - tmp.sprintf("\\x%x", (unsigned int)(unsigned char)c); - out += tmp.toLatin1(); + default: { + const char buf[] = { + '\\', + 'x', + QtMiscUtils::toHexLower(uchar(c) / 16), + QtMiscUtils::toHexLower(uchar(c) % 16), + 0 + }; + out += buf; + } } } @@ -460,7 +467,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) #if defined (QTEXTSTREAM_DEBUG) qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d", - qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), sizeof(buf), int(bytesRead)); + qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), int(sizeof(buf)), int(bytesRead)); #endif if (bytesRead <= 0) @@ -681,15 +688,9 @@ bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenD && (!maxlen || totalSize < maxlen) && (device && (canStillReadFromDevice = fillReadBuffer()))); - // if the token was not found, but we reached the end of input, - // then we accept what we got. if we are not at the end of input, - // we return false. - if (!foundToken && (!maxlen || totalSize < maxlen) - && (totalSize == 0 - || (string && stringOffset + totalSize < string->size()) - || (device && !device->atEnd() && canStillReadFromDevice))) { + if (totalSize == 0) { #if defined (QTEXTSTREAM_DEBUG) - qDebug("QTextStreamPrivate::scan() did not find the token."); + qDebug("QTextStreamPrivate::scan() reached the end of input."); #endif return false; } @@ -812,13 +813,28 @@ inline void QTextStreamPrivate::restoreToSavedConverterState() /*! \internal */ -inline void QTextStreamPrivate::write(const QString &data) +void QTextStreamPrivate::write(const QChar *data, int len) +{ + if (string) { + // ### What about seek()?? + string->append(data, len); + } else { + writeBuffer.append(data, len); + if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE) + flushWriteBuffer(); + } +} + +/*! + \internal +*/ +inline void QTextStreamPrivate::write(QChar ch) { if (string) { // ### What about seek()?? - string->append(data); + string->append(ch); } else { - writeBuffer += data; + writeBuffer += ch; if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE) flushWriteBuffer(); } @@ -865,45 +881,53 @@ inline void QTextStreamPrivate::ungetChar(QChar ch) /*! \internal */ -inline void QTextStreamPrivate::putString(const QString &s, bool number) +inline void QTextStreamPrivate::putChar(QChar ch) +{ + if (params.fieldWidth > 0) + putString(&ch, 1); + else + write(ch); +} + +/*! + \internal +*/ +void QTextStreamPrivate::putString(const QChar *data, int len, bool number) { - QString tmp = s; + QString pad; + int padLeft = 0, padRight = 0; // handle padding - int padSize = params.fieldWidth - s.size(); + int padSize = params.fieldWidth - len; if (padSize > 0) { - QString pad(padSize, params.padChar); + pad = QString(padSize, params.padChar); switch (params.fieldAlignment) { case QTextStream::AlignLeft: - tmp.append(pad); + padRight = padSize; break; case QTextStream::AlignRight: case QTextStream::AlignAccountingStyle: - tmp.prepend(pad); + padLeft = padSize; if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) { - const QChar sign = s.size() > 0 ? s.at(0) : QChar(); + const QChar sign = len > 0 ? data[0] : QChar(); if (sign == locale.negativeSign() || sign == locale.positiveSign()) { - QChar *data = tmp.data(); - data[padSize] = tmp.at(0); - data[0] = sign; + // write the sign before the padding, then skip it later + write(&sign, 1); + ++data; + --len; } - } + } break; case QTextStream::AlignCenter: - tmp.prepend(QString(padSize/2, params.padChar)); - tmp.append(QString(padSize - padSize/2, params.padChar)); + padLeft = padSize/2; + padRight = padSize - padSize/2; break; } } -#if defined (QTEXTSTREAM_DEBUG) - QByteArray a = s.toUtf8(); - QByteArray b = tmp.toUtf8(); - qDebug("QTextStreamPrivate::putString(\"%s\") calls write(\"%s\")", - qt_prettyDebug(a.constData(), a.size(), qMax(16, a.size())).constData(), - qt_prettyDebug(b.constData(), b.size(), qMax(16, b.size())).constData()); -#endif - write(tmp); + write(pad.constData(), padLeft); + write(data, len); + write(pad.constData(), padRight); } /*! @@ -1563,17 +1587,60 @@ QString QTextStream::readAll() */ QString QTextStream::readLine(qint64 maxlen) { + QString line; + + readLine(&line, maxlen); + return line; +} + +/*! + \since 5.5 + + Reads one line of text from the stream into \a line. + If \a line is 0, the read line is not stored. + + The maximum allowed line length is set to \a maxlen. If + the stream contains lines longer than this, then the lines will be + split after \a maxlen characters and returned in parts. + + If \a maxlen is 0, the lines can be of any length. + + The resulting line has no trailing end-of-line characters ("\\n" + or "\\r\\n"), so calling QString::trimmed() can be unnecessary. + + If \a line has sufficient capacity for the data that is about to be + read, this function may not need to allocate new memory. Because of + this, it can be faster than the other readLine() overload. + + Returns \c false if the stream has read to the end of the file or + an error has occurred; otherwise returns \c true. The contents in + \a line before the call are discarded in any case. + + \sa readAll(), QIODevice::readLine() +*/ +bool QTextStream::readLine(QString *line, qint64 maxlen) +{ Q_D(QTextStream); - CHECK_VALID_STREAM(QString()); + // keep in sync with CHECK_VALID_STREAM + if (!d->string && !d->device) { + qWarning("QTextStream: No device"); + if (line && !line->isNull()) + line->resize(0); + return false; + } const QChar *readPtr; int length; - if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) - return QString(); + if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) { + if (line && !line->isNull()) + line->resize(0); + return false; + } - QString tmp = QString(readPtr, length); + if (Q_LIKELY(line)) + line->setUnicode(readPtr, length); d->consumeLastToken(); - return tmp; + return true; } /*! @@ -2231,7 +2298,7 @@ QTextStream &QTextStream::operator<<(QChar c) { Q_D(QTextStream); CHECK_VALID_STREAM(*this); - d->putString(QString(c)); + d->putChar(c); return *this; } @@ -2244,7 +2311,7 @@ QTextStream &QTextStream::operator<<(char c) { Q_D(QTextStream); CHECK_VALID_STREAM(*this); - d->putString(QString(QChar::fromLatin1(c))); + d->putChar(QChar::fromLatin1(c)); return *this; } |