summaryrefslogtreecommitdiff
path: root/shared/zstring.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:08:42 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:08:42 +0200
commitc32707148292d104c66276b43796d6057c8c7a5d (patch)
treebb83513f4aff24153e21a4ec92e34e4c27651b1f /shared/zstring.h
parent3.9 (diff)
downloadFreeFileSync-c32707148292d104c66276b43796d6057c8c7a5d.tar.gz
FreeFileSync-c32707148292d104c66276b43796d6057c8c7a5d.tar.bz2
FreeFileSync-c32707148292d104c66276b43796d6057c8c7a5d.zip
3.10
Diffstat (limited to 'shared/zstring.h')
-rw-r--r--shared/zstring.h795
1 files changed, 102 insertions, 693 deletions
diff --git a/shared/zstring.h b/shared/zstring.h
index 7b993fd0..a015dbe4 100644
--- a/shared/zstring.h
+++ b/shared/zstring.h
@@ -7,797 +7,206 @@
#ifndef ZSTRING_H_INCLUDED
#define ZSTRING_H_INCLUDED
-#include <cstring> //size_t, memcpy(), memcmp()
-#include <cstdlib> //malloc(), free()
-#include <cassert>
-#include <vector>
-#include <sstream>
-#include <algorithm> //specialize std::swap
-#include <functional>
+#include "zbase.h"
+#include <cstring> //strcmp()
#ifndef NDEBUG
-#include <set>
+#include <map>
#include <wx/thread.h>
#endif
-#ifdef ZSTRING_CHAR
-typedef char DefaultChar; //use char strings
-#define DefaultStr(x) x //
-#elif defined ZSTRING_WIDE_CHAR
-typedef wchar_t DefaultChar; //use wide character strings
-#define DefaultStr(x) L ## x //
-#endif
-
-
-class Zstring
-{
-public:
- Zstring();
- Zstring(const DefaultChar* source); //string is copied: O(length)
- Zstring(const DefaultChar* source, size_t length); //string is copied: O(length)
- Zstring(const Zstring& source); //reference-counting => O(1)
- ~Zstring();
-
- operator const DefaultChar*() const; //implicit conversion to C string
-
- //wxWidgets-like functions
- bool StartsWith(const DefaultChar* begin) const;
- bool StartsWith(DefaultChar begin) const;
- bool StartsWith(const Zstring& begin) const;
- bool EndsWith(const DefaultChar* end) const;
- bool EndsWith(const DefaultChar end) const;
- bool EndsWith(const Zstring& end) const;
- Zstring& Truncate(size_t newLen);
- Zstring& Replace(const DefaultChar* old, const DefaultChar* replacement, bool replaceAll = true);
- Zstring AfterLast( DefaultChar ch) const; //returns the whole string if ch not found
- Zstring BeforeLast( DefaultChar ch) const; //returns empty string if ch not found
- Zstring AfterFirst( DefaultChar ch) const; //returns empty string if ch not found
- Zstring BeforeFirst(DefaultChar ch) const; //returns the whole string if ch not found
- size_t Find(DefaultChar ch, bool fromEnd = false) const; //returns npos if not found
- bool Matches(const DefaultChar* mask) const;
- static bool Matches(const DefaultChar* name, const DefaultChar* mask);
- Zstring& Trim(bool fromRight); //from right or left
- std::vector<Zstring> Tokenize(const DefaultChar delimiter) const;
-#ifdef FFS_WIN
- Zstring& MakeUpper();
-#endif
-
- //std::string functions
- size_t length() const;
- const DefaultChar* c_str() const;
- Zstring substr(size_t pos = 0, size_t len = npos) const; //allocate new string
- bool empty() const;
- void clear();
- int compare(size_t pos1, size_t n1, const DefaultChar* other) const;
- size_t find(const DefaultChar* str, size_t pos = 0 ) const;
- size_t find(DefaultChar ch, size_t pos = 0) const;
- size_t rfind(DefaultChar ch, size_t pos = npos) const;
- Zstring& replace(size_t pos1, size_t n1, const DefaultChar* str, size_t n2);
- size_t size() const;
- void reserve(size_t minCapacity);
- Zstring& assign(const DefaultChar* source, size_t len);
- void resize(size_t newSize, DefaultChar fillChar = 0 );
-
- Zstring& operator=(const Zstring& source);
- Zstring& operator=(const DefaultChar* source);
-
-
- friend bool operator==(const Zstring& lhs, const Zstring& rhs);
- friend bool operator==(const Zstring& lhs, const DefaultChar* rhs);
- friend bool operator==(const DefaultChar* lhs, const Zstring& rhs);
-
- friend bool operator< (const Zstring& lhs, const Zstring& rhs);
- friend bool operator< (const Zstring& lhs, const DefaultChar* rhs);
- friend bool operator< (const DefaultChar* lhs, const Zstring& rhs);
-
- friend bool operator!=(const Zstring& lhs, const Zstring& rhs);
- friend bool operator!=(const Zstring& lhs, const DefaultChar* rhs);
- friend bool operator!=(const DefaultChar* lhs, const Zstring& rhs);
-
- void swap(Zstring& other);
-
- const DefaultChar operator[](size_t pos) const;
-
- Zstring& operator+=(const Zstring& other);
- Zstring& operator+=(const DefaultChar* other);
- Zstring& operator+=(DefaultChar ch);
-
- static const size_t npos = static_cast<size_t>(-1);
-
-private:
- Zstring(int); //detect usage errors
-
- DefaultChar* data();
-
- void initAndCopy(const DefaultChar* source, size_t length);
- void incRef() const; //support for reference-counting
- void decRef(); //
-
- //helper methods
- static size_t defaultLength (const DefaultChar* input); //strlen()
- static int defaultCompare(const DefaultChar* str1, const DefaultChar* str2); //strcmp()
- static int defaultCompare(const DefaultChar* str1, const DefaultChar* str2, size_t count); //strncmp()
- static const DefaultChar* defaultStrFind(const DefaultChar* str1, DefaultChar ch); //strchr()
- static const DefaultChar* defaultStrFind(const DefaultChar* str1, const DefaultChar* str1End, const DefaultChar* str2); //"analog" to strstr()
- static bool matchesHelper(const DefaultChar* string, const DefaultChar* mask);
-
- struct StringDescriptor
- {
- mutable unsigned int refCount;
- size_t length;
- size_t capacity; //allocated length without null-termination
- };
- static StringDescriptor* allocate(const size_t newLength);
-
- StringDescriptor* descr;
-};
-
-
-const Zstring operator+(const Zstring& lhs, const Zstring& rhs);
-const Zstring operator+(const Zstring& lhs, const DefaultChar* rhs);
-const Zstring operator+(const DefaultChar* lhs, const Zstring& rhs);
-const Zstring operator+(DefaultChar lhs, const Zstring& rhs);
-const Zstring operator+(const Zstring& lhs, DefaultChar rhs);
-
-template <class T>
-Zstring numberToZstring(const T& number); //convert number to Zstring
-
-//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES
-int cmpFileName(const Zstring& lhs, const Zstring& rhs);
-int cmpFileName(const Zstring& lhs, const DefaultChar* rhs);
-int cmpFileName(const DefaultChar* lhs, const Zstring& rhs);
-int cmpFileName(const DefaultChar* lhs, const DefaultChar* rhs);
-
-struct LessFilename : public std::binary_function<Zstring, Zstring, bool>//case-insensitive on Windows, case-sensitive on Linux
-{
- bool operator()(const Zstring& a, const Zstring& b) const;
-};
-
-namespace std
-{
-template<>
-inline
-void swap(Zstring& rhs, Zstring& lhs)
-{
- rhs.swap(lhs);
-}
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//#######################################################################################
-//begin of implementation
-
-//-------------standard helper functions ---------------------------------------------------------------
-inline
-size_t Zstring::defaultLength(const DefaultChar* input) //strlen()
-{
- const DefaultChar* const startPos = input;
- while (*input != 0)
- ++input;
-
- return input - startPos;
-}
-
-
-inline
-int Zstring::defaultCompare(const DefaultChar* str1, const DefaultChar* str2) //strcmp()
-{
- while (*str1 == *str2)
- {
- if (*str1 == 0)
- return 0;
- ++str1;
- ++str2;
- }
-
- return *str1 - *str2;
-}
-
-
-inline
-int Zstring::defaultCompare(const DefaultChar* str1, const DefaultChar* str2, size_t count) //strncmp()
-{
- while (count-- != 0)
- {
- if (*str1 != *str2)
- return *str1 - *str2;
-
- if (*str1 == 0)
- return 0;
- ++str1;
- ++str2;
- }
-
- return 0;
-}
-
-
-inline
-const DefaultChar* Zstring::defaultStrFind(const DefaultChar* str1, DefaultChar ch) //strchr()
-{
- while (*str1 != ch) //ch is allowed to be 0 by contract! must return end of string in this case
- {
- if (*str1 == 0)
- return NULL;
-
- ++str1;
- }
-
- return str1;
-}
-
-
-inline
-const DefaultChar* Zstring::defaultStrFind(const DefaultChar* str1, const DefaultChar* str1End, const DefaultChar* str2) //"analog" to strstr()
-{
- const size_t str2Len = defaultLength(str2);
-
- str1End -= str2Len; //no need to process the "last chunk" of str1
- ++str1End; //
-
- while(str1 < str1End) //don't use !=; str1End may be smaller than str1!
- {
- if(::memcmp(str1, str2, str2Len * sizeof(DefaultChar)) == 0)
- return str1;
- ++str1;
- }
- return NULL;
-}
-//--------------------------------------------------------------------------------------------------
-
#ifndef NDEBUG
-class AllocationCount //small test for memory leaks in Zstring
+class LeakChecker //small test for memory leaks
{
public:
- void inc(const DefaultChar* object)
+ void insert(const void* ptr, size_t size)
{
wxCriticalSectionLocker dummy(lockActStrings);
- activeStrings.insert(object);
+ if (activeStrings.find(ptr) != activeStrings.end())
+ reportProblem(std::string("Fatal Error: New memory points into occupied space: ") + rawMemToString(ptr, size));
+
+ activeStrings[ptr] = size;
}
- void dec(const DefaultChar* object)
+ void remove(const void* ptr)
{
wxCriticalSectionLocker dummy(lockActStrings);
- activeStrings.erase(object);
+
+ if (activeStrings.find(ptr) == activeStrings.end())
+ reportProblem(std::string("Fatal Error: No memory available for deallocation at this location!"));
+
+ activeStrings.erase(ptr);
}
- static AllocationCount& getInstance();
+ static LeakChecker& instance();
private:
- AllocationCount() {}
- AllocationCount(const AllocationCount&);
- ~AllocationCount();
+ 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)
wxCriticalSection lockActStrings;
- std::set<const DefaultChar*> activeStrings;
+ typedef std::map<const void*, size_t> VoidPtrSizeMap;
+ VoidPtrSizeMap activeStrings;
};
#endif //NDEBUG
-inline
-size_t getCapacityToAllocate(const size_t length)
-{
- return (length + (19 - length % 16)); //allocate some additional length to speed up concatenation
-}
-
-
-inline
-Zstring::StringDescriptor* Zstring::allocate(const size_t newLength)
+class AllocatorFreeStoreChecked
{
- //allocate and set data for new string
- const size_t newCapacity = getCapacityToAllocate(newLength);
- assert(newCapacity);
-
- StringDescriptor* const newDescr = static_cast<StringDescriptor*>(::malloc(sizeof(StringDescriptor) + (newCapacity + 1) * sizeof(DefaultChar))); //use C-memory functions because of realloc()
- if (newDescr == NULL)
- throw std::bad_alloc();
-
- newDescr->refCount = 1;
- newDescr->length = newLength;
- newDescr->capacity = newCapacity;
-
-#ifndef NDEBUG
- AllocationCount::getInstance().inc(reinterpret_cast<DefaultChar*>(newDescr + 1)); //test Zstring for memory leaks
-#endif
- return newDescr;
-}
-
-
-inline
-Zstring::Zstring()
-{
- //static (dummy) empty Zstring
-#ifdef ZSTRING_CHAR
- static Zstring emptyString("");
-#elif defined ZSTRING_WIDE_CHAR
- static Zstring emptyString(L"");
-#endif
-
- emptyString.incRef();
- descr = emptyString.descr;
-}
-
-
-inline
-
-Zstring::Zstring(const DefaultChar* source)
-{
- initAndCopy(source, defaultLength(source));
-}
-
-
-inline
-Zstring::Zstring(const DefaultChar* source, size_t sourceLen)
-{
- initAndCopy(source, sourceLen);
-}
-
-
-inline
-Zstring::Zstring(const Zstring& source)
-{
- descr = source.descr;
- incRef(); //reference counting!
-}
-
-
-inline
-Zstring::~Zstring()
-{
- decRef();
-}
-
-
-inline
-void Zstring::initAndCopy(const DefaultChar* source, size_t sourceLen)
-{
- assert(source);
- descr = allocate(sourceLen);
- ::memcpy(data(), source, sourceLen * sizeof(DefaultChar));
- data()[sourceLen] = 0;
-}
-
-
-inline
-void Zstring::incRef() const
-{
- assert(descr);
- ++descr->refCount;
-}
-
-
-inline
-void Zstring::decRef()
-{
- assert(descr && descr->refCount >= 1); //descr points to the begin of the allocated memory block
- if (--descr->refCount == 0)
+public:
+ static void* allocate(size_t size) //throw (std::bad_alloc)
{
#ifndef NDEBUG
- AllocationCount::getInstance().dec(c_str()); //test Zstring for memory leaks
+ void* newMem = ::operator new(size);
+ LeakChecker::instance().insert(newMem, size); //test Zbase for memory leaks
+ return newMem;
+#else
+ return ::operator new(size);
#endif
- ::free(descr); //beginning of whole memory block
}
-}
-
-inline
-Zstring::operator const DefaultChar*() const
-{
- return c_str();
-}
-
-
-inline
-Zstring& Zstring::operator=(const Zstring& source)
-{
- Zstring(source).swap(*this);
- return *this;
-}
-
-
-inline
-size_t Zstring::Find(DefaultChar ch, bool fromEnd) const
-{
- return fromEnd ?
- rfind(ch, npos) :
- find(ch, 0);
-}
-
-
-// get all characters after the last occurence of ch
-// (returns the whole string if ch not found)
-inline
-Zstring Zstring::AfterLast(DefaultChar ch) const
-{
- const size_t pos = rfind(ch, npos);
- if (pos != npos )
- return Zstring(c_str() + pos + 1, length() - pos - 1);
- else
- return *this;
-}
-
-
-// get all characters before the last occurence of ch
-// (returns empty string if ch not found)
-inline
-Zstring Zstring::BeforeLast(DefaultChar ch) const
-{
- const size_t pos = rfind(ch, npos);
- if (pos != npos)
- return Zstring(c_str(), pos); //data is non-empty string in this context: else ch would not have been found!
- else
- return Zstring();
-}
-
-
-//returns empty string if ch not found
-inline
-Zstring Zstring::AfterFirst(DefaultChar ch) const
-{
- const size_t pos = find(ch, 0);
- if (pos != npos)
- return Zstring(c_str() + pos + 1, length() - pos - 1);
- else
- return Zstring();
-
-}
-
-//returns the whole string if ch not found
-inline
-Zstring Zstring::BeforeFirst(DefaultChar ch) const
-{
- const size_t pos = find(ch, 0);
- if (pos != npos)
- return Zstring(c_str(), pos); //data is non-empty string in this context: else ch would not have been found!
- else
- return *this;
-}
-
-
-inline
-bool Zstring::StartsWith(const DefaultChar* begin) const
-{
- const size_t beginLength = defaultLength(begin);
- if (length() < beginLength)
- return false;
- return compare(0, beginLength, begin) == 0;
-}
-
-
-inline
-bool Zstring::StartsWith(DefaultChar begin) const
-{
- const size_t len = length();
- return len && (this->operator[](0) == begin);
-}
-
-
-inline
-bool Zstring::StartsWith(const Zstring& begin) const
-{
- const size_t beginLength = begin.length();
- if (length() < beginLength)
- return false;
- return compare(0, beginLength, begin.c_str()) == 0;
-}
-
-
-inline
-bool Zstring::EndsWith(const DefaultChar* end) const
-{
- const size_t thisLength = length();
- const size_t endLength = defaultLength(end);
- if (thisLength < endLength)
- return false;
- return compare(thisLength - endLength, endLength, end) == 0;
-}
-
-
-inline
-bool Zstring::EndsWith(const DefaultChar end) const
-{
- const size_t len = length();
- return len && (this->operator[](len - 1) == end);
-}
-
-
-inline
-bool Zstring::EndsWith(const Zstring& end) const
-{
- const size_t thisLength = length();
- const size_t endLength = end.length();
- if (thisLength < endLength)
- return false;
- return compare(thisLength - endLength, endLength, end.c_str()) == 0;
-}
-
-
-inline
-Zstring& Zstring::Truncate(size_t newLen)
-{
- if (newLen < length())
+ static void deallocate(void* ptr)
{
- if (descr->refCount > 1) //allocate new string
- return *this = Zstring(c_str(), newLen);
- else //overwrite this string
- {
- descr->length = newLen;
- data()[newLen] = 0;
- }
+#ifndef NDEBUG
+ LeakChecker::instance().remove(ptr); //check for memory leaks
+#endif
+ ::operator delete(ptr);
}
+};
- return *this;
-}
-
-
-inline
-size_t Zstring::find(const DefaultChar* str, size_t pos) const
-{
- assert(pos <= length());
- const DefaultChar* const found = defaultStrFind(c_str() + pos, c_str() + length(), str);
- return found == NULL ? npos : found - c_str();
-}
-
-
-inline
-size_t Zstring::find(DefaultChar ch, size_t pos) const
-{
- assert(pos <= length());
- const DefaultChar* thisStr = c_str();
- const DefaultChar* found = defaultStrFind(thisStr + pos, ch);
- return found == NULL ? npos : found - thisStr;
-}
-
-
-inline
-bool operator==(const Zstring& lhs, const Zstring& rhs)
-{
- return lhs.length() != rhs.length() ? false : Zstring::defaultCompare(lhs.c_str(), rhs.c_str()) == 0; //memcmp() offers no better performance here...
-}
-
-
-inline
-bool operator==(const Zstring& lhs, const DefaultChar* rhs)
-{
- return Zstring::defaultCompare(lhs.c_str(), rhs) == 0; //overload using strcmp(char*, char*) should be fastest!
-}
+//############################## 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 Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-inline
-bool operator==(const DefaultChar* lhs, const Zstring& rhs)
+struct LessFilename //case-insensitive on Windows, case-sensitive on Linux
{
- return operator==(rhs, lhs);
-}
-
+ template <class T, template <class, class> class SP, class AP>
+ bool operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const;
+};
-inline
-bool operator<(const Zstring& lhs, const Zstring& rhs)
+struct EqualFilename //case-insensitive on Windows, case-sensitive on Linux
{
- return Zstring::defaultCompare(lhs.c_str(), rhs.c_str()) < 0;
-}
+ template <class T, template <class, class> class SP, class AP>
+ bool operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const;
+};
+#endif
+#ifdef FFS_WIN
+template <template <class, class> class SP, class AP>
+void MakeUpper(Zbase<wchar_t, SP, AP>& str);
+#endif
-inline
-bool operator<(const Zstring& lhs, const DefaultChar* rhs)
-{
- return Zstring::defaultCompare(lhs.c_str(), rhs) < 0;
-}
+#ifdef FFS_WIN //Windows stores filenames in wide character format
+typedef wchar_t Zchar;
+#define Zstr(x) L ## x
-inline
-bool operator<(const DefaultChar* lhs, const Zstring& rhs)
-{
- return Zstring::defaultCompare(lhs, rhs.c_str()) < 0;
-}
+#elif defined FFS_LINUX //Linux uses UTF-8
+typedef char Zchar;
+#define Zstr(x) x
+#endif
+//"The reason for all the fuss above" (Loki/SmartPtr)
+typedef Zbase<Zchar, StorageRefCount, AllocatorFreeStoreChecked> Zstring;
-inline
-bool operator!=(const Zstring& lhs, const Zstring& rhs)
-{
- return !operator==(lhs, rhs);
-}
-inline
-bool operator!=(const Zstring& lhs, const DefaultChar* rhs)
-{
- return !operator==(lhs, rhs);
-}
-inline
-bool operator!=(const DefaultChar* lhs, const Zstring& rhs)
-{
- return !operator==(lhs, rhs);
-}
-inline
-int Zstring::compare(size_t pos1, size_t n1, const DefaultChar* other) const
-{
- assert(n1 <= length() - pos1);
- return defaultCompare(c_str() + pos1, other, n1);
-}
-inline
-size_t Zstring::length() const
-{
- return descr->length;
-}
-inline
-size_t Zstring::size() const
-{
- return descr->length;
-}
-inline
-const DefaultChar* Zstring::c_str() const
-{
- return reinterpret_cast<DefaultChar*>(descr + 1);
-}
-inline
-DefaultChar* Zstring::data()
-{
- return reinterpret_cast<DefaultChar*>(descr + 1);
-}
-inline
-bool Zstring::empty() const
-{
- return descr->length == 0;
-}
-inline
-void Zstring::clear()
-{
- *this = Zstring();
-}
-inline
-const DefaultChar Zstring::operator[](const size_t pos) const
-{
- assert(pos < length());
- return c_str()[pos];
-}
-inline
-const Zstring operator+(const Zstring& lhs, const Zstring& rhs)
-{
- return Zstring(lhs) += rhs;
-}
-inline
-const Zstring operator+(const Zstring& lhs, const DefaultChar* rhs)
-{
- return Zstring(lhs) += rhs;
-}
-inline
-const Zstring operator+(const DefaultChar* lhs, const Zstring& rhs)
+//################################# inline implementation ########################################
+#if defined(FFS_WIN) || defined(FFS_LINUX)
+namespace z_impl
{
- return Zstring(lhs) += rhs;
+int compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB);
+void makeUpperCaseWin(wchar_t* str, size_t size);
}
+template <class T, template <class, class> class SP, class AP>
inline
-const Zstring operator+(DefaultChar lhs, const Zstring& rhs)
+int cmpFileName(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs)
{
- return (Zstring() += lhs) += 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
+#endif
}
+template <class T, template <class, class> class SP, class AP>
inline
-const Zstring operator+(const Zstring& lhs, DefaultChar rhs)
+bool LessFilename::operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const
{
- return Zstring(lhs) += rhs;
+#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
+#endif
}
+template <class T, template <class, class> class SP, class AP>
inline
-void Zstring::resize(size_t newSize, DefaultChar fillChar)
+bool EqualFilename::operator()(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs) const
{
- const size_t oldSize = length();
- if (oldSize < newSize)
- {
- reserve(newSize); //make unshared and ensure capacity
-
- //fill up...
- DefaultChar* strPtr = data() + oldSize;
- const DefaultChar* const strEnd = data() + newSize;
- while (strPtr != strEnd)
- {
- *strPtr = fillChar;
- ++strPtr;
- }
-
- data()[newSize] = 0;
- descr->length = newSize;
- }
- else if (oldSize > newSize)
- {
- if (descr->refCount > 1)
- *this = Zstring(c_str(), newSize); //no need to reserve() and copy the old string completely!
- else //overwrite this string
- {
- data()[newSize] = 0;
- descr->length = newSize;
- }
- }
+#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
+#endif
}
+#endif //defined(FFS_WIN) || defined(FFS_LINUX)
+#ifdef FFS_WIN
+template <template <class, class> class SP, class AP>
inline
-void Zstring::swap(Zstring& other)
+void MakeUpper(Zbase<wchar_t, SP, AP>& str)
{
- std::swap(descr, other.descr);
+ z_impl::makeUpperCaseWin(str.begin(), str.length());
}
+#endif
-template <class T>
-inline
-Zstring numberToZstring(const T& number) //convert number to string the C++ way
+namespace std
{
- std::basic_ostringstream<DefaultChar> ss;
- ss << number;
- return Zstring(ss.str().c_str());
-}
-
-
+template<>
inline
-int cmpFileName(const DefaultChar* lhs, const Zstring& rhs)
+void swap(Zstring& rhs, Zstring& lhs)
{
- return cmpFileName(rhs, lhs);
+ rhs.swap(lhs);
}
-
-
-inline
-bool LessFilename::operator()(const Zstring& a, const Zstring& b) const
-{
-// //quick check based on string length
-// const size_t aLength = a.data.shortName.length();
-// const size_t bLength = b.data.shortName.length();
-// if (aLength != bLength)
-// return aLength < bLength;
- return cmpFileName(a, b) < 0;
}
-#endif // ZSTRING_H_INCLUDED
+#endif //ZSTRING_H_INCLUDED
bgstack15