summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2014-01-14 22:34:57 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-31 21:51:23 +0100
commit3bae7b0a2833c5de9e9b66a7068d2fd9cccabb79 (patch)
tree1d237c807923371d54e25237110f4fdda39cd47c /src
parent8b77fe9f6419017a0a270be464fa3e8b2771dadb (diff)
Centralize the UTF16-Latin1 comparisons in one place
We have quite a few versions of this code in qstring.cpp, which means that it's hard to optimize them all. Instead, create two functions to do the comparisons, one case-sensitive (ucstrncmp & ucstrcmp) and one case-insensitive (ucstricmp). Change-Id: I55c6588ade160bc8d16e19727b8f3dca523b38bf Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qstring.cpp92
1 files changed, 29 insertions, 63 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index cf85807888..a2ea3bfdfa 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -307,6 +307,21 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l)
return 0;
}
+static int ucstrncmp(const QChar *a, const uchar *c, int l)
+{
+ const ushort *uc = reinterpret_cast<const ushort *>(a);
+ const ushort *e = uc + l;
+
+ while (uc < e) {
+ int diff = *uc - *c;
+ if (diff)
+ return diff;
+ uc++, c++;
+ }
+
+ return 0;
+}
+
// Unicode case-sensitive comparison
static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
{
@@ -331,6 +346,13 @@ static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
return ucstrncmp(reinterpret_cast<const QChar *>(a), reinterpret_cast<const QChar *>(b), length) == 0;
}
+static int ucstrcmp(const QChar *a, int alen, const uchar *b, int blen)
+{
+ int l = qMin(alen, blen);
+ int cmp = ucstrncmp(a, b, l);
+ return cmp ? cmp : (alen-blen);
+}
+
/*!
\internal
@@ -2226,17 +2248,7 @@ bool QString::operator==(QLatin1String other) const
if (!other.size())
return isEmpty();
- const ushort *uc = d->data();
- const ushort *e = uc + d->size;
- const uchar *c = (uchar *)other.latin1();
-
- while (uc < e) {
- if (*uc != *c)
- return false;
- ++uc;
- ++c;
- }
- return true;
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) == 0;
}
/*! \fn bool QString::operator==(const QByteArray &other) const
@@ -2290,16 +2302,7 @@ bool QString::operator<(QLatin1String other) const
if (!c || *c == 0)
return false;
- const ushort *uc = d->data();
- const ushort *e = uc + qMin(d->size, other.size());
-
- while (uc < e) {
- if (*uc != *c)
- break;
- ++uc;
- ++c;
- }
- return (uc == e ? d->size < other.size() : *uc < *c);
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) < 0;
}
/*! \fn bool QString::operator<(const QByteArray &other) const
@@ -2392,16 +2395,7 @@ bool QString::operator>(QLatin1String other) const
if (!c || *c == '\0')
return !isEmpty();
- const ushort *uc = d->data();
- const ushort *e = uc + qMin(d->size, other.size());
-
- while (uc < e) {
- if (*uc != *c)
- break;
- ++uc;
- ++c;
- }
- return (uc == e) ? d->size > other.size() : *uc > *c;
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) > 0;
}
/*! \fn bool QString::operator>(const QByteArray &other) const
@@ -5110,22 +5104,7 @@ int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
return length1;
if (cs == Qt::CaseSensitive) {
- const ushort *e = uc + length1;
- if (s2.size() < length1)
- e = uc + s2.size();
- while (uc < e) {
- int diff = *uc - *c;
- if (diff)
- return diff;
- uc++, c++;
- }
-
- if (uc == uce) {
- if (c == (const uchar *)s2.latin1() + s2.size())
- return 0;
- return -1;
- }
- return 1;
+ return ucstrcmp(data1, length1, c, s2.size());
} else {
return ucstricmp(uc, uce, c, c + s2.size());
}
@@ -8329,19 +8308,10 @@ bool operator==(QLatin1String s1, const QStringRef &s2)
if (s1.size() != s2.size())
return false;
- const ushort *uc = reinterpret_cast<const ushort *>(s2.unicode());
- const ushort *e = uc + s2.size();
const uchar *c = reinterpret_cast<const uchar *>(s1.latin1());
if (!c)
return s2.isEmpty();
-
- while (*c) {
- if (uc == e || *uc != *c)
- return false;
- ++uc;
- ++c;
- }
- return (uc == e);
+ return ucstrncmp(s2.unicode(), c, s2.size()) == 0;
}
/*!
@@ -9313,9 +9283,7 @@ static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
const ushort *data = reinterpret_cast<const ushort*>(haystack);
const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; ++i)
- if (data[i] != latin[i])
- return false;
+ return ucstrncmp(haystack, latin, slen) == 0;
} else {
for (int i = 0; i < slen; ++i)
if (foldCase(data[i]) != foldCase((ushort)latin[i]))
@@ -9365,9 +9333,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
const ushort *data = reinterpret_cast<const ushort*>(haystack);
if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; i++)
- if (data[pos+i] != latin[i])
- return false;
+ return ucstrncmp(haystack + pos, latin, slen) == 0;
} else {
for (int i = 0; i < slen; i++)
if (foldCase(data[pos+i]) != foldCase((ushort)latin[i]))