📄 atlmisc.h
字号:
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)
{
int n = _cstrcspn(p, lpszCharSet);
return (p[n] != 0) ? (TCHAR*)&p[n] : 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 (TCHAR*)_tcschr(p, ch);
}
static TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
{
return (TCHAR*)_tcsrchr(p, ch);
}
static TCHAR* _cstrrev(TCHAR* pStr)
{
return _tcsrev(pStr);
}
static TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet)
{
return (TCHAR*)_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 (TCHAR*)_tcspbrk(p, lpszCharSet);
}
static int _cstrisdigit(TCHAR ch)
{
return _istdigit(ch);
}
static int _cstrisspace(TCHAR ch)
{
return _istspace((_TUCHAR)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);
}
#ifndef _WIN32_WCE
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);
}
#endif //!_WIN32_WCE
static int _cstrtoi(const TCHAR* nptr)
{
return _ttoi(nptr);
}
#endif //!_ATL_MIN_CRT
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;
}
};
// Compare helpers
bool __stdcall operator ==(const CString& s1, const CString& s2);
bool __stdcall operator ==(const CString& s1, LPCTSTR s2);
bool __stdcall operator ==(LPCTSTR s1, const CString& s2);
bool __stdcall operator !=(const CString& s1, const CString& s2);
bool __stdcall operator !=(const CString& s1, LPCTSTR s2);
bool __stdcall operator !=(LPCTSTR s1, const CString& s2);
bool __stdcall operator <(const CString& s1, const CString& s2);
bool __stdcall operator <(const CString& s1, LPCTSTR s2);
bool __stdcall operator <(LPCTSTR s1, const CString& s2);
bool __stdcall operator >(const CString& s1, const CString& s2);
bool __stdcall operator >(const CString& s1, LPCTSTR s2);
bool __stdcall operator >(LPCTSTR s1, const CString& s2);
bool __stdcall operator <=(const CString& s1, const CString& s2);
bool __stdcall operator <=(const CString& s1, LPCTSTR s2);
bool __stdcall operator <=(LPCTSTR s1, const CString& s2);
bool __stdcall operator >=(const CString& s1, const CString& s2);
bool __stdcall operator >=(const CString& s1, LPCTSTR s2);
bool __stdcall operator >=(LPCTSTR s1, const CString& s2);
///////////////////////////////////////////////////////////////////////////////
// CString Implementation
inline CStringData* CString::GetData() const
{
ATLASSERT(m_pchData != NULL);
return ((CStringData*)m_pchData) - 1;
}
inline void CString::Init()
{ m_pchData = _GetEmptyString().m_pchData; }
inline CString::CString(const unsigned char* lpsz)
{
Init();
*this = (LPCSTR)lpsz;
}
inline const CString& CString::operator =(const unsigned char* lpsz)
{
*this = (LPCSTR)lpsz;
return *this;
}
#ifdef _UNICODE
inline const CString& CString::operator +=(char ch)
{
*this += (TCHAR)ch;
return *this;
}
inline const CString& CString::operator =(char ch)
{
*this = (TCHAR)ch;
return *this;
}
inline CString __stdcall operator +(const CString& string, char ch)
{ return string + (TCHAR)ch; }
inline CString __stdcall operator +(char ch, const CString& string)
{ return (TCHAR)ch + string; }
#endif //_UNICODE
inline int CString::GetLength() const
{ return GetData()->nDataLength; }
inline int CString::GetAllocLength() const
{ return GetData()->nAllocLength; }
inline BOOL CString::IsEmpty() const
{ return GetData()->nDataLength == 0; }
inline CString::operator LPCTSTR() const
{ return m_pchData; }
inline int PASCAL CString::SafeStrlen(LPCTSTR lpsz)
{ return (lpsz == NULL) ? 0 : lstrlen(lpsz); }
// CString support (windows specific)
inline int CString::Compare(LPCTSTR lpsz) const
{ return _cstrcmp(m_pchData, lpsz); } // MBCS/Unicode aware
inline int CString::CompareNoCase(LPCTSTR lpsz) const
{ return _cstrcmpi(m_pchData, lpsz); } // MBCS/Unicode aware
// CString::Collate is often slower than Compare but is MBSC/Unicode
// aware as well as locale-sensitive with respect to sort order.
#ifndef _WIN32_WCE
inline int CString::Collate(LPCTSTR lpsz) const
{ return _cstrcoll(m_pchData, lpsz); } // locale sensitive
inline int CString::CollateNoCase(LPCTSTR lpsz) const
{ return _cstrcolli(m_pchData, lpsz); } // locale sensitive
#endif //!_WIN32_WCE
inline TCHAR CString::GetAt(int nIndex) const
{
ATLASSERT(nIndex >= 0);
ATLASSERT(nIndex < GetData()->nDataLength);
return m_pchData[nIndex];
}
inline TCHAR CString::operator [](int nIndex) const
{
// same as GetAt
ATLASSERT(nIndex >= 0);
ATLASSERT(nIndex < GetData()->nDataLength);
return m_pchData[nIndex];
}
inline bool __stdcall operator ==(const CString& s1, const CString& s2)
{ return s1.Compare(s2) == 0; }
inline bool __stdcall operator ==(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) == 0; }
inline bool __stdcall operator ==(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) == 0; }
inline bool __stdcall operator !=(const CString& s1, const CString& s2)
{ return s1.Compare(s2) != 0; }
inline bool __stdcall operator !=(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) != 0; }
inline bool __stdcall operator !=(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) != 0; }
inline bool __stdcall operator <(const CString& s1, const CString& s2)
{ return s1.Compare(s2) < 0; }
inline bool __stdcall operator <(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) < 0; }
inline bool __stdcall operator <(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) > 0; }
inline bool __stdcall operator >(const CString& s1, const CString& s2)
{ return s1.Compare(s2) > 0; }
inline bool __stdcall operator >(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) > 0; }
inline bool __stdcall operator >(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) < 0; }
inline bool __stdcall operator <=(const CString& s1, const CString& s2)
{ return s1.Compare(s2) <= 0; }
inline bool __stdcall operator <=(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) <= 0; }
inline bool __stdcall operator <=(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) >= 0; }
inline bool __stdcall operator >=(const CString& s1, const CString& s2)
{ return s1.Compare(s2) >= 0; }
inline bool __stdcall operator >=(const CString& s1, LPCTSTR s2)
{ return s1.Compare(s2) >= 0; }
inline bool __stdcall operator >=(LPCTSTR s1, const CString& s2)
{ return s2.Compare(s1) <= 0; }
inline CString::CString()
{
Init();
}
inline CString::CString(const CString& stringSrc)
{
ATLASSERT(stringSrc.GetData()->nRefs != 0);
if (stringSrc.GetData()->nRefs >= 0)
{
ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
m_pchData = stringSrc.m_pchData;
InterlockedIncrement(&GetData()->nRefs);
}
else
{
Init();
*this = stringSrc.m_pchData;
}
}
inline BOOL CString::AllocBuffer(int nLen)
// always allocate one extra character for '\0' termination
// assumes [optimistically] that data length will equal allocation length
{
ATLASSERT(nLen >= 0);
ATLASSERT(nLen <= INT_MAX - 1); // max size (enough room for 1 extra)
if (nLen == 0)
{
Init();
}
else
{
CStringData* pData = NULL;
ATLTRY(pData = (CStringData*)new BYTE[sizeof(CStringData) + (nLen + 1) * sizeof(TCHAR)]);
if(pData == NULL)
return FALSE;
pData->nRefs = 1;
pData->data()[nLen] = '\0';
pData->nDataLength = nLen;
pData->nAllocLength = nLen;
m_pchData = pData->data();
}
return TRUE;
}
inline void CString::Release()
{
if (GetData() != _atltmpDataNil)
{
ATLASSERT(GetData()->nRefs != 0);
if (InterlockedDecrement(&GetData()->nRefs) <= 0)
delete[] (BYTE*)GetData();
Init();
}
}
inline void PASCAL CString::Release(CStringData* pData)
{
if (pData != _atltmpDataNil)
{
ATLASSERT(pData->nRefs != 0);
if (InterlockedDecrement(&pData->nRefs) <= 0)
delete[] (BYTE*)pData;
}
}
inline void CString::Empty()
{
if (GetData()->nDataLength == 0)
return;
if (GetData()->nRefs >= 0)
Release();
else
*this = _T("");
ATLASSERT(GetData()->nDataLength == 0);
ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
}
inline void CString::CopyBeforeWrite()
{
if (GetData()->nRefs > 1)
{
CStringData* pData = GetData();
Release();
if(AllocBuffer(pData->nDataLength))
memcpy(m_pchData, pData->data(), (pData->nDataLength + 1) * sizeof(TCHAR));
}
ATLASSERT(GetData()->nRefs <= 1);
}
inline BOOL CString::AllocBeforeWrite(int nLen)
{
BOOL bRet = TRUE;
if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
{
Release();
bRet = AllocBuffer(nLen);
}
ATLASSERT(GetData()->nRefs <= 1);
return bRet;
}
inline CString::~CString()
// free any attached data
{
if (GetData() != _atltmpDataNil)
{
if (InterlockedDecrement(&GetData()->nRefs) <= 0)
delete[] (BYTE*)GetData();
}
}
inline void CString::AllocCopy(CString& dest, int nCopyLen, int nCopyIndex,
int nExtraLen) const
{
// will clone the data attached to this string
// allocating 'nExtraLen' characters
// Places results in uninitialized string 'dest'
// Will copy the part or all of original data to start of new string
int nNewLen = nCopyLen + nExtraLen;
if (nNewLen == 0)
{
dest.Init();
}
else
{
if(dest.AllocBuffer(nNewLen))
memcpy(dest.m_pchData, m_pchData + nCopyIndex, nCopyLen * sizeof(TCHAR));
}
}
inline CString::CString(LPCTSTR lpsz)
{
Init();
if (lpsz != NULL && HIWORD(lpsz) == NULL)
{
UINT nID = LOWORD((DWORD_PTR)lpsz);
if (!LoadString(nID))
ATLTRACE2(atlTraceUI, 0, _T("Warning: implicit LoadString(%u) in CString failed\n"), nID);
}
else
{
int nLen = SafeStrlen(lpsz);
if (nLen != 0)
{
if(AllocBuffer(nLen))
memcpy(m_pchData, lpsz, nLen * sizeof(TCHAR));
}
}
}
#ifdef _UNICODE
inline CString::CString(LPCSTR lpsz)
{
Init();
int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
if (nSrcLen != 0)
{
if(AllocBuffer(nSrcLen))
{
_mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
ReleaseBuffer();
}
}
}
#else //_UNICODE
inline CString::CString(LPCWSTR lpsz)
{
Init();
int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0;
if (nSrcLen != 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -