summaryrefslogtreecommitdiff
path: root/zen/zstring.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2016-03-16 21:34:59 +0100
committerDaniel Wilhelm <daniel@wili.li>2016-03-16 21:34:59 +0100
commit339ed7f63798fb5ccab05fa7fb9d0d95743c9c89 (patch)
tree214819f601b69bfd32507ca59047dd4d68ed5632 /zen/zstring.cpp
parent7.9 (diff)
downloadFreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.tar.gz
FreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.tar.bz2
FreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.zip
8.0
Diffstat (limited to 'zen/zstring.cpp')
-rw-r--r--zen/zstring.cpp120
1 files changed, 53 insertions, 67 deletions
diff --git a/zen/zstring.cpp b/zen/zstring.cpp
index 59f15f19..6d249e70 100644
--- a/zen/zstring.cpp
+++ b/zen/zstring.cpp
@@ -8,8 +8,7 @@
#include <stdexcept>
#ifdef ZEN_WIN
- #include "dll.h"
- //#include "win_ver.h"
+ #include "win.h"
#endif
using namespace zen;
@@ -37,80 +36,67 @@ time per call | function
#ifdef ZEN_WIN
-namespace
-{
-//try to call "CompareStringOrdinal" for low-level string comparison: unfortunately available not before Windows Vista!
-//by a factor ~3 faster than old string comparison using "LCMapString"
-typedef int (WINAPI* CompareStringOrdinalFunc)(LPCWSTR lpString1, int cchCount1,
- LPCWSTR lpString2, int cchCount2, BOOL bIgnoreCase);
-const SysDllFun<CompareStringOrdinalFunc> compareStringOrdinal = SysDllFun<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal");
-//watch for dependencies in global namespace!!!
-}
-
-
int cmpStringNoCase(const wchar_t* lhs, size_t lhsLen, const wchar_t* rhs, size_t rhsLen)
{
assert(std::find(lhs, lhs + lhsLen, 0) == lhs + lhsLen); //don't expect embedded nulls!
assert(std::find(rhs, rhs + rhsLen, 0) == rhs + rhsLen); //
- if (compareStringOrdinal) //this additional test has no noticeable performance impact
+#ifdef ZEN_WIN_VISTA_AND_LATER
+ //"CompareStringOrdinal" (available since Windows Vista) is by a factor ~3 faster than old string comparison using "LCMapString"
+ const int rv = ::CompareStringOrdinal(lhs, //__in LPCWSTR lpString1,
+ static_cast<int>(lhsLen), //__in int cchCount1,
+ rhs, //__in LPCWSTR lpString2,
+ static_cast<int>(rhsLen), //__in int cchCount2,
+ true); //__in BOOL bIgnoreCase
+ if (rv <= 0)
+ throw std::runtime_error("Error comparing strings (CompareStringOrdinal). " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
+ else
+ return rv - 2; //convert to C-style string compare result
+#else
+ //do NOT use "CompareString"; this function is NOT meant for file name comparisons (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
+ //the only reliable way to compare filepaths (with XP) is to call "CharUpper" or "LCMapString":
+
+ const auto minSize = std::min(lhsLen, rhsLen);
+
+ if (minSize == 0) //LCMapString does not allow input sizes of 0!
+ return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
+
+ auto copyToUpperCase = [minSize](const wchar_t* strIn, wchar_t* strOut)
+ {
+ //faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString()
+ if (::LCMapString(LOCALE_INVARIANT, //__in LCID Locale,
+ LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
+ strIn, //__in LPCTSTR lpSrcStr,
+ static_cast<int>(minSize), //__in int cchSrc,
+ strOut, //__out LPTSTR lpDestStr,
+ static_cast<int>(minSize)) == 0) //__in int cchDest
+ throw std::runtime_error("Error comparing strings (LCMapString). " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
+ };
+
+ auto eval = [&](wchar_t* bufL, wchar_t* bufR)
+ {
+ copyToUpperCase(lhs, bufL);
+ copyToUpperCase(rhs, bufR);
+
+ const int rv = ::wcsncmp(bufL, bufR, minSize);
+ if (rv != 0)
+ return rv;
+
+ return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
+ };
+
+ if (minSize <= MAX_PATH) //performance optimization: stack
{
- const int rv = compareStringOrdinal(lhs, //__in LPCWSTR lpString1,
- static_cast<int>(lhsLen), //__in int cchCount1,
- rhs, //__in LPCWSTR lpString2,
- static_cast<int>(rhsLen), //__in int cchCount2,
- true); //__in BOOL bIgnoreCase
- if (rv <= 0)
- throw std::runtime_error("Error comparing strings (CompareStringOrdinal). " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
- else
- return rv - 2; //convert to C-style string compare result
+ wchar_t bufferL[MAX_PATH] = {};
+ wchar_t bufferR[MAX_PATH] = {};
+ return eval(bufferL, bufferR);
}
- else //fallback
+ else //use freestore
{
- //do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
- //the only reliable way to compare filepaths (with XP) is to call "CharUpper" or "LCMapString":
-
- const auto minSize = std::min(lhsLen, rhsLen);
-
- if (minSize == 0) //LCMapString does not allow input sizes of 0!
- return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
-
- auto copyToUpperCase = [minSize](const wchar_t* strIn, wchar_t* strOut)
- {
- //faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString()
- if (::LCMapString(LOCALE_INVARIANT, //__in LCID Locale,
- LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
- strIn, //__in LPCTSTR lpSrcStr,
- static_cast<int>(minSize), //__in int cchSrc,
- strOut, //__out LPTSTR lpDestStr,
- static_cast<int>(minSize)) == 0) //__in int cchDest
- throw std::runtime_error("Error comparing strings (LCMapString). " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
- };
-
- auto eval = [&](wchar_t* bufL, wchar_t* bufR)
- {
- copyToUpperCase(lhs, bufL);
- copyToUpperCase(rhs, bufR);
-
- const int rv = ::wcsncmp(bufL, bufR, minSize);
- if (rv != 0)
- return rv;
-
- return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
- };
-
- if (minSize <= MAX_PATH) //performance optimization: stack
- {
- wchar_t bufferL[MAX_PATH] = {};
- wchar_t bufferR[MAX_PATH] = {};
- return eval(bufferL, bufferR);
- }
- else //use freestore
- {
- std::vector<wchar_t> buffer(2 * minSize);
- return eval(&buffer[0], &buffer[minSize]);
- }
+ std::vector<wchar_t> buffer(2 * minSize);
+ return eval(&buffer[0], &buffer[minSize]);
}
+#endif
}
bgstack15