From d9a8caca47a4122ec2551200ea2ef30c7054f5f7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 1 Oct 2024 10:13:49 +0200 Subject: [PATCH] QStringConverter: de-pessimize lookup by UTF-16 name Instead of converting the QStringView into a L1 string (allocating memory), duplicate the matching code for char and char16_t. Fixes a ### comment from the time we converted lookup to QAnyStringView. Amends b3edce58e5aea76d1d84c868f76171c2b40520a4. Task-number: QTBUG-126109 Change-Id: I5ae6eb452e68af19b495b3790fe79ee583968d72 Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira (cherry picked from commit c095f7fbf820ac944c5d3096f48dd18752a218b3) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/text/qstringconverter.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index 104c10a7674..633eb1b72d9 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -1910,22 +1910,28 @@ const QStringConverter::Interface QStringConverter::encodingInterfaces[QStringCo }; // match names case insensitive and skipping '-' and '_' -static bool nameMatch_impl(const char *a, QLatin1StringView rhs) +template +static bool nameMatch_impl_impl(const char *a, const Char *b, const Char *b_end) { - const char *b = rhs.data(); - const char *b_end = rhs.end(); do { while (*a == '-' || *a == '_') ++a; - while (b != b_end && (*b == '-' || *b == '_')) + while (b != b_end && (*b == Char{'-'} || *b == Char{'_'})) ++b; if (!*a && b == b_end) // end of both strings return true; - } while (QtMiscUtils::toAsciiLower(*a++) == QtMiscUtils::toAsciiLower(*b++)); + if (char16_t(*b) > 127) + return false; // non-US-ASCII cannot match US-ASCII (prevents narrowing below) + } while (QtMiscUtils::toAsciiLower(*a++) == QtMiscUtils::toAsciiLower(char(*b++))); return false; } +static bool nameMatch_impl(const char *a, QLatin1StringView b) +{ + return nameMatch_impl_impl(a, b.begin(), b.end()); +} + static bool nameMatch_impl(const char *a, QUtf8StringView b) { return nameMatch_impl(a, QLatin1StringView{QByteArrayView{b}}); @@ -1933,7 +1939,7 @@ static bool nameMatch_impl(const char *a, QUtf8StringView b) static bool nameMatch_impl(const char *a, QStringView b) { - return nameMatch_impl(a, QLatin1StringView{b.toString().toLatin1()}); // ### optimize + return nameMatch_impl_impl(a, b.utf16(), b.utf16() + b.size()); // uses char16_t*, not QChar* } static bool nameMatch(const char *a, QAnyStringView b)