summaryrefslogtreecommitdiff
path: root/zen/zstring.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2015-10-02 14:55:46 +0200
committerDaniel Wilhelm <daniel@wili.li>2015-10-02 14:55:46 +0200
commitb32d1e948b32a8f7607ebc30f10dda903426f63c (patch)
tree7fa78f18308671970198981b650e237bcd84957e /zen/zstring.cpp
parent7.0 (diff)
downloadFreeFileSync-b32d1e948b32a8f7607ebc30f10dda903426f63c.tar.gz
FreeFileSync-b32d1e948b32a8f7607ebc30f10dda903426f63c.tar.bz2
FreeFileSync-b32d1e948b32a8f7607ebc30f10dda903426f63c.zip
7.1
Diffstat (limited to 'zen/zstring.cpp')
-rw-r--r--zen/zstring.cpp131
1 files changed, 23 insertions, 108 deletions
diff --git a/zen/zstring.cpp b/zen/zstring.cpp
index 73ef3ee9..68934e19 100644
--- a/zen/zstring.cpp
+++ b/zen/zstring.cpp
@@ -16,98 +16,8 @@
#include <ctype.h> //toupper()
#endif
-#ifndef NDEBUG
- #include "thread.h"
- #include <iostream>
-#endif
-
using namespace zen;
-
-#ifndef NDEBUG
-namespace
-{
-class LeakChecker //small test for memory leaks
-{
-public:
- static LeakChecker& get()
- {
- //meyers singleton: avoid static initialization order problem in global namespace!
- static LeakChecker inst;
- return inst;
- }
-
- void insert(const void* ptr, size_t size)
- {
- boost::lock_guard<boost::mutex> dummy(lockActStrings);
- if (!activeStrings.emplace(ptr, size).second)
- reportProblem("Serious Error: New memory points into occupied space: " + rawMemToString(ptr, size));
- }
-
- void remove(const void* ptr)
- {
- boost::lock_guard<boost::mutex> dummy(lockActStrings);
- if (activeStrings.erase(ptr) != 1)
- reportProblem("Serious Error: No memory available for deallocation at this location!");
- }
-
-private:
- LeakChecker() {}
-
- ~LeakChecker()
- {
- if (!activeStrings.empty())
- {
- std::string leakingStrings;
-
- int items = 0;
- for (auto it = activeStrings.begin(); it != activeStrings.end() && items < 20; ++it, ++items)
- leakingStrings += "\"" + rawMemToString(it->first, it->second) + "\"\n";
-
- const std::string message = std::string("Memory leak detected!") + "\n\n"
- + "Candidates:\n" + leakingStrings;
-#ifdef ZEN_WIN
- MessageBoxA(nullptr, message.c_str(), "Error", MB_SERVICE_NOTIFICATION | MB_ICONERROR);
-#else
- std::cerr << message;
- std::abort();
-#endif
- }
- }
-
- LeakChecker (const LeakChecker&) = delete;
- LeakChecker& operator=(const LeakChecker&) = delete;
-
- static std::string rawMemToString(const void* ptr, size_t size)
- {
- std::string output(reinterpret_cast<const char*>(ptr), std::min<size_t>(size, 100));
- replace(output, '\0', ' '); //don't stop at 0-termination
- return output;
- }
-
- void reportProblem(const std::string& message) //throw std::logic_error
- {
-#ifdef ZEN_WIN
- ::MessageBoxA(nullptr, message.c_str(), "Error", MB_SERVICE_NOTIFICATION | MB_ICONERROR);
-#else
- std::cerr << message;
-#endif
- throw std::logic_error("Memory leak! " + message + "\n" + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
- }
-
- boost::mutex lockActStrings;
- std::unordered_map<const void*, size_t> activeStrings;
-};
-
-//caveat: function scope static initialization is not thread-safe in VS 2010!
-auto& dummy = LeakChecker::get(); //still not sufficient if multiple threads access during static init!!!
-}
-
-void z_impl::leakCheckerInsert(const void* ptr, size_t size) { LeakChecker::get().insert(ptr, size); }
-void z_impl::leakCheckerRemove(const void* ptr ) { LeakChecker::get().remove(ptr); }
-#endif //NDEBUG
-
-
/*
Perf test: compare strings 10 mio times; 64 bit build
-----------------------------------------------------
@@ -148,15 +58,18 @@ const SysDllFun<CompareStringOrdinalFunc> compareStringOrdinal = SysDllFun<Compa
}
-int cmpFileName(const Zstring& lhs, const Zstring& rhs)
+int cmpFilePath(const Zchar* lhs, size_t lhsLen, const Zchar* 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
{
- 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
+ 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
@@ -167,13 +80,10 @@ int cmpFileName(const Zstring& lhs, const Zstring& rhs)
//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 size_t sizeLhs = lhs.size();
- const size_t sizeRhs = rhs.size();
-
- const auto minSize = std::min(sizeLhs, sizeRhs);
+ const auto minSize = std::min(lhsLen, rhsLen);
if (minSize == 0) //LCMapString does not allow input sizes of 0!
- return static_cast<int>(sizeLhs) - static_cast<int>(sizeRhs);
+ return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
auto copyToUpperCase = [&](const wchar_t* strIn, wchar_t* strOut)
{
@@ -189,14 +99,14 @@ int cmpFileName(const Zstring& lhs, const Zstring& rhs)
auto eval = [&](wchar_t* bufL, wchar_t* bufR)
{
- copyToUpperCase(lhs.c_str(), bufL);
- copyToUpperCase(rhs.c_str(), bufR);
+ copyToUpperCase(lhs, bufL);
+ copyToUpperCase(rhs, bufR);
- const int rv = ::wmemcmp(bufL, bufR, minSize);
+ const int rv = ::wcsncmp(bufL, bufR, minSize);
if (rv != 0)
return rv;
- return static_cast<int>(sizeLhs) - static_cast<int>(sizeRhs);
+ return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
};
if (minSize <= MAX_PATH) //performance optimization: stack
@@ -238,10 +148,15 @@ Zstring makeUpperCopy(const Zstring& str)
#elif defined ZEN_MAC
-int cmpFileName(const Zstring& lhs, const Zstring& rhs)
+int cmpFilePath(const Zchar* lhs, size_t lhsLen, const Zchar* rhs, size_t rhsLen)
{
- const int rv = ::strcasecmp(lhs.c_str(), rhs.c_str()); //locale-dependent!
- return rv;
+ assert(std::find(lhs, lhs + lhsLen, 0) == lhs + lhsLen); //don't expect embedded nulls!
+ assert(std::find(rhs, rhs + rhsLen, 0) == rhs + rhsLen); //
+
+ const int rv = ::strncasecmp(lhs, rhs, std::min(lhsLen, rhsLen)); //locale-dependent!
+ if (rv != 0)
+ return rv;
+ return static_cast<int>(lhsLen) - static_cast<int>(rhsLen);
}
bgstack15