summaryrefslogtreecommitdiff
path: root/zen/zstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/zstring.cpp')
-rw-r--r--zen/zstring.cpp101
1 files changed, 63 insertions, 38 deletions
diff --git a/zen/zstring.cpp b/zen/zstring.cpp
index f16af6a0..a2a26f83 100644
--- a/zen/zstring.cpp
+++ b/zen/zstring.cpp
@@ -6,6 +6,7 @@
#include "zstring.h"
#include <stdexcept>
+#include <unordered_map>
#ifdef ZEN_WIN
#include "dll.h"
@@ -40,7 +41,7 @@ public:
void insert(const void* ptr, size_t size)
{
boost::lock_guard<boost::mutex> dummy(lockActStrings);
- if (!activeStrings.insert(std::make_pair(ptr, size)).second)
+ if (!activeStrings.emplace(ptr, size).second)
reportProblem("Serious Error: New memory points into occupied space: " + rawMemToString(ptr, size));
}
@@ -96,7 +97,7 @@ private:
}
boost::mutex lockActStrings;
- zen::hash_map<const void*, size_t> activeStrings;
+ std::unordered_map<const void*, size_t> activeStrings;
};
//caveat: function scope static initialization is not thread-safe in VS 2010!
@@ -148,15 +149,15 @@ const SysDllFun<CompareStringOrdinalFunc> compareStringOrdinal = SysDllFun<Compa
}
-int z_impl::compareFilenamesNoCase(const wchar_t* lhs, const wchar_t* rhs, size_t sizeLhs, size_t sizeRhs)
+int cmpFileName(const Zstring& lhs, const Zstring& rhs)
{
if (compareStringOrdinal) //this additional test has no noticeable performance impact
{
- const int rv = compareStringOrdinal(lhs, //__in LPCWSTR lpString1,
- static_cast<int>(sizeLhs), //__in int cchCount1,
- rhs, //__in LPCWSTR lpString2,
- static_cast<int>(sizeRhs), //__in int cchCount2,
- true); //__in BOOL bIgnoreCase
+ const int rv = compareStringOrdinal(lhs.c_str(), //__in LPCWSTR lpString1,
+ static_cast<int>(lhs.size()), //__in int cchCount1,
+ rhs.c_str(), //__in LPCWSTR lpString2,
+ static_cast<int>(rhs.size()), //__in int cchCount2,
+ true); //__in BOOL bIgnoreCase
if (rv <= 0)
throw std::runtime_error("Error comparing strings (CompareStringOrdinal).");
else
@@ -167,31 +168,35 @@ int z_impl::compareFilenamesNoCase(const wchar_t* lhs, const wchar_t* rhs, size_
//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":
- auto copyToUpperCase = [](const wchar_t* strIn, wchar_t* strOut, size_t len)
+ const size_t sizeLhs = lhs.size();
+ const size_t sizeRhs = rhs.size();
+
+ const auto minSize = std::min(sizeLhs, sizeRhs);
+
+ if (minSize == 0) //LCMapString does not allow input sizes of 0!
+ return static_cast<int>(sizeLhs) - static_cast<int>(sizeRhs);
+
+ auto copyToUpperCase = [&](const wchar_t* strIn, wchar_t* strOut)
{
//faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString()
- if (::LCMapString(ZSTRING_INVARIANT_LOCALE, //__in LCID Locale,
- LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
- strIn, //__in LPCTSTR lpSrcStr,
- static_cast<int>(len), //__in int cchSrc,
- strOut, //__out LPTSTR lpDestStr,
- static_cast<int>(len)) == 0) //__in int cchDest
+ if (::LCMapString(ZSTRING_INVARIANT_LOCALE, //__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).");
};
- const auto minSize = std::min(sizeLhs, sizeRhs);
-
auto eval = [&](wchar_t* bufL, wchar_t* bufR)
{
- if (minSize > 0) //LCMapString does not allow input sizes of 0!
- {
- copyToUpperCase(lhs, bufL, minSize);
- copyToUpperCase(rhs, bufR, minSize);
-
- const int rv = ::wmemcmp(bufL, bufR, minSize);
- if (rv != 0)
- return rv;
- }
+ copyToUpperCase(lhs.c_str(), bufL);
+ copyToUpperCase(rhs.c_str(), bufR);
+
+ const int rv = ::wmemcmp(bufL, bufR, minSize);
+ if (rv != 0)
+ return rv;
+
return static_cast<int>(sizeLhs) - static_cast<int>(sizeRhs);
};
@@ -203,35 +208,55 @@ int z_impl::compareFilenamesNoCase(const wchar_t* lhs, const wchar_t* rhs, size_
}
else //use freestore
{
- std::vector<wchar_t> bufferL(minSize);
- std::vector<wchar_t> bufferR(minSize);
- return eval(&bufferL[0], &bufferR[0]);
+ std::vector<wchar_t> buffer(2 * minSize);
+ return eval(&buffer[0], &buffer[minSize]);
}
}
}
-void z_impl::makeFilenameUpperCase(wchar_t* str, size_t size)
+Zstring makeUpperCopy(const Zstring& str)
{
- if (size == 0) //LCMapString does not allow input sizes of 0!
- return;
+ const int len = static_cast<int>(str.size());
+
+ if (len == 0) //LCMapString does not allow input sizes of 0!
+ return str;
+
+ Zstring output;
+ output.resize(len);
//use Windows' upper case conversion: faster than ::CharUpper()
- if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, str, static_cast<int>(size), str, static_cast<int>(size)) == 0)
- throw std::runtime_error("Error converting to upper case! (LCMapString)");
+ if (::LCMapString(ZSTRING_INVARIANT_LOCALE, //__in LCID Locale,
+ LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
+ str.c_str(), //__in LPCTSTR lpSrcStr,
+ len, //__in int cchSrc,
+ &*output.begin(), //__out LPTSTR lpDestStr,
+ len) == 0) //__in int cchDest
+ throw std::runtime_error("Error comparing strings (LCMapString).");
+
+ return output;
}
+
#elif defined ZEN_MAC
-int z_impl::compareFilenamesNoCase(const char* lhs, const char* rhs, size_t sizeLhs, size_t sizeRhs)
+int cmpFileName(const Zstring& lhs, const Zstring& rhs)
{
- return ::strcasecmp(lhs, rhs); //locale-dependent!
+ return ::strcasecmp(lhs.c_str(), rhs.c_str()); //locale-dependent!
}
-void z_impl::makeFilenameUpperCase(char* str, size_t size)
+Zstring makeUpperCopy(const Zstring& str)
{
- std::for_each(str, str + size, [](char& c) { c = static_cast<char>(::toupper(static_cast<unsigned char>(c))); }); //locale-dependent!
+ const size_t len = str.size();
+
+ Zstring output;
+ output.resize(len);
+
+ std::transform(str.begin(), str.end(), output.begin(), [](char c) { return static_cast<char>(::toupper(static_cast<unsigned char>(c))); }); //locale-dependent!
+
//result of toupper() is an unsigned char mapped to int range, so the char representation is in the last 8 bits and we need not care about signedness!
//this should work for UTF-8, too: all chars >= 128 are mapped upon themselves!
+
+ return output;
}
#endif
bgstack15