From 694a92ab24787fae85a391691e841e142e4bfc18 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 3 Feb 2023 23:04:36 +0100 Subject: [PATCH] SQL/ODBC: optimize toSQLTCHAR() - avoid an unneeded copy Avoid an unneeded copy in toSQLTCHAR() when sizeof(SQLTCHAR) == 1 or 4 by directly writing the encoded data into the QVarLengthArray. Change-Id: Ic4180343764fa1ca175a9cdd444c5359d664c754 Reviewed-by: Thiago Macieira --- src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 43 +++++++++-------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 94c124f039..771ed96ef9 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -58,39 +59,27 @@ inline static QString fromSQLTCHAR(const QVarLengthArray& input, qsize return result; } -template -void toSQLTCHARImpl(QVarLengthArray &result, const QString &input); // primary template undefined - -template -void do_append(QVarLengthArray &result, const Container &c) +template +QStringConverter::Encoding encodingForSqlTChar() { - result.append(reinterpret_cast(c.data()), c.size()); -} - -template <> -void toSQLTCHARImpl<1>(QVarLengthArray &result, const QString &input) -{ - const auto u8 = input.toUtf8(); - do_append(result, u8); -} - -template <> -void toSQLTCHARImpl<2>(QVarLengthArray &result, const QString &input) -{ - do_append(result, input); -} - -template <> -void toSQLTCHARImpl<4>(QVarLengthArray &result, const QString &input) -{ - const auto u32 = input.toUcs4(); - do_append(result, u32); + if constexpr (SIZE == 1) + return QStringConverter::Utf8; + else if constexpr (SIZE == 2) + return QStringConverter::Utf16; + else if constexpr (SIZE == 4) + return QStringConverter::Utf32; + else + static_assert(QtPrivate::value_dependent_false(), + "Don't know how to handle sizeof(SQLTCHAR) != 1/2/4"); } inline static QVarLengthArray toSQLTCHAR(const QString &input) { QVarLengthArray result; - toSQLTCHARImpl(result, input); + QStringEncoder enc(encodingForSqlTChar()); + result.resize(enc.requiredSpace(input.size())); + const auto end = enc.appendToBuffer(reinterpret_cast(result.data()), input); + result.resize((end - reinterpret_cast(result.data())) / sizeof(SQLTCHAR)); result.append(0); // make sure it's null terminated, doesn't matter if it already is, it does if it isn't. return result; }