📄 atsstring.h
字号:
// Windows Template Library - WTL version 7.0
// Copyright (C) 1997-2002 Microsoft Corporation
// All rights reserved.
//
// This file is a part of the Windows Template Library.
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
#ifndef __ACTIVESTRING_H__
#define __ACTIVESTRING_H__
#ifndef A_ATL_NO_OLD_HEADERS_WIN64
#if !defined(_WIN64) && (_ATL_VER < 0x0700)
typedef long ALONG_PTR;
typedef unsigned long AULONG_PTR;
typedef AULONG_PTR ADWORD_PTR;
#endif //!defined(_WIN64) && (_ATL_VER < 0x0700)
#endif //!_ATL_NO_OLD_HEADERS_WIN64
#ifndef _WTL_NO_CAtsString
#ifndef _DEBUG
#include <stdio.h>
#endif //!_DEBUG
#include <tchar.h>
#include <atlbase.h>
#include <LIMITS.H>
/////////////////////////////////////////////////////////////////////////////
// Classes in this file
//
// CAtsString
//
struct CAtsStringData
{
long nRefs; // reference count
int nDataLength;
int nAllocLength;
// TCHAR data[nAllocLength]
TCHAR* data()
{ return (TCHAR*)(this + 1); }
};
// Globals
// For an empty string, m_pchData will point here
// (note: avoids special case of checking for NULL m_pchData)
// empty string data (and locked)
_declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 };
_declspec(selectany) CAtsStringData* _atltmpDataNil = (CAtsStringData*)&rgInitData;
_declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CAtsStringData));
class CAtsString
{
public:
// Constructors
CAtsString();
CAtsString(const CAtsString& stringSrc);
CAtsString(TCHAR ch, int nRepeat = 1);
CAtsString(LPCSTR lpsz);
CAtsString(LPCWSTR lpsz);
CAtsString(LPCSTR lpch, int nLength);
CAtsString(LPCWSTR lpch, int nLength);
CAtsString(const unsigned char* psz);
// Attributes & Operations
// as an array of characters
int GetLength() const;
BOOL IsEmpty() const;
void Empty(); // free up the data
TCHAR GetAt(int nIndex) const; // 0 based
TCHAR operator[](int nIndex) const; // same as GetAt
void SetAt(int nIndex, TCHAR ch);
operator LPCTSTR() const; // as a C string
// overloaded assignment
const CAtsString& operator=(const CAtsString& stringSrc);
const CAtsString& operator=(TCHAR ch);
#ifdef _UNICODE
const CAtsString& operator=(char ch);
#endif
const CAtsString& operator=(LPCSTR lpsz);
const CAtsString& operator=(LPCWSTR lpsz);
const CAtsString& operator=(const unsigned char* psz);
// string concatenation
const CAtsString& operator+=(const CAtsString& string);
const CAtsString& operator+=(TCHAR ch);
#ifdef _UNICODE
const CAtsString& operator+=(char ch);
#endif
const CAtsString& operator+=(LPCTSTR lpsz);
friend CAtsString __stdcall operator+(const CAtsString& string1, const CAtsString& string2);
friend CAtsString __stdcall operator+(const CAtsString& string, TCHAR ch);
friend CAtsString __stdcall operator+(TCHAR ch, const CAtsString& string);
#ifdef _UNICODE
friend CAtsString __stdcall operator+(const CAtsString& string, char ch);
friend CAtsString __stdcall operator+(char ch, const CAtsString& string);
#endif
friend CAtsString __stdcall operator+(const CAtsString& string, LPCTSTR lpsz);
friend CAtsString __stdcall operator+(LPCTSTR lpsz, const CAtsString& string);
// string comparison
int Compare(LPCTSTR lpsz) const; // straight character
int CompareNoCase(LPCTSTR lpsz) const; // ignore case
int Collate(LPCTSTR lpsz) const; // NLS aware
int CollateNoCase(LPCTSTR lpsz) const; // ignore case
// simple sub-string extraction
CAtsString Mid(int nFirst, int nCount) const;
CAtsString Mid(int nFirst) const;
CAtsString Left(int nCount) const;
CAtsString Right(int nCount) const;
CAtsString SpanIncluding(LPCTSTR lpszCharSet) const;
CAtsString SpanExcluding(LPCTSTR lpszCharSet) const;
// upper/lower/reverse conversion
void MakeUpper();
void MakeLower();
void MakeReverse();
// trimming whitespace (either side)
void TrimRight();
void TrimLeft();
// remove continuous occurrences of chTarget starting from right
void TrimRight(TCHAR chTarget);
// remove continuous occcurrences of characters in passed string,
// starting from right
void TrimRight(LPCTSTR lpszTargets);
// remove continuous occurrences of chTarget starting from left
void TrimLeft(TCHAR chTarget);
// remove continuous occcurrences of characters in
// passed string, starting from left
void TrimLeft(LPCTSTR lpszTargets);
// advanced manipulation
// replace occurrences of chOld with chNew
int Replace(TCHAR chOld, TCHAR chNew);
// replace occurrences of substring lpszOld with lpszNew;
// empty lpszNew removes instances of lpszOld
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
// remove occurrences of chRemove
int Remove(TCHAR chRemove);
// insert character at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, TCHAR ch);
// insert substring at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, LPCTSTR pstr);
// delete nCount characters starting at zero-based index
int Delete(int nIndex, int nCount = 1);
// searching (return starting index, or -1 if not found)
// look for a single character match
int Find(TCHAR ch) const; // like "C" strchr
int ReverseFind(TCHAR ch) const;
int Find(TCHAR ch, int nStart) const; // starting at index
int FindOneOf(LPCTSTR lpszCharSet) const;
// look for a specific sub-string
int Find(LPCTSTR lpszSub) const; // like "C" strstr
int Find(LPCTSTR lpszSub, int nStart) const; // starting at index
// Concatentation for non strings
const CAtsString& Append(int n)
{
TCHAR szBuffer[10];
wsprintf(szBuffer,_T("%d"),n);
ConcatInPlace(SafeStrlen(szBuffer), szBuffer);
return *this;
}
// simple formatting
BOOL __cdecl Format(LPCTSTR lpszFormat, ...);
BOOL __cdecl Format(UINT nFormatID, ...);
BOOL FormatV(LPCTSTR lpszFormat, va_list argList);
// formatting for localization (uses FormatMessage API)
BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...);
BOOL __cdecl FormatMessage(UINT nFormatID, ...);
// Windows support
BOOL LoadString(UINT nID); // load from string resource
// 255 chars max
#ifndef _UNICODE
// ANSI <-> OEM support (convert string in place)
void AnsiToOem();
void OemToAnsi();
#endif
#ifndef _ATL_NO_COM
// OLE BSTR support (use for OLE automation)
BSTR AllocSysString() const;
BSTR SetSysString(BSTR* pbstr) const;
#endif //!_ATL_NO_COM
// Access to string implementation buffer as "C" character array
LPTSTR GetBuffer(int nMinBufLength);
void ReleaseBuffer(int nNewLength = -1);
LPTSTR GetBufferSetLength(int nNewLength);
void FreeExtra();
// Use LockBuffer/UnlockBuffer to turn refcounting off
LPTSTR LockBuffer();
void UnlockBuffer();
// Implementation
public:
~CAtsString();
int GetAllocLength() const;
static BOOL __stdcall _IsValidString(LPCWSTR lpsz, int nLength = -1)
{
if(lpsz == NULL)
return FALSE;
return !::IsBadStringPtrW(lpsz, nLength);
}
static BOOL __stdcall _IsValidString(LPCSTR lpsz, int nLength = -1)
{
if(lpsz == NULL)
return FALSE;
return !::IsBadStringPtrA(lpsz, nLength);
}
LPTSTR m_pchData; // pointer to ref counted string data
BOOL ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
CAtsStringData* GetData() const;
static int PASCAL SafeStrlen(LPCTSTR lpsz);
protected:
// implementation helpers
void Init();
void AllocCopy(CAtsString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
BOOL AllocBuffer(int nLen);
void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
void CopyBeforeWrite();
BOOL AllocBeforeWrite(int nLen);
void Release();
static void PASCAL Release(CAtsStringData* pData);
static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
{
/*jonfei
#ifdef _DEBUG
// LoadString without annoying warning from the Debug kernel if the
// segment containing the string is not present
if (::FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE((nID>>4) + 1), RT_STRING) == NULL)
{
lpszBuf[0] = '\0';
return 0; // not found
}
#endif //_DEBUG
int nLen = ::LoadString(_Module.GetResourceInstance(), nID, lpszBuf, nMaxBuf);
if (nLen == 0)
lpszBuf[0] = '\0';
return nLen;
*/return 0;
}
static const CAtsString& __stdcall _GetEmptyString()
{
return *(CAtsString*)&_atltmpPchNil;
}
// CAtsString conversion helpers
static int __cdecl _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count)
{
if (count == 0 && mbstr != NULL)
return 0;
int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (int)count, NULL, NULL);
ATLASSERT(mbstr == NULL || result <= (int)count);
if (result > 0)
mbstr[result - 1] = 0;
return result;
}
static int __cdecl _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count)
{
if (count == 0 && wcstr != NULL)
return 0;
int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (int)count);
ATLASSERT(wcstr == NULL || result <= (int)count);
if (result > 0)
wcstr[result - 1] = 0;
return result;
}
// Helpers to avoid CRT startup code
#ifdef _ATL_MIN_CRT
static TCHAR* _cstrchr(const TCHAR* p, TCHAR ch)
{
//strchr for '\0' should succeed
while (*p != 0)
{
if (*p == ch)
break;
p = ::CharNext(p);
}
return (TCHAR*)((*p == ch) ? p : NULL);
}
static TCHAR* _cstrchr_db(const TCHAR* p, TCHAR ch1, TCHAR ch2)
{
const TCHAR* lpsz = NULL;
while (*p != 0)
{
if (*p == ch1 && *(p + 1) == ch2)
{
lpsz = p;
break;
}
p = ::CharNext(p);
}
return (TCHAR*)lpsz;
}
static TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
{
const TCHAR* lpsz = NULL;
while (*p != 0)
{
if (*p == ch)
lpsz = p;
p = ::CharNext(p);
}
return (TCHAR*)lpsz;
}
static TCHAR* _cstrrev(TCHAR* pStr)
{
// Optimize NULL, zero-length, and single-char case.
if ((pStr == NULL) || (pStr[0] == '\0') || (pStr[1] == '\0'))
return pStr;
TCHAR* p = pStr;
while (p[1] != 0)
{
TCHAR* pNext = ::CharNext(p);
if(pNext > p + 1)
{
char p1 = *(char*)p;
*(char*)p = *(char*)(p + 1);
*(char*)(p + 1) = p1;
}
p = pNext;
}
TCHAR* q = pStr;
while (q < p)
{
TCHAR t = *q;
*q = *p;
*p = t;
q++;
p--;
}
return (TCHAR*)pStr;
}
static TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet)
{
int nLen = lstrlen(pCharSet);
if (nLen == 0)
return (TCHAR*)pStr;
const TCHAR* pRet = NULL;
const TCHAR* pCur = pStr;
while((pStr = _cstrchr(pCur, *pCharSet)) != NULL)
{
if(memcmp(pCur, pCharSet, nLen * sizeof(TCHAR)) == 0)
{
pRet = pCur;
break;
}
pCur = ::CharNext(pCur);
}
return (TCHAR*) pRet;
}
static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet)
{
int nRet = 0;
TCHAR* p = (TCHAR*)pStr;
while (*p != 0)
{
TCHAR* pNext = ::CharNext(p);
if(pNext > p + 1)
{
if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL)
break;
nRet += 2;
}
else
{
if(_cstrchr(pCharSet, *p) == NULL)
break;
nRet++;
}
p = pNext;
}
return nRet;
}
static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet)
{
int nRet = 0;
TCHAR* p = (TCHAR*)pStr;
while (*p != 0)
{
TCHAR* pNext = ::CharNext(p);
if(pNext > p + 1)
{
if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL)
break;
nRet += 2;
}
else
{
if(_cstrchr(pCharSet, *p) != NULL)
break;
nRet++;
}
p = pNext;
}
return nRet;
}
static TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet)
{
while (*p != 0)
{
if (_cstrchr(lpszCharSet, *p) != NULL)
{
return (TCHAR*)p;
break;
}
p = ::CharNext(p);
}
return NULL;
}
static int _cstrisdigit(TCHAR ch)
{
WORD type;
GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
return (type & C1_DIGIT) == C1_DIGIT;
}
static int _cstrisspace(TCHAR ch)
{
WORD type;
GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
return (type & C1_SPACE) == C1_SPACE;
}
static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return lstrcmp(pstrOne, pstrOther);
}
static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return lstrcmpi(pstrOne, pstrOther);
}
static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1);
ATLASSERT(nRet != 0);
return nRet - 2; // Convert to strcmp convention. This really is documented.
}
static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1);
ATLASSERT(nRet != 0);
return nRet - 2; // Convert to strcmp convention. This really is documented.
}
static int _cstrtoi(const TCHAR* nptr)
{
int c; /* current char */
int total; /* current total */
int sign; /* if '-', then negative, otherwise positive */
while ( _cstrisspace(*nptr) )
++nptr;
c = (int)(_TUCHAR)*nptr++;
sign = c; /* save sign indication */
if (c == _T('-') || c == _T('+'))
c = (int)(_TUCHAR)*nptr++; /* skip sign */
total = 0;
while (_cstrisdigit((TCHAR)c)) {
total = 10 * total + (c - '0'); /* accumulate digit */
c = (int)(_TUCHAR)*nptr++; /* get next char */
}
if (sign == '-')
return -total;
else
return total; /* return result, negated if necessary */
}
#else //!_ATL_MIN_CRT
static TCHAR* _cstrchr(const TCHAR* p, TCHAR ch)
{
return _tcschr(p, ch);
}
static TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
{
return _tcsrchr(p, ch);
}
static TCHAR* _cstrrev(TCHAR* pStr)
{
return _tcsrev(pStr);
}
static TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet)
{
return _tcsstr(pStr, pCharSet);
}
static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet)
{
return (int)_tcsspn(pStr, pCharSet);
}
static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet)
{
return (int)_tcscspn(pStr, pCharSet);
}
static TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet)
{
return _tcspbrk(p, lpszCharSet);
}
static int _cstrisdigit(TCHAR ch)
{
return _istdigit(ch);
}
static int _cstrisspace(TCHAR ch)
{
return _istspace(ch);
}
static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return _tcscmp(pstrOne, pstrOther);
}
static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return _tcsicmp(pstrOne, pstrOther);
}
static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return _tcscoll(pstrOne, pstrOther);
}
static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return _tcsicoll(pstrOne, pstrOther);
}
static int _cstrtoi(const TCHAR* nptr)
{
return _ttoi(nptr);
}
#endif //!_ATL_MIN_CRT
};
// Compare helpers
bool __stdcall operator==(const CAtsString& s1, const CAtsString& s2);
bool __stdcall operator==(const CAtsString& s1, LPCTSTR s2);
bool __stdcall operator==(LPCTSTR s1, const CAtsString& s2);
bool __stdcall operator!=(const CAtsString& s1, const CAtsString& s2);
bool __stdcall operator!=(const CAtsString& s1, LPCTSTR s2);
bool __stdcall operator!=(LPCTSTR s1, const CAtsString& s2);
bool __stdcall operator<(const CAtsString& s1, const CAtsString& s2);
bool __stdcall operator<(const CAtsString& s1, LPCTSTR s2);
bool __stdcall operator<(LPCTSTR s1, const CAtsString& s2);
bool __stdcall operator>(const CAtsString& s1, const CAtsString& s2);
bool __stdcall operator>(const CAtsString& s1, LPCTSTR s2);
bool __stdcall operator>(LPCTSTR s1, const CAtsString& s2);
bool __stdcall operator<=(const CAtsString& s1, const CAtsString& s2);
bool __stdcall operator<=(const CAtsString& s1, LPCTSTR s2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -