From d44aae13589074752ab74d796a7ade87261bceb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 19 Oct 2023 15:14:45 +0200 Subject: QLocal8Bit::convertToUnicode[win]: Drop QVLA in favor of array We now, instead, resize and copy the data directly into a QString if we run out of space in the pre-allocated array. Pick-to: 6.6 6.5 Task-number: QTBUG-118318 Task-number: QTBUG-105105 Change-Id: I1eed5e75f0bd067b4e7d6bff97c4186f3f6ee0ad Reviewed-by: Thiago Macieira --- src/corelib/text/qstringconverter.cpp | 45 +++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'src/corelib/text/qstringconverter.cpp') diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index 0391a21735..ff6b66956e 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -10,6 +10,7 @@ #include "private/qstringiterator_p.h" #include "private/qtools_p.h" #include "qbytearraymatcher.h" +#include "qcontainertools_impl.h" #include #if QT_CONFIG(icu) @@ -26,6 +27,8 @@ #endif // !QT_BOOTSTRAPPED #endif +#include + #if __has_include() && __cplusplus > 201703L #include #endif @@ -1323,10 +1326,12 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage, if (!mb || !mblen) return QString(); - QVarLengthArray wc(4096); + std::array buf; + wchar_t *out = buf.data(); + qsizetype outlen = buf.size(); + int len; QString sp; - bool prepend = false; char state_data = 0; int remainingChars = 0; @@ -1342,31 +1347,32 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage, prev[0] = state_data; prev[1] = mb[0]; remainingChars = 0; - len = MultiByteToWideChar(codePage, MB_PRECOMPOSED, - prev, 2, wc.data(), wc.length()); + len = MultiByteToWideChar(codePage, MB_PRECOMPOSED, prev, 2, out, outlen); if (len) { - sp.append(QChar(wc[0])); if (mblen == 1) { state->remainingChars = 0; - return sp; + return QStringView(out, len).toString(); } - prepend = true; mb++; mblen--; - wc[0] = 0; + ++out; + --outlen; } } while (!(len=MultiByteToWideChar(codePage, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, - mb, mblen, wc.data(), wc.length()))) { + mb, mblen, out, int(outlen)))) { int r = GetLastError(); if (r == ERROR_INSUFFICIENT_BUFFER) { + Q_ASSERT(QtPrivate::q_points_into_range(out, buf.data(), buf.data() + buf.size())); const int wclen = MultiByteToWideChar(codePage, MB_PRECOMPOSED, mb, mblen, 0, 0); - wc.resize(wclen); + const qsizetype offset = qsizetype(out - buf.data()); + sp.resize(offset + wclen); + auto it = reinterpret_cast(sp.data()); + it = std::copy_n(buf.data(), offset, it); + out = it; + outlen = wclen; } else if (r == ERROR_NO_UNICODE_TRANSLATION) { - //find the last non NULL character - while (mblen > 1 && !(mb[mblen-1])) - mblen--; //check whether, we hit an invalid character in the middle if ((mblen <= 1) || (remainingChars && state_data)) return convertToUnicodeCharByChar(in, codePage, state); @@ -1384,7 +1390,7 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage, if (len <= 0) return QString(); - if (wc[len-1] == 0) // len - 1: we don't want terminator + if (out[len - 1] == u'\0') --len; //save the new state information @@ -1392,11 +1398,14 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage, state->state_data[0] = (char)state_data; state->remainingChars = remainingChars; } - QString s((QChar*)wc.data(), len); - if (prepend) { - return sp+s; + + if (QtPrivate::q_points_into_range(out, buf.data(), buf.data() + buf.size())) { + if (out - buf.data() + len > 0) + sp = QStringView(buf.data(), out + len).toString(); + } else{ + sp.truncate(out - reinterpret_cast(sp.data()) + len); } - return s; + return sp; } QByteArray QLocal8Bit::convertFromUnicode_sys(QStringView in, QStringConverter::State *state) -- cgit v1.2.3