diff options
author | Juha Vuolle <juha.vuolle@qt.io> | 2023-12-12 14:08:04 +0200 |
---|---|---|
committer | Juha Vuolle <juha.vuolle@qt.io> | 2024-01-10 16:36:05 +0200 |
commit | 4da14a67a6157c415f8228a8bae7d6b0f895df7c (patch) | |
tree | bab39226dbc78dad60b680b8df80ef06326e1f7d /src/network/access | |
parent | 9aaf1a031befc39244290c63f3905896934f6082 (diff) |
Add streaming text support to QRestReply
Provides the possibility to read text data as it arrives, instead
of needing to wait until the whole body is received.
Pick-to: 6.7
Task-number: QTBUG-119002
Change-Id: I64f90148fd41a77c4ae2d5dbd6194a924a9f3a86
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qrestreply.cpp | 39 | ||||
-rw-r--r-- | src/network/access/qrestreply_p.h | 5 |
2 files changed, 26 insertions, 18 deletions
diff --git a/src/network/access/qrestreply.cpp b/src/network/access/qrestreply.cpp index 0cea26868d..a736660786 100644 --- a/src/network/access/qrestreply.cpp +++ b/src/network/access/qrestreply.cpp @@ -222,7 +222,7 @@ QByteArray QRestReply::body() } /*! - Returns the received data as a QString. Requires the reply to be finished. + Returns the received data as a QString. The received data is decoded into a QString (UTF-16). The decoding uses the \e Content-Type header's \e charset parameter to determine the @@ -230,33 +230,36 @@ QByteArray QRestReply::body() available or not supported by \l QStringConverter, UTF-8 is used as a default. - Calling this function consumes the received data, and any further calls - to get response data will return empty. - - This function returns a default-constructed value and will not consume - any data if the reply is not finished. + Calling this function consumes the data received so far. Returns + a default constructed value if no new data is available, or if the + decoding is not supported by \l QStringConverter, or if the decoding + has errors (for example invalid characters). \sa json(), body(), isFinished(), finished() */ QString QRestReply::text() { Q_D(QRestReply); - if (!isFinished()) { - qCWarning(lcQrest, "Attempt to read text() of an unfinished reply, ignoring."); - return {}; - } + QString result; + QByteArray data = d->networkReply->readAll(); if (data.isEmpty()) + return result; + + if (!d->decoder) { + const QByteArray charset = d->contentCharset(); + d->decoder = QStringDecoder(charset); + if (!d->decoder->isValid()) { // the decoder may not support the mimetype's charset + qCWarning(lcQrest, "text(): Charset \"%s\" is not supported", charset.constData()); + return result; + } + } + // Check if the decoder already had an error, or has errors after decoding current data chunk + if (d->decoder->hasError() || (result = (*d->decoder)(data), d->decoder->hasError())) { + qCWarning(lcQrest, "text() Decoding error occurred"); return {}; - - const QByteArray charset = d->contentCharset(); - QStringDecoder decoder(charset); - if (!decoder.isValid()) { // the decoder may not support the mimetype's charset - qCWarning(lcQrest, "Charset \"%s\" is not supported, defaulting to UTF-8", - charset.constData()); - decoder = QStringDecoder(QStringDecoder::Utf8); } - return decoder(data); + return result; } /*! diff --git a/src/network/access/qrestreply_p.h b/src/network/access/qrestreply_p.h index 4b156b3793..7fe0842ff3 100644 --- a/src/network/access/qrestreply_p.h +++ b/src/network/access/qrestreply_p.h @@ -19,8 +19,12 @@ #include <QtNetwork/qnetworkreply.h> #include <QtCore/qjsondocument.h> +#include <optional> + QT_BEGIN_NAMESPACE +class QStringDecoder; + class QRestReplyPrivate : public QObjectPrivate { public: @@ -28,6 +32,7 @@ public: ~QRestReplyPrivate() override; QNetworkReply *networkReply = nullptr; + std::optional<QStringDecoder> decoder; QByteArray contentCharset() const; bool hasNonHttpError() const; |