📄 atl_cstring.cpp
字号:
}
GetBuffer(nMaxLen);
/*VERIFY*/ if (!(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength()))
{
ATLASSERT(0);
}
ReleaseBuffer();
va_end(argListSave);
}
// formatting (using wsprintf style formatting)
void AFX_CDECL CString::Format(LPCTSTR lpszFormat, ...)
{
ATLASSERT(AfxIsValidString(lpszFormat));
va_list argList;
va_start(argList, lpszFormat);
FormatV(lpszFormat, argList);
va_end(argList);
}
void AFX_CDECL CString::Format(UINT nFormatID, ...)
{
CString strFormat;
/*VERIFY*/ if (!(strFormat.LoadString(nFormatID) != 0))
{
ATLASSERT(0);
}
va_list argList;
va_start(argList, nFormatID);
FormatV(strFormat, argList);
va_end(argList);
}
// formatting (using FormatMessage style formatting)
void AFX_CDECL CString::FormatMessage(LPCTSTR lpszFormat, ...)
{
// format message into temporary buffer lpszTemp
va_list argList;
va_start(argList, lpszFormat);
LPTSTR lpszTemp;
if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 ||
lpszTemp == NULL)
{
//AfxThrowMemoryException();
ATLASSERT(0);
}
// assign lpszTemp into the resulting string and free the temporary
*this = lpszTemp;
LocalFree(lpszTemp);
va_end(argList);
}
void AFX_CDECL CString::FormatMessage(UINT nFormatID, ...)
{
// get format string from string table
CString strFormat;
/*VERIFY*/ if (!(strFormat.LoadString(nFormatID) != 0))
{
ATLASSERT(0);
}
// format message into temporary buffer lpszTemp
va_list argList;
va_start(argList, nFormatID);
LPTSTR lpszTemp;
if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 ||
lpszTemp == NULL)
{
//AfxThrowMemoryException();
ATLASSERT(0);
}
// assign lpszTemp into the resulting string and free lpszTemp
*this = lpszTemp;
LocalFree(lpszTemp);
va_end(argList);
}
void CString::TrimRight(LPCTSTR lpszTargetList)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != '\0')
{
if (_tcschr(lpszTargetList, *lpsz) != NULL)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = _tcsinc(lpsz);
}
if (lpszLast != NULL)
{
// truncate at left-most matching character
*lpszLast = '\0';
GetData()->nDataLength = lpszLast - m_pchData;
}
}
void CString::TrimRight(TCHAR chTarget)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != '\0')
{
if (*lpsz == chTarget)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = _tcsinc(lpsz);
}
if (lpszLast != NULL)
{
// truncate at left-most matching character
*lpszLast = '\0';
GetData()->nDataLength = lpszLast - m_pchData;
}
}
void CString::TrimRight()
{
// find beginning of trailing spaces by starting at beginning (DBCS aware)
CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != '\0')
{
if (_istspace(*lpsz))
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = _tcsinc(lpsz);
}
if (lpszLast != NULL)
{
// truncate at trailing space start
*lpszLast = '\0';
GetData()->nDataLength = lpszLast - m_pchData;
}
}
void CString::TrimLeft(LPCTSTR lpszTargets)
{
// if we're not trimming anything, we're not doing any work
if (SafeStrlen(lpszTargets) == 0)
return;
CopyBeforeWrite();
LPCTSTR lpsz = m_pchData;
while (*lpsz != '\0')
{
if (_tcschr(lpszTargets, *lpsz) == NULL)
break;
lpsz = _tcsinc(lpsz);
}
if (lpsz != m_pchData)
{
// fix up data and length
int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR));
GetData()->nDataLength = nDataLength;
}
}
void CString::TrimLeft(TCHAR chTarget)
{
// find first non-matching character
CopyBeforeWrite();
LPCTSTR lpsz = m_pchData;
while (chTarget == *lpsz)
lpsz = _tcsinc(lpsz);
if (lpsz != m_pchData)
{
// fix up data and length
int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR));
GetData()->nDataLength = nDataLength;
}
}
void CString::TrimLeft()
{
// find first non-space character
CopyBeforeWrite();
LPCTSTR lpsz = m_pchData;
while (_istspace(*lpsz))
lpsz = _tcsinc(lpsz);
if (lpsz != m_pchData)
{
// fix up data and length
int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR));
GetData()->nDataLength = nDataLength;
}
}
///////////////////////////////////////////////////////////////////////////////
// --- from WINSTR.CPP
/////////////////////////////////////////////////////////////////////////////
// Windows extensions to strings
#ifdef _UNICODE
#define CHAR_FUDGE 1 // one TCHAR unused is good enough
#else
#define CHAR_FUDGE 2 // two BYTES unused for case of DBC last char
#endif
BOOL CString::LoadString(UINT nID)
{
// try fixed buffer first (to avoid wasting space in the heap)
TCHAR szTemp[256];
int nLen = AfxLoadString(nID, szTemp, _countof(szTemp));
if (_countof(szTemp) - nLen > CHAR_FUDGE)
{
*this = szTemp;
return nLen > 0;
}
// try buffer size of 512, then larger size until entire string is retrieved
int nSize = 256;
do
{
nSize += 256;
nLen = AfxLoadString(nID, GetBuffer(nSize-1), nSize);
} while (nSize - nLen <= CHAR_FUDGE);
ReleaseBuffer();
return nLen > 0;
}
#ifndef _AFXDLL
int AFXAPI AfxLoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
{
ATLASSERT(AfxIsValidAddress(lpszBuf, nMaxBuf*sizeof(TCHAR)));
#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;
}
#endif
/////////////////////////////////////////////////////////////////////////////
// --- from FixedAlloc.H
// fixalloc.h - declarations for fixed block allocator
#ifndef __FIXALLOC_H__
#define __FIXALLOC_H__
#include "afxplex_.h"
/////////////////////////////////////////////////////////////////////////////
// CFixedAlloc
class CFixedAlloc
{
// Constructors
public:
CFixedAlloc(UINT nAllocSize, UINT nBlockSize = 64);
// Attributes
UINT GetAllocSize() { return m_nAllocSize; }
// Operations
public:
void* Alloc(); // return a chunk of memory of nAllocSize
void Free(void* p); // free chunk of memory returned from Alloc
void FreeAll(); // free everything allocated from this allocator
// Implementation
public:
~CFixedAlloc();
protected:
struct CNode
{
CNode* pNext; // only valid when in free list
};
UINT m_nAllocSize; // size of each block from Alloc
UINT m_nBlockSize; // number of blocks to get at a time
CPlex* m_pBlocks; // linked list of blocks (is nBlocks*nAllocSize)
CNode* m_pNodeFree; // first free node (NULL if no free nodes)
CRITICAL_SECTION m_protect;
};
#ifndef _DEBUG
// DECLARE_FIXED_ALLOC -- used in class definition
#define DECLARE_FIXED_ALLOC(class_name) \
public: \
void* operator new(size_t size) \
{ \
ATLASSERT(size == s_alloc.GetAllocSize()); \
UNUSED(size); \
return s_alloc.Alloc(); \
} \
void* operator new(size_t, void* p) \
{ return p; } \
void operator delete(void* p) { s_alloc.Free(p); } \
void* operator new(size_t size, LPCSTR, int) \
{ \
ATLASSERT(size == s_alloc.GetAllocSize()); \
UNUSED(size); \
return s_alloc.Alloc(); \
} \
protected: \
static CFixedAlloc s_alloc \
// IMPLEMENT_FIXED_ALLOC -- used in class implementation file
#define IMPLEMENT_FIXED_ALLOC(class_name, block_size) \
CFixedAlloc class_name::s_alloc(sizeof(class_name), block_size) \
#else //!_DEBUG
#define DECLARE_FIXED_ALLOC(class_name) // nothing in debug
#define IMPLEMENT_FIXED_ALLOC(class_name, block_size) // nothing in debug
#endif //!_DEBUG
#endif
// --- from FixedAlloc.H
/////////////////////////////////////////////////////////////////////////////
// CFixedAlloc
CFixedAlloc::CFixedAlloc(UINT nAllocSize, UINT nBlockSize)
{
ATLASSERT(nAllocSize >= sizeof(CNode));
ATLASSERT(nBlockSize > 1);
m_nAllocSize = nAllocSize;
m_nBlockSize = nBlockSize;
m_pNodeFree = NULL;
m_pBlocks = NULL;
InitializeCriticalSection(&m_protect);
}
CFixedAlloc::~CFixedAlloc()
{
FreeAll();
DeleteCriticalSection(&m_protect);
}
void CFixedAlloc::FreeAll()
{
EnterCriticalSection(&m_protect);
m_pBlocks->FreeDataChain();
m_pBlocks = NULL;
m_pNodeFree = NULL;
LeaveCriticalSection(&m_protect);
}
void* CFixedAlloc::Alloc()
{
EnterCriticalSection(&m_protect);
if (m_pNodeFree == NULL)
{
CPlex* pNewBlock = NULL;
TRY
{
// add another block
pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize, m_nAllocSize);
}
CATCH_ALL(e)
{
LeaveCriticalSection(&m_protect);
THROW_LAST();
}
END_CATCH_ALL
// chain them into free list
CNode* pNode = (CNode*)pNewBlock->data();
// free in reverse order to make it easier to debug
(BYTE*&)pNode += (m_nAllocSize * m_nBlockSize) - m_nAllocSize;
for (int i = m_nBlockSize-1; i >= 0; i--, (BYTE*&)pNode -= m_nAllocSize)
{
pNode->pNext = m_pNodeFree;
m_pNodeFree = pNode;
}
}
ATLASSERT(m_pNodeFree != NULL); // we must have something
// remove the first available node from the free list
void* pNode = m_pNodeFree;
m_pNodeFree = m_pNodeFree->pNext;
LeaveCriticalSection(&m_protect);
return pNode;
}
void CFixedAlloc::Free(void* p)
{
if (p != NULL)
{
EnterCriticalSection(&m_protect);
// simply return the node to the free list
CNode* pNode = (CNode*)p;
pNode->pNext = m_pNodeFree;
m_pNodeFree = pNode;
LeaveCriticalSection(&m_protect);
}
}
// --- from Plex.cpp
/////////////////////////////////////////////////////////////////////////////
// CPlex
CPlex* PASCAL CPlex::Create(CPlex*& pHead, UINT nMax, UINT cbElement)
{
ATLASSERT(nMax > 0 && cbElement > 0);
CPlex* p = (CPlex*) new BYTE[sizeof(CPlex) + nMax * cbElement];
// may throw exception
p->pNext = pHead;
pHead = p; // change head (adds in reverse order for simplicity)
return p;
}
void CPlex::FreeDataChain() // free this one and links
{
CPlex* p = this;
while (p != NULL)
{
BYTE* bytes = (BYTE*) p;
CPlex* pNext = p->pNext;
delete[] bytes;
p = pNext;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -