From de71c8a6f827b7ac1a0c394a92c113edbe6d5df7 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 30 Oct 2014 19:34:19 +0400 Subject: Add QTextStream::readLine() overload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The most common use case for QTextStream::readLine() is reading a file line by line in a loop. The existing readLine() method allocates new memory for each line, that results in a loss of speed. The introduced overload can use already allocated memory. Besides it allows you to not think about filesystem specifics. The current QFile documentation suggests a separate way to read files from /proc filesystem. With this overload it's possible to use the same idiom in all cases: QTextStream in(&file); QString line; while (in.readLine(&line)) { process_line(line); } The idea was inspired by the blog post of Ivan Čukić: http://ivan.fomentgroup.org/blog/2014/10/03/api-design-and-impact-on-the-performance-qt-vs-stl-example/ Change-Id: I0c62b4a52681870589bc099905e83ed69e03dd40 Reviewed-by: Martin Smith Reviewed-by: David Faure Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qtextstream.cpp | 53 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'src/corelib/io/qtextstream.cpp') diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 771067fa14..ff3b007b21 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1580,18 +1580,61 @@ QString QTextStream::readAll() \sa readAll(), QIODevice::readLine() */ 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; } /*! -- cgit v1.2.3