diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2022-06-28 10:01:53 +0200 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2022-07-12 13:24:56 +0200 |
commit | 6bc227a06a0d1392d220aa79ddb1cdc145d4f76e (patch) | |
tree | 2fec1d932fda80146f40a94dee860ea896d8edd0 /src | |
parent | c78ec505293ed576779c0ee7342746cde39281d6 (diff) |
Port QXmlStremReader to QAnyStringView
Port the constructor and addData() method to QAnyStringView, but keep
the overloads taking a QByteArray to avoid extra copies when actual
QByteArray is passed. These overlaods need to be Q_WEAK_OVERLOADs, to
avoid ambiguities (e.g. for const char * arguments).
Additionally, add a test to make sure the patch doesn't break parsing
from a QLatin1StringView input.
[ChangeLog][QtCore][QXmlStremReader] Added constructor and addData()
overloads taking QAnyStringView.
Change-Id: I0efaab82a2123271c88407e380f3c67d1099a4a6
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/compat/removed_api.cpp | 35 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.cpp | 128 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.h | 15 |
3 files changed, 128 insertions, 50 deletions
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index d56ea9f43a..ba844715d8 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -278,3 +278,38 @@ QT_WARNING_POP // order sections alphabetically to reduce chances of merge conflicts #endif // QT_CORE_REMOVED_SINCE(6, 4) + +#if QT_CORE_REMOVED_SINCE(6, 5) + +#include "qxmlstream.h" + +QXmlStreamReader::QXmlStreamReader(const QByteArray &data) + : QXmlStreamReader(data, PrivateConsructorTag{}) +{ +} + +QXmlStreamReader::QXmlStreamReader(const QString &data) + : QXmlStreamReader(qToAnyStringViewIgnoringNull(data)) +{ +} + +QXmlStreamReader::QXmlStreamReader(const char *data) + : QXmlStreamReader(QAnyStringView(data)) +{ +} + +void QXmlStreamReader::addData(const QByteArray &data) +{ + addData<>(data); +} +void QXmlStreamReader::addData(const QString &data) +{ + addData(qToAnyStringViewIgnoringNull(data)); +} + +void QXmlStreamReader::addData(const char *data) +{ + addData(QAnyStringView(data)); +} + +#endif // QT_CORE_REMOVED_SINCE(6, 5) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index a6a2bc41af..28e927d7da 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -360,41 +360,55 @@ QXmlStreamReader::QXmlStreamReader(QIODevice *device) } /*! - Creates a new stream reader that reads from \a data. + \overload - \sa addData(), clear(), setDevice() - */ -QXmlStreamReader::QXmlStreamReader(const QByteArray &data) - : d_ptr(new QXmlStreamReaderPrivate(this)) -{ - Q_D(QXmlStreamReader); - d->dataBuffer = data; -} + \fn QXmlStreamReader::QXmlStreamReader(const QByteArray &data) + + Creates a new stream reader that reads from \a data. + + \sa addData(), clear(), setDevice() +*/ /*! - Creates a new stream reader that reads from \a data. + Creates a new stream reader that reads from \a data. - \sa addData(), clear(), setDevice() - */ -QXmlStreamReader::QXmlStreamReader(const QString &data) + \note In Qt versions prior to 6.5, this constructor was overloaded + for QString and \c {const char*}. + + \sa addData(), clear(), setDevice() +*/ +QXmlStreamReader::QXmlStreamReader(QAnyStringView data) : d_ptr(new QXmlStreamReaderPrivate(this)) { Q_D(QXmlStreamReader); - d->dataBuffer = data.toUtf8(); - d->decoder = QStringDecoder(QStringDecoder::Utf8); - d->lockEncoding = true; + data.visit([d](auto data) { + if constexpr (std::is_same_v<decltype(data), QStringView>) { + d->dataBuffer = data.toUtf8(); + d->decoder = QStringDecoder(QStringDecoder::Utf8); + d->lockEncoding = true; + } else if constexpr (std::is_same_v<decltype(data), QLatin1StringView>) { + // Conversion to a QString is required, to avoid breaking + // pre-existing (before porting to QAnyStringView) behavior. + d->dataBuffer = QString::fromLatin1(data).toUtf8(); + d->decoder = QStringDecoder(QStringDecoder::Utf8); + d->lockEncoding = true; + } else { + d->dataBuffer = QByteArray(data.data(), data.size()); + } + }); } /*! - Creates a new stream reader that reads from \a data. + \internal - \sa addData(), clear(), setDevice() - */ -QXmlStreamReader::QXmlStreamReader(const char *data) + Creates a new stream reader that reads from \a data. + Used by the weak constructor taking a QByteArray. +*/ +QXmlStreamReader::QXmlStreamReader(const QByteArray &data, PrivateConsructorTag) : d_ptr(new QXmlStreamReaderPrivate(this)) { Q_D(QXmlStreamReader); - d->dataBuffer = QByteArray(data); + d->dataBuffer = data; } /*! @@ -443,47 +457,61 @@ QIODevice *QXmlStreamReader::device() const return d->device; } - /*! - Adds more \a data for the reader to read. This function does - nothing if the reader has a device(). + \overload - \sa readNext(), clear() - */ -void QXmlStreamReader::addData(const QByteArray &data) -{ - Q_D(QXmlStreamReader); - if (d->device) { - qWarning("QXmlStreamReader: addData() with device()"); - return; - } - d->dataBuffer += data; -} + \fn void QXmlStreamReader::addData(const QByteArray &data) + + Adds more \a data for the reader to read. This function does + nothing if the reader has a device(). + + \sa readNext(), clear() +*/ /*! - Adds more \a data for the reader to read. This function does - nothing if the reader has a device(). + Adds more \a data for the reader to read. This function does + nothing if the reader has a device(). - \sa readNext(), clear() - */ -void QXmlStreamReader::addData(const QString &data) + \note In Qt versions prior to 6.5, this function was overloaded + for QString and \c {const char*}. + + \sa readNext(), clear() +*/ +void QXmlStreamReader::addData(QAnyStringView data) { Q_D(QXmlStreamReader); - d->lockEncoding = true; - if (!d->decoder.isValid()) - d->decoder = QStringDecoder(QStringDecoder::Utf8); - addData(data.toUtf8()); + data.visit([=](auto data) { + if constexpr (std::is_same_v<decltype(data), QStringView>) { + d->lockEncoding = true; + if (!d->decoder.isValid()) + d->decoder = QStringDecoder(QStringDecoder::Utf8); + addDataImpl(data.toUtf8()); + } else if constexpr (std::is_same_v<decltype(data), QLatin1StringView>) { + // Conversion to a QString is required, to avoid breaking + // pre-existing (before porting to QAnyStringView) behavior. + if (!d->decoder.isValid()) + d->decoder = QStringDecoder(QStringDecoder::Utf8); + addDataImpl(QString::fromLatin1(data).toUtf8()); + } else { + addDataImpl(QByteArray(data.data(), data.size())); + } + }); } /*! - Adds more \a data for the reader to read. This function does - nothing if the reader has a device(). + \internal - \sa readNext(), clear() - */ -void QXmlStreamReader::addData(const char *data) + Adds more \a data for the reader to read. This function does + nothing if the reader has a device(). +*/ +void QXmlStreamReader::addDataImpl(const QByteArray &data) { - addData(QByteArray(data)); + Q_D(QXmlStreamReader); + if (d->device) { + qWarning("QXmlStreamReader: addData() with device()"); + return; + } + d->dataBuffer += data; } /*! diff --git a/src/corelib/serialization/qxmlstream.h b/src/corelib/serialization/qxmlstream.h index 366d357b37..8ba24f430e 100644 --- a/src/corelib/serialization/qxmlstream.h +++ b/src/corelib/serialization/qxmlstream.h @@ -197,16 +197,27 @@ public: QXmlStreamReader(); explicit QXmlStreamReader(QIODevice *device); +#if QT_CORE_REMOVED_SINCE(6, 5) explicit QXmlStreamReader(const QByteArray &data); explicit QXmlStreamReader(const QString &data); explicit QXmlStreamReader(const char * data); +#endif // QT_CORE_REMOVED_SINCE(6, 5) + Q_WEAK_OVERLOAD + explicit QXmlStreamReader(const QByteArray &data) + : QXmlStreamReader(data, PrivateConsructorTag{}) { } + explicit QXmlStreamReader(QAnyStringView data); ~QXmlStreamReader(); void setDevice(QIODevice *device); QIODevice *device() const; +#if QT_CORE_REMOVED_SINCE(6, 5) void addData(const QByteArray &data); void addData(const QString &data); void addData(const char *data); +#endif // QT_CORE_REMOVED_SINCE(6, 5) + Q_WEAK_OVERLOAD + void addData(const QByteArray &data) { addDataImpl(data); } + void addData(QAnyStringView data); void clear(); @@ -293,6 +304,10 @@ public: QXmlStreamEntityResolver *entityResolver() const; private: + struct PrivateConsructorTag { }; + QXmlStreamReader(const QByteArray &data, PrivateConsructorTag); + void addDataImpl(const QByteArray &data); + Q_DISABLE_COPY(QXmlStreamReader) Q_DECLARE_PRIVATE(QXmlStreamReader) QScopedPointer<QXmlStreamReaderPrivate> d_ptr; |