summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@qt.io>2023-12-12 14:08:04 +0200
committerJuha Vuolle <juha.vuolle@qt.io>2024-01-10 16:36:05 +0200
commit4da14a67a6157c415f8228a8bae7d6b0f895df7c (patch)
treebab39226dbc78dad60b680b8df80ef06326e1f7d /src/network/access
parent9aaf1a031befc39244290c63f3905896934f6082 (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.cpp39
-rw-r--r--src/network/access/qrestreply_p.h5
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;