From b3edce58e5aea76d1d84c868f76171c2b40520a4 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 5 Jun 2024 20:55:22 +0200 Subject: [PATCH] QStringConverter: port encodingForName() to QAnyStringView These kinds of lookup functions are no-brainers for QAnyStringView. This is required to replace the QStringEncoder/Decoder constructors from QString, newly added for 6.8, and found in API review to be better written using QAnyStringView. Because this is API-Review-relevant, keep the QStringView case pessimized. It's not worse than the code that it replaces (toLatin1() on an unshared QString performs in-place conversion), and can be improved later. [ChangeLog][QtCore][QStringConverter] The encodingForName() function now takes QAnyStringView (was: const char*). Pick-to: 6.8 Task-number: QTBUG-126108 Change-Id: I02cc53bfbc8f1eebe539816487a10b39e96fac2d Reviewed-by: Ahmad Samir Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira --- src/corelib/compat/removed_api.cpp | 7 ++++++ src/corelib/text/qstringconverter.cpp | 30 +++++++++++++++++++----- src/corelib/text/qstringconverter_base.h | 4 ++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index babdc74f42c..8826716bde8 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -1138,6 +1138,13 @@ bool QtPrivate::ResultIteratorBase::operator!=(const QtPrivate::ResultIteratorBa #include "qstring.h" // inlined API +#include "qstringconverter.h" + +auto QStringConverter::encodingForName(const char *name) noexcept -> std::optional +{ + return encodingForName(QAnyStringView{name}); +} + #if QT_CONFIG(thread) # include "qthreadpool.h" // inlined API #endif diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index a960899e59d..745261cd559 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -1910,20 +1910,37 @@ const QStringConverter::Interface QStringConverter::encodingInterfaces[QStringCo }; // match names case insensitive and skipping '-' and '_' -static bool nameMatch(const char *a, const char *b) +static bool nameMatch_impl(const char *a, QLatin1StringView rhs) { + const char *b = rhs.data(); + const char *b_end = rhs.end(); do { while (*a == '-' || *a == '_') ++a; - while (*b == '-' || *b == '_') + while (b != b_end && (*b == '-' || *b == '_')) ++b; - if (!*a && !*b) // end of both strings + if (!*a && b == b_end) // end of both strings return true; } while (QtMiscUtils::toAsciiLower(*a++) == QtMiscUtils::toAsciiLower(*b++)); return false; } +static bool nameMatch_impl(const char *a, QUtf8StringView b) +{ + return nameMatch_impl(a, QLatin1StringView{QByteArrayView{b}}); +} + +static bool nameMatch_impl(const char *a, QStringView b) +{ + return nameMatch_impl(a, QLatin1StringView{b.toString().toLatin1()}); // ### optimize +} + +static bool nameMatch(const char *a, QAnyStringView b) +{ + return b.visit([a](auto b) { return nameMatch_impl(a, b); }); +} + /*! \fn constexpr QStringConverter::QStringConverter() @@ -2237,11 +2254,12 @@ const char *QStringConverter::name() const noexcept the QStringConverter constructor when Qt is built with ICU, if ICU provides a converter with the given name. - \a name is expected to be UTF-8 encoded. + \note In Qt versions prior to 6.8, this function took only a \c{const char *}, + which was expected to be UTF-8-encoded. */ -std::optional QStringConverter::encodingForName(const char *name) noexcept +std::optional QStringConverter::encodingForName(QAnyStringView name) noexcept { - if (!name) + if (name.isEmpty()) return std::nullopt; for (qsizetype i = 0; i < LastEncoding + 1; ++i) { if (nameMatch(encodingInterfaces[i].name, name)) diff --git a/src/corelib/text/qstringconverter_base.h b/src/corelib/text/qstringconverter_base.h index d6b6fcb484b..0c4a19cbe7b 100644 --- a/src/corelib/text/qstringconverter_base.h +++ b/src/corelib/text/qstringconverter_base.h @@ -14,6 +14,7 @@ #include // QT_{BEGIN,END}_NAMESPACE #include // Q_DECLARE_FLAGS #include +#include #include @@ -156,7 +157,10 @@ public: Q_CORE_EXPORT const char *name() const noexcept; +#if QT_CORE_REMOVED_SINCE(6, 8) Q_CORE_EXPORT static std::optional encodingForName(const char *name) noexcept; +#endif + Q_CORE_EXPORT static std::optional encodingForName(QAnyStringView name) noexcept; Q_CORE_EXPORT static const char *nameForEncoding(Encoding e); Q_CORE_EXPORT static std::optional encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;