?? tstring.cpp
字號:
#include "TString.h"
#include <memory.h>
int T_afxInitData[] = { -1, 0, 0, 0 };
TStringData* T_afxDataNil = (TStringData*)&T_afxInitData;
TLPCTSTR T_afxPchNil = (TLPCTSTR)(((TBYTE*)&T_afxInitData)+sizeof(TStringData));
const TString& TAfxGetEmptyString()
{
return *(TString*)&T_afxPchNil;
}
char TafxChNil = '\0';
// constructs empty TString
TString::TString()
{
Init();
}
// copy constructor
TString::TString(const TString& stringSrc)
{
assert(stringSrc.GetData()->nRefs != 0); //ASSERT->assert
if (stringSrc.GetData()->nRefs >= 0)
{
assert(stringSrc.GetData() != T_afxDataNil); //ASSERT->assert
m_pchData = stringSrc.m_pchData;
//InterlockedIncrement(&GetData()->nRefs);
GetData()->nRefs++; //要求加鎖???
}
else
{
Init();
*this = stringSrc.m_pchData;
}
}
// from a single character
TString::TString( char ch, int nLength ) //Param2-nRepeat
{
Init();
if (nLength >= 1)
{
AllocBuffer(nLength);
//#ifdef _UNICODE
// for (int i = 0; i < nLength; i++)
// m_pchData[i] = ch;
//#else
memset(m_pchData, ch, nLength);
//#endif
}
}
// from an ANSI string (converts to TCHAR)
TString::TString( TLPCTSTR lpsz )
{
Init();
//if (lpsz != NULL && HIWORD(lpsz) == NULL)
//{
// UINT nID = LOWORD((DWORD)lpsz);
// if (!LoadString(nID))
// TRACE1("Warning: implicit LoadString(%u) failed\n", nID);
//}
//else
{
int nLen = SafeStrlen(lpsz);
if (nLen != 0)
{
AllocBuffer(nLen);
memcpy(m_pchData, lpsz, nLen*sizeof(char));
}
}
}
// subset of characters from an ANSI string (converts to TCHAR)
TString::TString(TLPCSTR lpch, int nLength)
{
Init();
if (nLength != 0)
{
//ASSERT(AfxIsValidAddress(lpch, nLength, FALSE)); //檢查指針的有效性
assert(lpch!=NULL);
AllocBuffer(nLength);
memcpy(m_pchData, lpch, nLength*sizeof(char));
}
}
// clear contents to empty
void TString::Empty()
{
if (GetData()->nDataLength == 0)
return;
if (GetData()->nRefs >= 0)
Release();
else
*this = &TafxChNil;
assert(GetData()->nDataLength == 0);
assert(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
}
// set a single character at zero-based index
void TString::SetAt(int nIndex, char ch)
{
assert(nIndex >= 0);
assert(nIndex < GetData()->nDataLength);
CopyBeforeWrite();
m_pchData[nIndex] = ch;
}
// overloaded assignment=======================
// ref-counted copy from another CString
const TString& TString::operator=(const TString& stringSrc)
{
if (m_pchData != stringSrc.m_pchData)
{
if ((GetData()->nRefs < 0 && GetData() != T_afxDataNil) ||
stringSrc.GetData()->nRefs < 0)
{
// actual copy necessary since one of the strings is locked
AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
}
else
{
// can just copy references around
Release();
assert(stringSrc.GetData() != T_afxDataNil);
m_pchData = stringSrc.m_pchData;
//InterlockedIncrement(&GetData()->nRefs);
GetData()->nRefs++; //修改之前加鎖
}
}
return *this;
}
// set string content to single character
const TString& TString::operator=(char ch)
{
AssignCopy(1, &ch);
return *this;
}
// copy string content from ANSI string (converts to TCHAR)
const TString& TString::operator=(TLPCSTR lpsz)
{
//assert(lpsz == NULL || AfxIsValidString(lpsz));
AssignCopy(SafeStrlen(lpsz), lpsz);
return *this;
}
// string concatenation==========================
// concatenate from another CString
const TString& TString::operator+=(const TString& string)
{
ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
return *this;
}
// concatenate a single character
const TString& TString::operator+=(char ch)
{
ConcatInPlace(1, &ch);
return *this;
}
// concatenate a UNICODE character after converting it to TCHAR
const TString& TString::operator+=(TLPCTSTR lpsz)
{
//ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
ConcatInPlace(SafeStrlen(lpsz), lpsz);
return *this;
}
//////////////////////////////////////////////////////////////////////////////
// concatenation
// NOTE: "operator+" is done as friend functions for simplicity
// There are three variants:
// CString + CString
// and for ? = TCHAR, LPCTSTR
// CString + ?
// ? + CString
TString operator+(const TString& string1,const TString& string2)
{
TString s;
s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
string2.GetData()->nDataLength, string2.m_pchData);
return s;
}
TString operator+(const TString& string1, char ch)
{
TString s;
s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
return s;
}
TString operator+(char ch, const TString& string)
{
TString s;
s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
return s;
}
TString operator+(const TString& string, TLPCTSTR lpsz)
{
//ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
TString s;
s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData,
TString::SafeStrlen(lpsz), lpsz);
return s;
}
TString operator+(TLPCTSTR lpsz, const TString& string)
{
//ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
TString s;
s.ConcatCopy(TString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength,
string.m_pchData);
return s;
}
// simple sub-string extraction==================================
// return nCount characters starting at zero-based nFirst
TString TString::Mid(int nFirst, int nCount) const
{
// out-of-bounds requests return sensible things
if (nFirst < 0)
nFirst = 0;
if (nCount < 0)
nCount = 0;
if (nFirst + nCount > GetData()->nDataLength)
nCount = GetData()->nDataLength - nFirst;
if (nFirst > GetData()->nDataLength)
nCount = 0;
assert(nFirst >= 0);
assert(nFirst + nCount <= GetData()->nDataLength);
// optimize case of returning entire string
if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
return *this;
TString dest;
AllocCopy(dest, nCount, nFirst, 0);
return dest;
}
// return all characters starting at zero-based nFirst
TString TString::Mid(int nFirst) const
{
return Mid(nFirst, GetData()->nDataLength - nFirst);
}
// return first nCount characters in string
TString TString::Left(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= GetData()->nDataLength)
return *this;
TString dest;
AllocCopy(dest, nCount, 0, 0);
return dest;
}
// return nCount characters from end of string
TString TString::Right(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= GetData()->nDataLength)
return *this;
TString dest;
AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
return dest;
}
// characters from beginning that are also in passed string
// strspn equivalent
TString TString::SpanIncluding(TLPCTSTR lpszCharSet) const
{
//ASSERT(AfxIsValidString(lpszCharSet));
//return Left(_tcsspn(m_pchData, lpszCharSet));
return TString("");
}
// characters from beginning that are not also in passed string
// strcspn equivalent
TString TString::SpanExcluding(TLPCTSTR lpszCharSet) const
{
//ASSERT(AfxIsValidString(lpszCharSet));
//return Left(_tcscspn(m_pchData, lpszCharSet));
return TString("");
}
// upper/lower/reverse conversion===================
// NLS aware conversion to uppercase
void TString::MakeUpper() //等待改造???
{
CopyBeforeWrite();
//_tcsupr(m_pchData);
}
// NLS aware conversion to lowercase
void TString::MakeLower() //等待改造???
{
CopyBeforeWrite();
//_tcslwr(m_pchData);
}
// reverse string right-to-left
void TString::MakeReverse() //等待改造???
{
CopyBeforeWrite();
//_tcsrev(m_pchData);
}
// trimming whitespace (either side)==============================
// remove whitespace starting from right edge
void TString::TrimRight()
{
// find beginning of trailing spaces by starting at beginning (DBCS aware)
return;
/* CopyBeforeWrite();
TLPTSTR lpsz = m_pchData;
TLPTSTR 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;
}*/
}
// remove whitespace starting from left side
void TString::TrimLeft()
{
// find first non-space character
return;
/* CopyBeforeWrite();
TLPCTSTR 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;
}
*/
}
// trimming anything (either side)=======
// remove continuous occurrences of chTarget starting from right
void TString::TrimRight(char chTarget)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
return;
/* CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -