Skip to content

Commit

Permalink
QLocal8Bit::convert{To,From}Unicode[win]: use more of state
Browse files Browse the repository at this point in the history
Like other backends we should increment the invalid character count
when we output a replacement character.
And we should also output the NULL character if requested!
The downside here is that convertFromUnicode doesn't even have the
ability to do so. So instead I added a comment explaining why it is not
handled there.

Task-number: QTBUG-118318
Pick-to: 6.6 6.5
Change-Id: I57ba631aa59454e77007ab353277b7e8c2b5526a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 3c8d717)
  • Loading branch information
Morten242 committed Feb 16, 2024
1 parent 2a950ce commit 4483e81
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/corelib/text/qstringconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,8 +1269,16 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
const char *mb = in.data();
qsizetype mblen = in.size();

if (state && state->flags & QStringConverter::Flag::Stateless)
Q_ASSERT(state);
qsizetype &invalidChars = state->invalidChars;
using Flag = QStringConverter::Flag;
const bool useNullForReplacement = !!(state->flags & Flag::ConvertInvalidToNull);
const char16_t replacementCharacter = useNullForReplacement ? QChar::Null
: QChar::ReplacementCharacter;
if (state->flags & Flag::Stateless) {
Q_ASSERT(state->remainingChars == 0);
state = nullptr;
}

if (!mb || !mblen)
return QString();
Expand Down Expand Up @@ -1321,7 +1329,8 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
// We couldn't decode any of the characters in the saved state,
// so output replacement characters
for (int i = 0; i < state->remainingChars; ++i)
out[i] = QChar::ReplacementCharacter;
out[i] = replacementCharacter;
invalidChars += state->remainingChars;
out += state->remainingChars;
outlen -= state->remainingChars;
state->remainingChars = 0;
Expand Down Expand Up @@ -1407,7 +1416,8 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
std::tie(out, outlen) = growOut(1);
if (!out)
return {};
*out = QChar::ReplacementCharacter;
*out = replacementCharacter;
++invalidChars;
++out;
--outlen;
++mb;
Expand Down Expand Up @@ -1436,7 +1446,8 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
if (!state && mblen > 0) {
// We have trailing character(s) that could not be converted, and
// nowhere to cache them
sp.resize(sp.size() + mblen, QChar::ReplacementCharacter);
sp.resize(sp.size() + mblen, replacementCharacter);
invalidChars += mblen;
}
return sp;
}
Expand All @@ -1453,8 +1464,18 @@ QByteArray QLocal8Bit::convertFromUnicode_sys(QStringView in, quint32 codePage,
qsizetype uclen = in.size();

Q_ASSERT(state);
if (state->flags & QStringConverter::Flag::Stateless) // temporary
// The Windows API has a *boolean* out-parameter that says if a replacement
// character was used, but it gives us no way to know _how many_ were used.
// Since we cannot simply scan the string for replacement characters
// (which is potentially a question mark, and thus a valid character),
// we simply do not track the number of invalid characters here.
// auto &invalidChars = state->invalidChars;

using Flag = QStringConverter::Flag;
if (state->flags & Flag::Stateless) { // temporary
Q_ASSERT(state->remainingChars == 0);
state = nullptr;
}

if (!ch)
return QByteArray();
Expand Down

0 comments on commit 4483e81

Please sign in to comment.