diff --git a/src/lib/component/controller/helper/DummyNode.h b/src/lib/component/controller/helper/DummyNode.h index e2c9af09..ca9f08cd 100644 --- a/src/lib/component/controller/helper/DummyNode.h +++ b/src/lib/component/controller/helper/DummyNode.h @@ -40,7 +40,7 @@ public: return a->isBundleNode(); } - return utility::toLowerCase(a->name) < utility::toLowerCase(b->name); + return utility::caseInsensitiveLess(a->name, b->name); } }; diff --git a/src/lib_utility/utility/utilityString.cpp b/src/lib_utility/utility/utilityString.cpp index 2fed84c9..19604878 100644 --- a/src/lib_utility/utility/utilityString.cpp +++ b/src/lib_utility/utility/utilityString.cpp @@ -622,4 +622,27 @@ std::wstring convertWhiteSpacesToSingleSpaces(const std::wstring& str) return join>(parts, L" "); } + +bool caseInsensitiveLess(const std::wstring& s1, const std::wstring& s2) +{ + size_t s1_size = s1.size(); + size_t s2_size = s2.size(); + bool res_cmp = s1_size < s2_size; + size_t lesser_size = s2_size ^ ((s1_size ^ s2_size) & -res_cmp); + for (size_t i = 0; i < lesser_size; ++i) + { + wchar_t s1_wchr = s1[i]; + wchar_t s2_wchr = s2[i]; + if (s1_wchr != s2_wchr) + { + s1_wchr = towlower(s1_wchr); + s2_wchr = towlower(s2_wchr); + if (s1_wchr != s2_wchr) + { + return s1_wchr < s2_wchr; + } + } + } + return res_cmp; +} } // namespace utility diff --git a/src/lib_utility/utility/utilityString.h b/src/lib_utility/utility/utilityString.h index 4d360fcf..7e9716ef 100644 --- a/src/lib_utility/utility/utilityString.h +++ b/src/lib_utility/utility/utilityString.h @@ -99,6 +99,8 @@ std::wstring elide(const std::wstring& str, ElideMode mode, size_t size); std::wstring convertWhiteSpacesToSingleSpaces(const std::wstring& str); +bool caseInsensitiveLess(const std::wstring& s1, const std::wstring& s2); + template ContainerType split(const std::string& str, const std::string& delimiter) { diff --git a/src/test/UtilityStringTestSuite.cpp b/src/test/UtilityStringTestSuite.cpp index fc53c582..e9574d78 100644 --- a/src/test/UtilityStringTestSuite.cpp +++ b/src/test/UtilityStringTestSuite.cpp @@ -300,3 +300,69 @@ TEST_CASE("replace") REQUIRE("" == utility::replace("", "foo", "bar")); REQUIRE("foobar" == utility::replace("foobar", "ba", "ba")); } + +TEST_CASE("caseInsensitiveLess should return false when comparing empty wstrings") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"", L"")); +} + +TEST_CASE("caseInsensitiveLess should return false when both wstrings are equal") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when both wstrings have" + "different cases but after lower casing are equal") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_CD!", L"aB_cD!")); +} + +TEST_CASE("caseInsensitiveLess should return true when first wstring is empty and second not") +{ + REQUIRE(utility::caseInsensitiveLess(L"", L"ab")); +} + +TEST_CASE("caseInsensitiveLess should return false when second wstring is empty and first not") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab", L"")); +} + +TEST_CASE("caseInsensitiveLess should return true when first wstring is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cd!e")); +} + +TEST_CASE("caseInsensitiveLess should return false when second wstring is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!e", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing first wstring, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"aB_cd!", L"ab_cd!e")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing second wstring, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cD!e")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing both wstrings, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"aB_cd!", L"ab_cD!E")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing first wstring, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_Cd!e", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing second wstring, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!e", L"Ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing both wstrings, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cD!E", L"aB_cd!")); +}