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>
This commit is contained in:
Mårten Nordheim 2023-10-19 15:14:45 +02:00
parent 3a5339b418
commit d44aae1358

View File

@ -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)