Optimize QXmlStreamWriterPrivate::doWriteToDevice(QStringView)

Use a stack buffer, and perform the recoding from U16 to U8 in chunks.

Since no-one so far managed to get a chunked QStringEncoder to produce
the same output as the test expected, at least not without additional
API, fall back to the raw QUtf8 functions. This also avoids the
indirect function call overhead that QStringEncoder would entail.

Fixes: QTBUG-109284
Change-Id: Icaa26c3988ac8506c9cf3fde18fd5892e5e63ef2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Marc Mutz 2022-12-08 16:10:06 +01:00
parent be3fbd8045
commit fa2153bd10

View File

@ -3063,13 +3063,19 @@ void QXmlStreamWriterPrivate::indent(int level)
void QXmlStreamWriterPrivate::doWriteToDevice(QStringView s)
{
QStringEncoder toUtf8(QStringEncoder::Utf8, QStringEncoder::Flag::Stateless);
QByteArray bytes = toUtf8(s);
if (toUtf8.hasError()) {
hasEncodingError = true;
return;
constexpr qsizetype MaxChunkSize = 512;
char buffer [3 * MaxChunkSize];
QStringEncoder::State state;
while (!s.isEmpty()) {
const qsizetype chunkSize = std::min(s.size(), MaxChunkSize);
char *end = QUtf8::convertFromUnicode(buffer, s.first(chunkSize), &state);
if (state.remainingChars > 0) {
hasEncodingError = true;
return;
}
doWriteToDevice(QUtf8StringView{buffer, end});
s = s.sliced(chunkSize);
}
doWriteToDevice(QUtf8StringView{bytes});
}
void QXmlStreamWriterPrivate::doWriteToDevice(QUtf8StringView s)