Fix operator==(QLatin1String, QLatin1String) and friends for substrings
authorKent Hansen <kent.hansen@nokia.com>
Wed, 1 Feb 2012 16:37:02 +0000 (17:37 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 2 Feb 2012 10:10:04 +0000 (11:10 +0100)
QLatin1String now has a constructor that takes explicit length, which
makes it possible to create a QLatin1String that isn't null-terminated.
Made the QLatin1String comparison operators work in that case.

Change-Id: I234ba851e67a6f5cfbb46fb6f0b22623ce40be28
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/corelib/tools/qstring.h
tests/auto/corelib/tools/qstring/tst_qstring.cpp

index 614ba71..129a53e 100644 (file)
@@ -972,17 +972,21 @@ inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QLatin1String &s
 { return (QString::fromAscii(s1, s1 ? int(strlen(s1)) : -1) >= s2); }
 
 inline bool operator==(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) == 0); }
+{ return (s1.size() == s2.size() && !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
 inline bool operator!=(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) != 0); }
+{ return (s1.size() != s2.size() || memcmp(s1.latin1(), s2.latin1(), s1.size())); }
 inline bool operator<(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) < 0); }
+{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
+  return (r < 0) || (r == 0 && s1.size() < s2.size()); }
 inline bool operator<=(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) <= 0); }
+{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
+  return (r < 0) || (r == 0 && s1.size() <= s2.size()); }
 inline bool operator>(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) > 0); }
+{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
+  return (r > 0) || (r == 0 && s1.size() > s2.size()); }
 inline bool operator>=(const QLatin1String &s1, const QLatin1String &s2)
-{ return (qstrcmp(s1.latin1(), s2.latin1()) >= 0); }
+{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
+  return (r > 0) || (r == 0 && s1.size() >= s2.size()); }
 
 
 inline bool QString::operator==(const QByteArray &s) const
index 2a94943..f3ff6e0 100644 (file)
@@ -222,6 +222,7 @@ private slots:
     void toHtmlEscaped();
 
     void operatorGreaterWithQLatin1String();
+    void compareQLatin1Strings();
 };
 
 typedef QList<int> IntList;
@@ -5194,6 +5195,88 @@ void tst_QString::operatorGreaterWithQLatin1String()
     QVERIFY(!(stringfoo < latin1foo));
 }
 
+void tst_QString::compareQLatin1Strings()
+{
+    QLatin1String abc("abc");
+    QLatin1String abcd("abcd");
+    QLatin1String cba("cba");
+    QLatin1String de("de");
+
+    QVERIFY(abc == abc);
+    QVERIFY(!(abc == cba));
+    QVERIFY(!(cba == abc));
+    QVERIFY(!(abc == abcd));
+    QVERIFY(!(abcd == abc));
+
+    QVERIFY(abc != cba);
+    QVERIFY(!(abc != abc));
+    QVERIFY(cba != abc);
+    QVERIFY(abc != abcd);
+    QVERIFY(abcd != abc);
+
+    QVERIFY(abc < abcd);
+    QVERIFY(abc < cba);
+    QVERIFY(abc < de);
+    QVERIFY(abcd < cba);
+    QVERIFY(!(abc < abc));
+    QVERIFY(!(abcd < abc));
+    QVERIFY(!(de < cba));
+
+    QVERIFY(abcd > abc);
+    QVERIFY(cba > abc);
+    QVERIFY(de > abc);
+    QVERIFY(!(abc > abc));
+    QVERIFY(!(abc > abcd));
+    QVERIFY(!(abcd > cba));
+
+    QVERIFY(abc <= abc);
+    QVERIFY(abc <= abcd);
+    QVERIFY(abc <= cba);
+    QVERIFY(abc <= de);
+    QVERIFY(!(abcd <= abc));
+    QVERIFY(!(cba <= abc));
+    QVERIFY(!(cba <= abcd));
+    QVERIFY(!(de <= abc));
+
+    QVERIFY(abc >= abc);
+    QVERIFY(abcd >= abc);
+    QVERIFY(!(abc >= abcd));
+    QVERIFY(cba >= abc);
+    QVERIFY(!(abc >= cba));
+    QVERIFY(de >= abc);
+    QVERIFY(!(abc >= de));
+
+    QLatin1String subfoo("fooZZ", 3);
+    QLatin1String foo("foo");
+    QVERIFY(subfoo == foo);
+    QVERIFY(foo == subfoo);
+    QVERIFY(!(subfoo != foo));
+    QVERIFY(!(foo != subfoo));
+    QVERIFY(!(foo < subfoo));
+    QVERIFY(!(subfoo < foo));
+    QVERIFY(foo >= subfoo);
+    QVERIFY(subfoo >= foo);
+    QVERIFY(!(foo > subfoo));
+    QVERIFY(!(subfoo > foo));
+    QVERIFY(foo <= subfoo);
+    QVERIFY(subfoo <= foo);
+
+    QLatin1String subabc("abcZZ", 3);
+    QLatin1String subab("abcZZ", 2);
+    QVERIFY(subabc != subab);
+    QVERIFY(subab != subabc);
+    QVERIFY(!(subabc == subab));
+    QVERIFY(!(subab == subabc));
+    QVERIFY(subab < subabc);
+    QVERIFY(!(subabc < subab));
+    QVERIFY(subabc > subab);
+    QVERIFY(!(subab > subabc));
+    QVERIFY(subab <= subabc);
+    QVERIFY(!(subabc <= subab));
+    QVERIFY(subabc >= subab);
+    QVERIFY(!(subab >= subabc));
+}
+
 QTEST_APPLESS_MAIN(tst_QString)
 
 #include "tst_qstring.moc"