QByteArray: add compare() with case sensitivity options

Need to do the same for startsWith() and endsWith(). indexOf() is a lot
harder.

[ChangeLog][QtCore][QByteArray] Added compare(), which takes
Qt::CaseSensitivity as one of the parameters. This function is more
efficient than using toLower() or toUpper() and then comparing.

Change-Id: Ib48364abee9f464c96c6fffd152e69bde4194df7
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
bb10
Thiago Macieira 2018-05-13 21:53:07 -07:00
parent c699daeceb
commit cad7100fda
18 changed files with 212 additions and 56 deletions

View File

@ -1694,10 +1694,10 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data,
iniSection = iniSection.trimmed();
if (qstricmp(iniSection.constData(), "general") == 0) {
if (iniSection.compare("general", Qt::CaseInsensitive) == 0) {
currentSection.clear();
} else {
if (qstricmp(iniSection.constData(), "%general") == 0) {
if (iniSection.compare("%general", Qt::CaseInsensitive) == 0) {
currentSection = QLatin1String(iniSection.constData() + 1);
} else {
currentSection.clear();
@ -1857,7 +1857,7 @@ bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSetti
if (realSection.isEmpty()) {
realSection = "[General]";
} else if (qstricmp(realSection.constData(), "general") == 0) {
} else if (realSection.compare("general", Qt::CaseInsensitive) == 0) {
realSection = "[%General]";
} else {
realSection.prepend('[');

View File

@ -356,7 +356,8 @@ char *qstrncpy(char *dst, const char *src, uint len)
Special case 2: Returns an arbitrary non-zero value if \a str1 is
nullptr or \a str2 is nullptr (but not both).
\sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
\sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
*/
int qstrcmp(const char *str1, const char *str2)
{
@ -381,7 +382,8 @@ int qstrcmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
\sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
*/
/*! \relates QByteArray
@ -400,7 +402,8 @@ int qstrcmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons}
\sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
*/
int qstricmp(const char *str1, const char *str2)
@ -434,7 +437,8 @@ int qstricmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}
\sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons},
QByteArray::compare()
*/
int qstrnicmp(const char *str1, const char *str2, uint len)
@ -456,6 +460,55 @@ int qstrnicmp(const char *str1, const char *str2, uint len)
/*!
\internal
\since 5.12
A helper for QByteArray::compare. Compares \a len1 bytes from \a str1 to \a
len2 bytes from \a str2. If \a len2 is -1, then \a str2 is expected to be
null-terminated.
*/
int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
{
Q_ASSERT(str1);
Q_ASSERT(len1 >= 0);
Q_ASSERT(len2 >= -1);
const uchar *s1 = reinterpret_cast<const uchar *>(str1);
const uchar *s2 = reinterpret_cast<const uchar *>(str2);
if (!s2)
return len1 == 0 ? 0 : 1;
int res;
uchar c;
if (len2 == -1) {
// null-terminated str2
qsizetype i;
for (i = 0; i < len1; ++i) {
c = latin1_lowercased[s2[i]];
if (!c)
return 1;
res = latin1_lowercased[s1[i]] - c;
if (res)
return res;
}
c = latin1_lowercased[s2[i]];
return c ? -1 : 0;
} else {
// not null-terminated
for (qsizetype i = 0; i < qMin(len1, len2); ++i) {
c = latin1_lowercased[s2[i]];
res = latin1_lowercased[s1[i]] - c;
if (res)
return res;
}
if (len1 == len2)
return 0;
return len1 < len2 ? -1 : 1;
}
}
/*!
\internal
### Qt6: replace the QByteArray parameter with [pointer,len] pair
*/
int qstrcmp(const QByteArray &str1, const char *str2)
{
@ -483,6 +536,7 @@ int qstrcmp(const QByteArray &str1, const char *str2)
/*!
\internal
### Qt6: replace the QByteArray parameter with [pointer,len] pair
*/
int qstrcmp(const QByteArray &str1, const QByteArray &str2)
{
@ -2863,6 +2917,31 @@ int QByteArray::count(char ch) const
Same as size().
*/
/*!
\fn int QByteArray::compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 5.12
Returns an integer less than, equal to, or greater than zero depending on
whether this QByteArray sorts before, at the same position, or after the
string pointed to by \a c. The comparison is performed according to case
sensitivity \a cs.
\sa operator==
*/
/*!
\fn int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\overload
\since 5.12
Returns an integer less than, equal to, or greater than zero depending on
whether this QByteArray sorts before, at the same position, or after the
QByteArray \a a. The comparison is performed according to case sensitivity
\a cs.
\sa operator==
*/
/*!
Returns \c true if this byte array starts with byte array \a ba;
otherwise returns \c false.
@ -3367,6 +3446,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is equal to byte array \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator==(const QByteArray &a1, const char *a2)
@ -3376,6 +3457,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is equal to string \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator==(const char *a1, const QByteArray &a2)
@ -3385,6 +3468,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is equal to byte array \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator!=(const QByteArray &a1, const QByteArray &a2)
@ -3394,6 +3479,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is not equal to byte array \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator!=(const QByteArray &a1, const char *a2)
@ -3403,6 +3490,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is not equal to string \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator!=(const char *a1, const QByteArray &a2)
@ -3412,6 +3501,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is not equal to byte array \a a2;
otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator<(const QByteArray &a1, const QByteArray &a2)
@ -3421,6 +3512,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than byte array
\a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn inline bool operator<(const QByteArray &a1, const char *a2)
@ -3430,6 +3523,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than string
\a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator<(const char *a1, const QByteArray &a2)
@ -3439,6 +3534,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically less than byte array
\a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator<=(const QByteArray &a1, const QByteArray &a2)
@ -3448,6 +3545,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than or equal
to byte array \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator<=(const QByteArray &a1, const char *a2)
@ -3457,6 +3556,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than or equal
to string \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator<=(const char *a1, const QByteArray &a2)
@ -3466,6 +3567,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically less than or equal
to byte array \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>(const QByteArray &a1, const QByteArray &a2)
@ -3475,6 +3578,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than byte
array \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>(const QByteArray &a1, const char *a2)
@ -3484,6 +3589,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than string
\a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>(const char *a1, const QByteArray &a2)
@ -3493,6 +3600,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically greater than byte array
\a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>=(const QByteArray &a1, const QByteArray &a2)
@ -3502,6 +3611,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than or
equal to byte array \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>=(const QByteArray &a1, const char *a2)
@ -3511,6 +3622,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than or
equal to string \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn bool operator>=(const char *a1, const QByteArray &a2)
@ -3520,6 +3633,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically greater than or
equal to byte array \a a2; otherwise returns \c false.
\sa QByteArray::compare()
*/
/*! \fn const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)

View File

@ -99,6 +99,7 @@ inline int qstrncmp(const char *str1, const char *str2, uint len)
}
Q_CORE_EXPORT int qstricmp(const char *, const char *);
Q_CORE_EXPORT int qstrnicmp(const char *, const char *, uint len);
Q_CORE_EXPORT int qstrnicmp(const char *, qsizetype, const char *, qsizetype = -1);
// implemented in qvsnprintf.cpp
Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap);
@ -231,6 +232,9 @@ public:
int count(const char *a) const;
int count(const QByteArray &a) const;
inline int compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline int compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
Q_REQUIRED_RESULT QByteArray left(int len) const;
Q_REQUIRED_RESULT QByteArray right(int len) const;
Q_REQUIRED_RESULT QByteArray mid(int index, int len = -1) const;
@ -603,6 +607,16 @@ inline bool QByteArray::contains(const QByteArray &a) const
{ return indexOf(a) != -1; }
inline bool QByteArray::contains(char c) const
{ return indexOf(c) != -1; }
inline int QByteArray::compare(const char *c, Qt::CaseSensitivity cs) const
{
return cs == Qt::CaseSensitive ? qstrcmp(*this, c) :
qstrnicmp(data(), size(), c, -1);
}
inline int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs) const
{
return cs == Qt::CaseSensitive ? qstrcmp(*this, a) :
qstrnicmp(data(), size(), a.data(), a.size());
}
inline bool operator==(const QByteArray &a1, const QByteArray &a2) Q_DECL_NOTHROW
{ return (a1.size() == a2.size()) && (memcmp(a1.constData(), a2.constData(), a1.size())==0); }
inline bool operator==(const QByteArray &a1, const char *a2) Q_DECL_NOTHROW

View File

@ -1076,14 +1076,12 @@ static int qt_compare_strings(QLatin1String lhs, QStringView rhs, Qt::CaseSensit
static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
if (cs == Qt::CaseInsensitive)
return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
if (lhs.isEmpty())
return lencmp(0, rhs.size());
const auto l = std::min(lhs.size(), rhs.size());
int r;
if (cs == Qt::CaseSensitive)
r = qstrncmp(lhs.data(), rhs.data(), l);
else
r = qstrnicmp(lhs.data(), rhs.data(), l);
int r = qstrncmp(lhs.data(), rhs.data(), l);
return r ? r : lencmp(lhs.size(), rhs.size());
}

View File

@ -244,7 +244,8 @@ static inline bool usePixelDensity()
return false;
return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
|| (screenEnvValueOk && screenEnvValue > 0)
|| (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
|| (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) &&
qgetenv(legacyDevicePixelEnvVar).compare("auto", Qt::CaseInsensitive) == 0);
}
void QHighDpiScaling::initHighDpiScaling()

View File

@ -287,7 +287,8 @@ bool is_protocol_upgraded(const QHttpNetworkReply &reply)
// Do some minimal checks here - we expect 'Upgrade: h2c' to be found.
const auto &header = reply.header();
for (const QPair<QByteArray, QByteArray> &field : header) {
if (field.first.toLower() == "upgrade" && field.second.toLower() == "h2c")
if (field.first.compare("upgrade", Qt::CaseInsensitive) == 0 &&
field.second.compare("h2c", Qt::CaseInsensitive) == 0)
return true;
}
}

View File

@ -453,8 +453,7 @@ bool QHstsHeaderParser::processDirective(const QByteArray &name, const QByteArra
{
Q_ASSERT(name.size());
// RFC6797 6.1/3 Directive names are case-insensitive
const auto lcName = name.toLower();
if (lcName == "max-age") {
if (name.compare("max-age", Qt::CaseInsensitive) == 0) {
// RFC 6797, 6.1.1
// The syntax of the max-age directive's REQUIRED value (after
// quoted-string unescaping, if necessary) is defined as:
@ -477,7 +476,7 @@ bool QHstsHeaderParser::processDirective(const QByteArray &name, const QByteArra
maxAge = age;
maxAgeFound = true;
} else if (lcName == "includesubdomains") {
} else if (name.compare("includesubdomains", Qt::CaseInsensitive) == 0) {
// RFC 6797, 6.1.2. The includeSubDomains Directive.
// The OPTIONAL "includeSubDomains" directive is a valueless directive.

View File

@ -97,16 +97,18 @@ HPack::HttpHeader build_headers(const QHttpNetworkRequest &request, quint32 maxH
if (size.second > maxHeaderListSize)
break;
QByteArray key(field.first.toLower());
if (key == "connection" || key == "host" || key == "keep-alive"
|| key == "proxy-connection" || key == "transfer-encoding")
if (field.first.compare("connection", Qt::CaseInsensitive) == 0 ||
field.first.compare("host", Qt::CaseInsensitive) == 0 ||
field.first.compare("keep-alive", Qt::CaseInsensitive) == 0 ||
field.first.compare("proxy-connection", Qt::CaseInsensitive) == 0 ||
field.first.compare("transfer-encoding", Qt::CaseInsensitive) == 0)
continue; // Those headers are not valid (section 3.2.1) - from QSpdyProtocolHandler
// TODO: verify with specs, which fields are valid to send ....
// toLower - 8.1.2 .... "header field names MUST be converted to lowercase prior
// to their encoding in HTTP/2.
// A request or response containing uppercase header field names
// MUST be treated as malformed (Section 8.1.2.6)".
header.push_back(HeaderField(key, field.second));
header.push_back(HeaderField(field.first.toLower(), field.second));
}
return header;
@ -1404,8 +1406,9 @@ bool QHttp2ProtocolHandler::tryReserveStream(const Http2::Frame &pushPromiseFram
return false;
}
const auto method = pseudoHeaders[":method"].toLower();
if (method != "get" && method != "head")
const QByteArray method = pseudoHeaders[":method"];
if (method.compare("get", Qt::CaseInsensitive) != 0 &&
method.compare("head", Qt::CaseInsensitive) != 0)
return false;
QUrl url;

View File

@ -528,7 +528,7 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke
QUrl redirectUrl;
const QList<QPair<QByteArray, QByteArray> > fields = reply->header();
for (const QNetworkReply::RawHeaderPair &header : fields) {
if (header.first.toLower() == "location") {
if (header.first.compare("location", Qt::CaseInsensitive) == 0) {
redirectUrl = QUrl::fromEncoded(header.second);
break;
}

View File

@ -64,7 +64,7 @@ qint64 QHttpNetworkHeaderPrivate::contentLength() const
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
end = fields.constEnd();
for ( ; it != end; ++it)
if (qstricmp("content-length", it->first) == 0) {
if (it->first.compare("content-length", Qt::CaseInsensitive) == 0) {
value = it->second;
break;
}
@ -95,7 +95,7 @@ QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
end = fields.constEnd();
for ( ; it != end; ++it)
if (qstricmp(name.constData(), it->first) == 0)
if (name.compare(it->first, Qt::CaseInsensitive) == 0)
result += it->second;
return result;
@ -104,7 +104,7 @@ QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray
void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data)
{
auto firstEqualsName = [&name](const QPair<QByteArray, QByteArray> &header) {
return qstricmp(name.constData(), header.first) == 0;
return name.compare(header.first, Qt::CaseInsensitive) == 0;
};
fields.erase(std::remove_if(fields.begin(), fields.end(),
firstEqualsName),

View File

@ -390,7 +390,8 @@ qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
bool QHttpNetworkReplyPrivate::isCompressed()
{
QByteArray encoding = headerField("content-encoding");
return qstricmp(encoding.constData(), "gzip") == 0 || qstricmp(encoding.constData(), "deflate") == 0;
return encoding.compare("gzip", Qt::CaseInsensitive) == 0 ||
encoding.compare("deflate", Qt::CaseInsensitive) == 0;
}
void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
@ -401,7 +402,7 @@ void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
end = fields.end();
while (it != end) {
if (qstricmp(name.constData(), it->first.constData()) == 0) {
if (name.compare(it->first, Qt::CaseInsensitive) == 0) {
removedContentLength = strtoull(it->second.constData(), nullptr, 0);
fields.erase(it);
break;

View File

@ -189,7 +189,7 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData)
const auto headers = metaData.rawHeaders();
for (const auto &header : headers) {
if (header.first.toLower() == "content-length") {
if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) {
const qint64 size = header.second.toLongLong();
if (size > (maximumCacheSize() * 3)/4)
return 0;
@ -642,7 +642,7 @@ bool QCacheItem::canCompress() const
bool typeOk = false;
const auto headers = metaData.rawHeaders();
for (const auto &header : headers) {
if (header.first.toLower() == "content-length") {
if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) {
qint64 size = header.second.toLongLong();
if (size > MAX_COMPRESSION_SIZE)
return false;
@ -650,7 +650,7 @@ bool QCacheItem::canCompress() const
sizeOk = true;
}
if (header.first.toLower() == "content-type") {
if (header.first.compare("content-type", Qt::CaseInsensitive) == 0) {
QByteArray type = header.second;
if (type.startsWith("text/")
|| (type.startsWith("application/")

View File

@ -1318,7 +1318,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
if (!value.isEmpty()) {
// Why are we appending values for headers which are already
// present?
if (qstricmp(it->first.constData(), "set-cookie") == 0)
if (it->first.compare("set-cookie", Qt::CaseInsensitive) == 0)
value += '\n';
else
value += ", ";
@ -1584,7 +1584,7 @@ bool QNetworkReplyHttpImplPrivate::sendCacheContents(const QNetworkCacheMetaData
QUrl redirectUrl;
for ( ; it != end; ++it) {
if (httpRequest.isFollowRedirects() &&
!qstricmp(it->first.toLower().constData(), "location"))
!it->first.compare("location", Qt::CaseInsensitive))
redirectUrl = QUrl::fromEncoded(it->second);
setRawHeader(it->first, it->second);
}

View File

@ -918,11 +918,11 @@ static int parseHeaderName(const QByteArray &headerName)
switch (tolower(headerName.at(0))) {
case 'c':
if (qstricmp(headerName.constData(), "content-type") == 0)
if (headerName.compare("content-type", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ContentTypeHeader;
else if (qstricmp(headerName.constData(), "content-length") == 0)
else if (headerName.compare("content-length", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ContentLengthHeader;
else if (qstricmp(headerName.constData(), "cookie") == 0)
else if (headerName.compare("cookie", Qt::CaseInsensitive) == 0)
return QNetworkRequest::CookieHeader;
else if (qstricmp(headerName.constData(), "content-disposition") == 0)
return QNetworkRequest::ContentDispositionHeader;
@ -943,21 +943,21 @@ static int parseHeaderName(const QByteArray &headerName)
break;
case 'l':
if (qstricmp(headerName.constData(), "location") == 0)
if (headerName.compare("location", Qt::CaseInsensitive) == 0)
return QNetworkRequest::LocationHeader;
else if (qstricmp(headerName.constData(), "last-modified") == 0)
else if (headerName.compare("last-modified", Qt::CaseInsensitive) == 0)
return QNetworkRequest::LastModifiedHeader;
break;
case 's':
if (qstricmp(headerName.constData(), "set-cookie") == 0)
if (headerName.compare("set-cookie", Qt::CaseInsensitive) == 0)
return QNetworkRequest::SetCookieHeader;
else if (qstricmp(headerName.constData(), "server") == 0)
else if (headerName.compare("server", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ServerHeader;
break;
case 'u':
if (qstricmp(headerName.constData(), "user-agent") == 0)
if (headerName.compare("user-agent", Qt::CaseInsensitive) == 0)
return QNetworkRequest::UserAgentHeader;
break;
}
@ -1100,7 +1100,7 @@ QNetworkHeadersPrivate::findRawHeader(const QByteArray &key) const
RawHeadersList::ConstIterator it = rawHeaders.constBegin();
RawHeadersList::ConstIterator end = rawHeaders.constEnd();
for ( ; it != end; ++it)
if (qstricmp(it->first.constData(), key.constData()) == 0)
if (it->first.compare(key, Qt::CaseInsensitive) == 0)
return it;
return end; // not found
@ -1181,7 +1181,7 @@ void QNetworkHeadersPrivate::setCookedHeader(QNetworkRequest::KnownHeaders heade
void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const QByteArray &value)
{
auto firstEqualsKey = [&key](const RawHeaderPair &header) {
return qstricmp(header.first.constData(), key.constData()) == 0;
return header.first.compare(key, Qt::CaseInsensitive) == 0;
};
rawHeaders.erase(std::remove_if(rawHeaders.begin(), rawHeaders.end(),
firstEqualsKey),

View File

@ -412,7 +412,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
QByteArray headerVal;
for (int i = 0; i < values.size(); ++i) {
const QPair<QByteArray, QByteArray> &current = values.at(i);
if (current.first.toLower() != search)
if (current.first.compare(search, Qt::CaseInsensitive) != 0)
continue;
QByteArray str = current.second.toLower();
if (method < Basic && str.startsWith("basic")) {
@ -443,7 +443,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
break;
case DigestMd5: {
this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
if (options.value("stale").toLower() == "true")
if (options.value("stale").compare("true", Qt::CaseInsensitive) == 0)
phase = Start;
if (user.isEmpty() && password.isEmpty())
phase = Done;
@ -630,7 +630,7 @@ static QByteArray digestMd5ResponseHelper(
hash.addData(":", 1);
hash.addData(password);
QByteArray ha1 = hash.result();
if (alg.toLower() == "md5-sess") {
if (alg.compare("md5-sess", Qt::CaseInsensitive) == 0) {
hash.reset();
// RFC 2617 contains an error, it was:
// hash.addData(ha1);
@ -650,7 +650,7 @@ static QByteArray digestMd5ResponseHelper(
hash.addData(method);
hash.addData(":", 1);
hash.addData(digestUri);
if (qop.toLower() == "auth-int") {
if (qop.compare("auth-int", Qt::CaseInsensitive) == 0) {
hash.addData(":", 1);
hash.addData(hEntity);
}

View File

@ -627,10 +627,9 @@ void QHttpSocketEngine::slotSocketReadNotification()
// from http spec is also allowed.
if (proxyConnectionHeader.isEmpty())
proxyConnectionHeader = d->reply->headerField("Connection");
proxyConnectionHeader = proxyConnectionHeader.toLower();
if (proxyConnectionHeader == "close") {
if (proxyConnectionHeader.compare("close", Qt::CaseSensitive) == 0) {
willClose = true;
} else if (proxyConnectionHeader == "keep-alive") {
} else if (proxyConnectionHeader.compare("keep-alive", Qt::CaseInsensitive) == 0) {
willClose = false;
} else {
// no Proxy-Connection header, so use the default

View File

@ -415,8 +415,7 @@ static void *eglContextForContext(QOpenGLContext *context)
QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
{
#ifndef QT_NO_OPENGL
QByteArray lowerCaseResource = resource.toLower();
if (lowerCaseResource == "get_egl_context")
if (resource.compare("get_egl_context", Qt::CaseInsensitive) == 0)
return NativeResourceForContextFunction(eglContextForContext);
#else
Q_UNUSED(resource);

View File

@ -858,15 +858,32 @@ void tst_QByteArray::qstricmp()
if ( actual != 0 ) {
actual = (actual < 0 ? -1 : 1);
}
QCOMPARE(expected, actual);
QCOMPARE(actual, expected);
actual = str1.toLatin1().compare(str2.toLatin1(), Qt::CaseInsensitive);
if ( actual != 0 ) {
actual = (actual < 0 ? -1 : 1);
}
QCOMPARE(actual, expected);
actual = str1.toLatin1().compare(str2.toLatin1().constData(), Qt::CaseInsensitive);
if ( actual != 0 ) {
actual = (actual < 0 ? -1 : 1);
}
QCOMPARE(actual, expected);
}
void tst_QByteArray::qstricmp_singularities()
{
QCOMPARE(::qstricmp(0, 0), 0);
QVERIFY(::qstricmp(0, "a") != 0);
QVERIFY(::qstricmp("a", 0) != 0);
QVERIFY(::qstricmp(0, "a") < 0);
QVERIFY(::qstricmp("a", 0) > 0);
QCOMPARE(::qstricmp("", ""), 0);
QCOMPARE(QByteArray().compare(nullptr, Qt::CaseInsensitive), 0);
QCOMPARE(QByteArray().compare("", Qt::CaseInsensitive), 0);
QVERIFY(QByteArray("a").compare(nullptr, Qt::CaseInsensitive) > 0);
QVERIFY(QByteArray("a").compare("", Qt::CaseInsensitive) > 0);
QVERIFY(QByteArray().compare("a", Qt::CaseInsensitive) < 0);
}
void tst_QByteArray::qstrnicmp_singularities()
@ -876,6 +893,9 @@ void tst_QByteArray::qstrnicmp_singularities()
QVERIFY(::qstrnicmp("a", 0, 123) != 0);
QCOMPARE(::qstrnicmp("", "", 123), 0);
QCOMPARE(::qstrnicmp("a", "B", 0), 0);
QCOMPARE(QByteArray().compare(QByteArray(), Qt::CaseInsensitive), 0);
QVERIFY(QByteArray().compare(QByteArray("a"), Qt::CaseInsensitive) < 0);
QVERIFY(QByteArray("a").compare(QByteArray(), Qt::CaseInsensitive) > 0);
}
void tst_QByteArray::chop_data()
@ -1759,6 +1779,12 @@ void tst_QByteArray::compare()
const bool isLess = result < 0;
const bool isGreater = result > 0;
int cmp = str1.compare(str2);
if (cmp)
cmp = (cmp < 0 ? -1 : 1);
QCOMPARE(cmp, result);
// basic tests:
QCOMPARE(str1 == str2, isEqual);
QCOMPARE(str1 < str2, isLess);