#if !defined(__CStr__) #define __CStr__ // include: cstr.h, stdarg.h #if !defined(CHAR) #define CHAR char #endif // !defined(CHAR) #if !defined(USE_STRLOCK) #define USE_STRLOCK #endif // !defined(USE_STRLOCK) #if !defined(__QSortCompareProc_DEFINED__) typedef int (__cdecl* QSortCompareProc)(const void* elem1, const void* elem2); #define __QSortCompareProc_DEFINED__ #endif // !defined(__QSortCompareProc_DEFINED__) int __cdecl str_memcmp(const void* elem1, const void* elem2); #if !defined(WIN32) #define lstrcmp strcmp #define lstrcmpi strcasecmp char* _strupr(char *string); char* _strlwr(char *string); #endif // !defined(WIN32) int __cdecl str_Compare(const void* elem1, const void* elem2); int __cdecl str_CompareReverse(const void* elem1, const void* elem2); int __cdecl str_CompareIC(const void* elem1, const void* elem2); int __cdecl str_CompareICReverse(const void* elem1, const void* elem2); DECLARE_TARRAYREF(CStr); class CStr { private: CHAR* m_psz; // all data in this section must be INITIALIZED!!!!!!!!!!!!! public: CStr(); CStr(const CHAR* pcsz); CStr(const CHAR* pcsz, int nLen); CStr(CHAR c, int nLen); CStr(const CStr& that); private: CStr(int nMax); public: ~CStr(); public: operator const CHAR* () const { return m_psz; } CHAR* GetRawBuffer() const { return m_psz; } // be very cautious!!!! int GetLength() const { return strlen(m_psz); } BOOL IsEmpty() const { return m_psz[0] == '\0'; } const CHAR* String() const { return m_psz; } const CHAR* Empty(); void Swap(CStr& that); #ifdef USE_STRLOCK WORD IsLocked() const; CHAR* LockBuffer(); WORD UnlockBuffer(); #endif // USE_STRLOCK #ifndef _DEBUG #define CheckRange(nIndex) #else // _DEBUG void CheckRange(int nIndex) const { ASSERT((0 <= nIndex) && (nIndex <= lstrlen(m_psz))); } #endif // !_DEBUG CHAR operator () (int nIndex) const { CheckRange(nIndex); return m_psz[nIndex]; } const CHAR& operator [] (int nIndex) const { CheckRange(nIndex); return m_psz[nIndex]; } CHAR& operator [] (int nIndex) { CheckRange(nIndex); return m_psz[nIndex]; } CHAR GetAt(int nIndex) const { CheckRange(nIndex); return m_psz[nIndex]; } void SetAt(int nIndex, CHAR c) { CheckRange(nIndex); m_psz[nIndex] = c; } #ifndef _DEBUG #undef CheckRange #endif // !_DEBUG const CHAR* Assign(const CHAR* pcsz, int nLen = -1); CStr& operator = (const CHAR* pcsz) { Assign(pcsz); return *this; } CStr& operator = (const CStr& that) { Assign(that.m_psz); return *this; } BOOL operator == (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) == 0: m_psz[0] == '\0'; } BOOL operator != (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) != 0: m_psz[0] != '\0'; } BOOL operator > (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) > 0: m_psz[0] != '\0'; } BOOL operator >= (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) >= 0: TRUE; } BOOL operator < (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) < 0: FALSE; } BOOL operator <= (const CHAR* pcsz) const { return pcsz ? strcmp(m_psz, pcsz) <= 0: m_psz[0] == '\0'; } CStr operator + (const CHAR* pcsz) const; CStr& operator += (const CHAR* pcsz); CStr operator + (CHAR c) const; CStr& operator += (CHAR c); void MakeUpper() { _strupr(m_psz); } void MakeLower() { _strlwr(m_psz); } void MakeReverse(); const CHAR* Prune(const CHAR* pcszDELs = NULL); const CHAR* TrimLeft(); const CHAR* TrimRight(); const CHAR* TrimAll(); void __cdecl Format(LPCTSTR lpszFormat, ...); void vFormat(LPCTSTR lpszFormat, va_list marker); CHAR* GetBuffer(int nLen); const CHAR* ReleaseBuffer(int nLen = -1); CHAR* GetBufferSetLength(int nLen); void ChangeChars(CHAR cBefore, CHAR cAfter); BOOL AsDirectory(BOOL bRemoveLastDEL = FALSE); BOOL AddDirDEL(); int FindExtPos() const; const char* FindExt() const; BOOL ChangeExt(const char* pcszExt, BOOL bForce = TRUE); const CHAR* Left(CStr& strLeft, int nCount) const; const CHAR* Right(CStr& strRight, int nCount) const; const CHAR* Mid(CStr& strMid, int nFirst) const; const CHAR* Mid(CStr& strMid, int nFirst, int nCount) const; CStr Left(int nCount) const; CStr Right(int nCount) const; CStr Mid(int nFirst) const; CStr Mid(int nFirst, int nCount) const; int FindNext(CHAR c, int nStart) const; int Find(CHAR c) const; int rFindNext(CHAR c, int nStart) const; int rFind(CHAR c) const; int Find(const CHAR* pcsz, int nStart) const; int Find(const CHAR* pcsz) const; int FindSet(const CHAR* pcszSet) const; int rFindSet(const CHAR* pcszSet) const; #if defined(WIN32) BOOL GetWindowText(HWND hWnd); #endif // defined(WIN32) protected: const CHAR* AssignNoCheck(const CHAR* pcsz, int nLen = -1); private: CHAR* Reset(); #ifdef USE_STRLOCK CHAR* ResetLocked(); #endif // USE_STRLOCK }; #if !defined(USE_CSTR_ISTREAM) && defined(_INC_ISTREAM) #define USE_CSTR_ISTREAM #endif // !defined(USE_CSTR_ISTREAM) && defined(_INC_ISTREAM) #if defined(NO_USE_CSTR_ISTREAM) #undef USE_CSTR_ISTREAM #endif // defined(NO_USE_CSTR_ISTREAM) #ifdef USE_CSTR_ISTREAM istream& operator >> (istream& s, CStr& str); #endif // USE_CSTR_ISTREAM #define LSTRS_TOLOWER 0x0001 #define LSTRS_TOUPPER 0x0002 #define LSTRS_ALLOWDUP 0x0004 #define LSTRS_DOSORT 0x0008 class CStrArray : public TARRAYREF(CStr) { public: int GetTotalLength() const; int Find(const char* pcsz) const; int AddIfNotFound(const char* pcsz); int AddIfNotFound(const CStr astrs[], int nCount); void Sort(QSortCompareProc pQSortCompareProc = (QSortCompareProc)NULL); BOOL LoadStrs(const char* pcszFile, const char* pcszVals = NULL, UINT uFlags = 0); BOOL LoadStrs(FILE* pFile, const char* pcszVals = NULL, UINT uFlags = 0); void LSTRS_CheckAdd(CStr& str, UINT uFlags); }; #ifdef _DEBUG #define ASSERT_VALIDSTRING(pcszStr) ASSERT(IsValidString(pcszStr)) #define ASSERT_VALIDSTRINGSAFE(pcszStr) ASSERT(IsValidStringSafe(pcszStr)) #define ASSERT_CLSPTR(p) ASSERT(IsValidMemory(p, sizeof(*p), TRUE)) BOOL IsValidString(const CHAR* pcszStr, int nLen = -1); BOOL IsValidStringSafe(const CHAR* pcszStr, int nLen = -1); BOOL IsValidMemory(const void* pMem, UINT uBytes, BOOL bWriteCheck = TRUE); BOOL IsValidMemorySafe(const void* pMem, UINT uBytes, BOOL bWriteCheck = TRUE); #else // !_DEBUG #define ASSERT_VALIDSTRING(pcszStr) #define ASSERT_VALIDSTRINGSAFE(pcszStr) #define ASSERT_CLSPTR(p) inline BOOL __RelIsValidAddr(const void* p, int nLen = -1) { &p, &nLen; return TRUE; } #define IsValidString 1 ? 1: __RelIsValidAddr #define IsValidStringSafe 1 ? 1: __RelIsValidAddr #define IsValidMemory 1 ? 1: __RelIsValidAddr #define IsValidMemorySafe 1 ? 1: __RelIsValidAddr #endif // _DEBUG #ifdef _DEBUG void CStrTestMain(); #endif // _DEBUG #endif // !defined(__CStr__)