diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-01-14 22:34:57 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-31 21:51:23 +0100 |
commit | 3bae7b0a2833c5de9e9b66a7068d2fd9cccabb79 (patch) | |
tree | 1d237c807923371d54e25237110f4fdda39cd47c /src | |
parent | 8b77fe9f6419017a0a270be464fa3e8b2771dadb (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.cpp | 92 |
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])) |