diff options
Diffstat (limited to 'zen/zstring.h')
-rw-r--r-- | zen/zstring.h | 168 |
1 files changed, 50 insertions, 118 deletions
diff --git a/zen/zstring.h b/zen/zstring.h index df96df7b..f4a79181 100644 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -7,72 +7,38 @@ #ifndef ZSTRING_H_INCLUDED #define ZSTRING_H_INCLUDED -#include <cstring> //strcmp() #include "string_base.h" - -#ifndef NDEBUG -#include "thread.h" //includes <boost/thread.hpp> -#include <map> +#ifdef FFS_LINUX +#include <cstring> //strcmp +#elif defined FFS_MAC +#include <strings.h> //strcasecmp #endif #ifndef NDEBUG -class LeakChecker //small test for memory leaks +namespace z_impl { -public: - void insert(const void* ptr, size_t size) - { - boost::lock_guard<boost::mutex> dummy(lockActStrings); - if (activeStrings.find(ptr) != activeStrings.end()) - reportProblem("Fatal Error: New memory points into occupied space: " + rawMemToString(ptr, size)); - - activeStrings[ptr] = size; - } - - void remove(const void* ptr) - { - boost::lock_guard<boost::mutex> dummy(lockActStrings); - if (activeStrings.find(ptr) == activeStrings.end()) - reportProblem("Fatal Error: No memory available for deallocation at this location!"); - - activeStrings.erase(ptr); - } - - static LeakChecker& instance(); - -private: - LeakChecker() {} - LeakChecker(const LeakChecker&); - LeakChecker& operator=(const LeakChecker&); - ~LeakChecker(); - - static std::string rawMemToString(const void* ptr, size_t size); - void reportProblem(const std::string& message); //throw std::logic_error - - boost::mutex lockActStrings; - zen::hash_map<const void*, size_t> activeStrings; -}; +void leakCheckerInsert(const void* ptr, size_t size); +void leakCheckerRemove(const void* ptr); +} #endif //NDEBUG - class AllocatorFreeStoreChecked { public: static void* allocate(size_t size) //throw std::bad_alloc { -#ifndef NDEBUG void* newMem = ::operator new(size); - LeakChecker::instance().insert(newMem, size); //test Zbase for memory leaks - return newMem; -#else - return ::operator new(size); +#ifndef NDEBUG + z_impl::leakCheckerInsert(newMem, size); //test Zbase for memory leaks #endif + return newMem; } static void deallocate(void* ptr) { #ifndef NDEBUG - LeakChecker::instance().remove(ptr); //check for memory leaks + z_impl::leakCheckerRemove(ptr); //check for memory leaks #endif ::operator delete(ptr); } @@ -82,66 +48,50 @@ public: //############################## helper functions ############################################# -#if defined(FFS_WIN) || defined(FFS_LINUX) -//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES -template <class T, template <class, class> class SP, class AP> int cmpFileName(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs); - -struct LessFilename //case-insensitive on Windows, case-sensitive on Linux -{ - template <class T, template <class, class> class SP, class AP> - bool operator()(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs) const; -}; - -struct EqualFilename //case-insensitive on Windows, case-sensitive on Linux -{ - template <class T, template <class, class> class SP, class AP> - bool operator()(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs) const; -}; -#endif - -#ifdef FFS_WIN -template <template <class, class> class SP, class AP> -void makeUpper(zen::Zbase<wchar_t, SP, AP>& str); -#endif #ifdef FFS_WIN //Windows encodes Unicode as UTF-16 wchar_t typedef wchar_t Zchar; #define Zstr(x) L ## x const Zchar FILE_NAME_SEPARATOR = L'\\'; -#elif defined FFS_LINUX //Linux uses UTF-8 +#elif defined FFS_LINUX || defined FFS_MAC //Linux uses UTF-8 typedef char Zchar; #define Zstr(x) x const Zchar FILE_NAME_SEPARATOR = '/'; - -#else -#error define your platform: FFS_WIN or FFS_LINUX #endif //"The reason for all the fuss above" - Loki/SmartPtr -//a high-performance string for use as file name in multithreaded contexts +//a high-performance string for interfacing with native OS APIs and multithreaded contexts typedef zen::Zbase<Zchar, zen::StorageRefCountThreadSafe, AllocatorFreeStoreChecked> Zstring; -inline -Zstring appendSeparator(Zstring path) //support rvalue references! -{ - return endsWith(path, FILE_NAME_SEPARATOR) ? path : (path += FILE_NAME_SEPARATOR); -} - - - - - - - - - +//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES +template <template <class, class> class SP, class AP> +int cmpFileName(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP, AP>& rhs); +struct LessFilename //case-insensitive on Windows, case-sensitive on Linux +{ + template <template <class, class> class SP, class AP> + bool operator()(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP, AP>& rhs) const { return cmpFileName(lhs, rhs) < 0; } +}; +struct EqualFilename //case-insensitive on Windows, case-sensitive on Linux +{ + template <template <class, class> class SP, class AP> + bool operator()(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP, AP>& rhs) const { return cmpFileName(lhs, rhs) == 0; } +}; +#if defined FFS_WIN || defined FFS_MAC +template <template <class, class> class SP, class AP> +void makeUpper(zen::Zbase<Zchar, SP, AP>& str); +#endif +inline +Zstring appendSeparator(Zstring path) //support rvalue references! +{ + return endsWith(path, FILE_NAME_SEPARATOR) ? path : (path += FILE_NAME_SEPARATOR); +} @@ -149,53 +99,35 @@ Zstring appendSeparator(Zstring path) //support rvalue references! //################################# inline implementation ######################################## -#if defined(FFS_WIN) || defined(FFS_LINUX) namespace z_impl { -int compareFilenamesWin(const wchar_t* lhs, const wchar_t* rhs, size_t sizeLhs, size_t sizeRhs); -void makeUpperCaseWin(wchar_t* str, size_t size); -} - - -template <class T, template <class, class> class SP, class AP> inline -int cmpFileName(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs) -{ -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()); -#elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()); //POSIX filenames don't have embedded 0 +#if defined FFS_WIN +int compareFilenamesNoCase(const Zchar* lhs, const Zchar* rhs, size_t sizeLhs, size_t sizeRhs); #endif -} - - -template <class T, template <class, class> class SP, class AP> inline -bool LessFilename::operator()(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs) const -{ -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()) < 0; -#elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()) < 0; //POSIX filenames don't have embedded 0 +#if defined FFS_WIN || defined FFS_MAC +void makeFilenameUpperCase(Zchar* str, size_t size); #endif } -template <class T, template <class, class> class SP, class AP> inline -bool EqualFilename::operator()(const zen::Zbase<T, SP, AP>& lhs, const zen::Zbase<T, SP, AP>& rhs) const +template <template <class, class> class SP, class AP> inline +int cmpFileName(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP, AP>& rhs) { -#ifdef FFS_WIN - return z_impl::compareFilenamesWin(lhs.data(), rhs.data(), lhs.length(), rhs.length()) == 0; +#if defined FFS_WIN + return z_impl::compareFilenamesNoCase(lhs.data(), rhs.data(), lhs.length(), rhs.length()); #elif defined FFS_LINUX - return ::strcmp(lhs.c_str(), rhs.c_str()) == 0; //POSIX filenames don't have embedded 0 + return std::strcmp(lhs.c_str(), rhs.c_str()); //POSIX filenames don't have embedded 0 +#elif defined FFS_MAC + return ::strcasecmp(lhs.c_str(), rhs.c_str()); //locale-dependent! #endif } -#endif //defined(FFS_WIN) || defined(FFS_LINUX) -#ifdef FFS_WIN +#if defined FFS_WIN || defined FFS_MAC template <template <class, class> class SP, class AP> inline -void makeUpper(zen::Zbase<wchar_t, SP, AP>& str) +void makeUpper(zen::Zbase<Zchar, SP, AP>& str) { - z_impl::makeUpperCaseWin(str.begin(), str.length()); + z_impl::makeFilenameUpperCase(str.begin(), str.length()); } #endif |