summaryrefslogtreecommitdiff
path: root/zen/zstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/zstring.h')
-rw-r--r--zen/zstring.h168
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
bgstack15