diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2023-10-19 15:14:45 +0200 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2023-10-27 17:44:35 +0200 |
commit | d44aae13589074752ab74d796a7ade87261bceb4 (patch) | |
tree | a80dd2035d86495f8a5457178c8600b58a51fb7e /src/corelib/text/qstringconverter.cpp | |
parent | 3a5339b4187c63acd0ea924937042f61150d2e06 (diff) |
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 <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/text/qstringconverter.cpp')
-rw-r--r-- | src/corelib/text/qstringconverter.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
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 <QtCore/qbytearraylist.h> #if QT_CONFIG(icu) @@ -26,6 +27,8 @@ #endif // !QT_BOOTSTRAPPED #endif +#include <array> + #if __has_include(<bit>) && __cplusplus > 201703L #include <bit> #endif @@ -1323,10 +1326,12 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage, if (!mb || !mblen) return QString(); - QVarLengthArray<wchar_t, 4096> wc(4096); + std::array<wchar_t, 4096> 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<wchar_t *>(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<wchar_t *>(sp.data()) + len); } - return s; + return sp; } QByteArray QLocal8Bit::convertFromUnicode_sys(QStringView in, QStringConverter::State *state) |