Skip to content

Commit

Permalink
QUrl: port percent-decoding to char16_t
Browse files Browse the repository at this point in the history
Port decode() to take a QStringView to isolate callers from char16_t.
Have it return qsizetype instead of int. Use QChar* as output pointer
internally, to avoid more casts.

Change-Id: Ia388361a281ee97c41b01d8e6fe2c00801d988c4
Reviewed-by: Lars Knoll <[email protected]>
  • Loading branch information
marc-kdab committed May 12, 2020
1 parent 4170fdf commit cf52a36
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions src/corelib/io/qurlrecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl:
* needs to be decoded.
*/
#ifdef __SSE2__
static bool simdCheckNonEncoded(ushort *&output, const ushort *&input, const ushort *end)
static bool simdCheckNonEncoded(QChar *&output, const char16_t *&input, const char16_t *end)
{
# ifdef __AVX2__
const __m256i percents256 = _mm256_broadcastw_epi16(_mm_cvtsi32_si128('%'));
Expand Down Expand Up @@ -561,8 +561,8 @@ static bool simdCheckNonEncoded(...)
\since 5.0
\internal
This function decodes a percent-encoded string located from \a begin to \a
end, by appending each character to \a appendTo. It returns the number of
This function decodes a percent-encoded string located in \a in
by appending each character to \a appendTo. It returns the number of
characters appended. Each percent-encoded sequence is decoded as follows:
\list
Expand All @@ -578,18 +578,22 @@ static bool simdCheckNonEncoded(...)
The input should also be a valid percent-encoded sequence (the output of
qt_urlRecode is always valid).
*/
static int decode(QString &appendTo, const ushort *begin, const ushort *end)
static qsizetype decode(QString &appendTo, QStringView in)
{
const char16_t *begin = in.utf16();
const char16_t *end = begin + in.size();

// fast check whether there's anything to be decoded in the first place
const ushort *input = reinterpret_cast<const ushort*>(QtPrivate::qustrchr(QStringView(begin, end), '%'));
const char16_t *input = QtPrivate::qustrchr(in, '%');

if (Q_LIKELY(input == end))
return 0; // nothing to do, it was already decoded!

// detach
const int origSize = appendTo.size();
appendTo.resize(origSize + (end - begin));
ushort *output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
QChar *output = appendTo.data() + origSize;
memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(QChar));
output += input - begin;

while (input != end) {
Expand All @@ -604,15 +608,15 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
}

++input;
*output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]);
if (output[-1] >= 0x80)
*output++ = QChar::fromUcs2(decodeNibble(input[0]) << 4 | decodeNibble(input[1]));
if (output[-1].unicode() >= 0x80)
output[-1] = QChar::ReplacementCharacter;
input += 2;

// search for the next percent, copying from input to output
if (simdCheckNonEncoded(output, input, end)) {
while (input != end) {
ushort uc = *input;
const char16_t uc = *input;
if (uc == '%')
break;
*output++ = uc;
Expand All @@ -621,7 +625,7 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
}
}

int len = output - reinterpret_cast<ushort *>(appendTo.begin());
const qsizetype len = output - appendTo.begin();
appendTo.truncate(len);
return len - origSize;
}
Expand Down Expand Up @@ -673,7 +677,7 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
{
uchar actionTable[sizeof defaultActionTable];
if (encoding == QUrl::FullyDecoded) {
return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end));
return int(decode(appendTo, QStringView{begin, end}));
}

memcpy(actionTable, defaultActionTable, sizeof actionTable);
Expand Down

0 comments on commit cf52a36

Please sign in to comment.