⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atsstring.h

📁 AtScript 1.1 一个很好用的脚本引擎,可以很方便的在你的软件中实现脚本功能,支持用户扩展对象
💻 H
📖 第 1 页 / 共 4 页
字号:
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);


/////////////////////////////////////////////////////////////////////////////
// CAtsString Implementation

inline CAtsStringData* CAtsString::GetData() const
	{ ATLASSERT(m_pchData != NULL); return ((CAtsStringData*)m_pchData) - 1; }
inline void CAtsString::Init()
	{ m_pchData = _GetEmptyString().m_pchData; }
inline CAtsString::CAtsString(const unsigned char* lpsz)
	{ Init(); *this = (LPCSTR)lpsz; }
inline const CAtsString& CAtsString::operator=(const unsigned char* lpsz)
	{ *this = (LPCSTR)lpsz; return *this; }
#ifdef _UNICODE
inline const CAtsString& CAtsString::operator+=(char ch)
	{ *this += (TCHAR)ch; return *this; }
inline const CAtsString& CAtsString::operator=(char ch)
	{ *this = (TCHAR)ch; return *this; }
inline CAtsString __stdcall operator+(const CAtsString& string, char ch)
	{ return string + (TCHAR)ch; }
inline CAtsString __stdcall operator+(char ch, const CAtsString& string)
	{ return (TCHAR)ch + string; }
#endif

inline int CAtsString::GetLength() const
	{ return GetData()->nDataLength; }
inline int CAtsString::GetAllocLength() const
	{ return GetData()->nAllocLength; }
inline BOOL CAtsString::IsEmpty() const
	{ return GetData()->nDataLength == 0; }
inline CAtsString::operator LPCTSTR() const
	{ return m_pchData; }
inline int PASCAL CAtsString::SafeStrlen(LPCTSTR lpsz)
	{ return (lpsz == NULL) ? 0 : lstrlen(lpsz); }

// CAtsString support (windows specific)
inline int CAtsString::Compare(LPCTSTR lpsz) const
	{ return _cstrcmp(m_pchData, lpsz); }    // MBCS/Unicode aware
inline int CAtsString::CompareNoCase(LPCTSTR lpsz) const
	{ return _cstrcmpi(m_pchData, lpsz); }   // MBCS/Unicode aware
// CAtsString::Collate is often slower than Compare but is MBSC/Unicode
//  aware as well as locale-sensitive with respect to sort order.
inline int CAtsString::Collate(LPCTSTR lpsz) const
	{ return _cstrcoll(m_pchData, lpsz); }   // locale sensitive
inline int CAtsString::CollateNoCase(LPCTSTR lpsz) const
	{ return _cstrcolli(m_pchData, lpsz); }   // locale sensitive

inline TCHAR CAtsString::GetAt(int nIndex) const
{
	ATLASSERT(nIndex >= 0);
	ATLASSERT(nIndex < GetData()->nDataLength);
	return m_pchData[nIndex];
}
inline TCHAR CAtsString::operator[](int nIndex) const
{
	// same as GetAt
	ATLASSERT(nIndex >= 0);
	ATLASSERT(nIndex < GetData()->nDataLength);
	return m_pchData[nIndex];
}
inline bool __stdcall operator==(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) == 0; }
inline bool __stdcall operator==(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) == 0; }
inline bool __stdcall operator==(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) == 0; }
inline bool __stdcall operator!=(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) != 0; }
inline bool __stdcall operator!=(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) != 0; }
inline bool __stdcall operator!=(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) != 0; }
inline bool __stdcall operator<(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) < 0; }
inline bool __stdcall operator<(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) < 0; }
inline bool __stdcall operator<(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) > 0; }
inline bool __stdcall operator>(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) > 0; }
inline bool __stdcall operator>(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) > 0; }
inline bool __stdcall operator>(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) < 0; }
inline bool __stdcall operator<=(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) <= 0; }
inline bool __stdcall operator<=(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) <= 0; }
inline bool __stdcall operator<=(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) >= 0; }
inline bool __stdcall operator>=(const CAtsString& s1, const CAtsString& s2)
	{ return s1.Compare(s2) >= 0; }
inline bool __stdcall operator>=(const CAtsString& s1, LPCTSTR s2)
	{ return s1.Compare(s2) >= 0; }
inline bool __stdcall operator>=(LPCTSTR s1, const CAtsString& s2)
	{ return s2.Compare(s1) <= 0; }

inline CAtsString::CAtsString()
{
	Init();
}

inline CAtsString::CAtsString(const CAtsString& 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 CAtsString::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
	{
		CAtsStringData* pData = NULL;
		ATLTRY(pData = (CAtsStringData*)new BYTE[sizeof(CAtsStringData) + (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 CAtsString::Release()
{
	if (GetData() != _atltmpDataNil)
	{
		ATLASSERT(GetData()->nRefs != 0);
		if (InterlockedDecrement(&GetData()->nRefs) <= 0)
			delete[] (BYTE*)GetData();
		Init();
	}
}

inline void PASCAL CAtsString::Release(CAtsStringData* pData)
{
	if (pData != _atltmpDataNil)
	{
		ATLASSERT(pData->nRefs != 0);
		if (InterlockedDecrement(&pData->nRefs) <= 0)
			delete[] (BYTE*)pData;
	}
}

inline void CAtsString::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 CAtsString::CopyBeforeWrite()
{
	if (GetData()->nRefs > 1)
	{
		CAtsStringData* pData = GetData();
		Release();
		if(AllocBuffer(pData->nDataLength))
			memcpy(m_pchData, pData->data(), (pData->nDataLength + 1) * sizeof(TCHAR));
	}
	ATLASSERT(GetData()->nRefs <= 1);
}

inline BOOL CAtsString::AllocBeforeWrite(int nLen)
{
	BOOL bRet = TRUE;
	if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
	{
		Release();
		bRet = AllocBuffer(nLen);
	}
	ATLASSERT(GetData()->nRefs <= 1);
	return bRet;
}

inline CAtsString::~CAtsString()
//  free any attached data
{
	if (GetData() != _atltmpDataNil)
	{
		if (InterlockedDecrement(&GetData()->nRefs) <= 0)
			delete[] (BYTE*)GetData();
	}
}

inline void CAtsString::AllocCopy(CAtsString& 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 CAtsString::CAtsString(LPCTSTR lpsz)
{
	Init();
	if (lpsz != NULL && HIWORD(lpsz) == NULL)
	{
		UINT nID = LOWORD((ADWORD_PTR)lpsz);
		LoadString(nID);
		// Jonfei 2004/6/7
		//if (!LoadString(nID))
		//	ATLTRACE2(atlTraceUI, 0, _T("Warning: implicit LoadString(%u) in CAtsString failed\n"), nID);
	}
	else
	{
		int nLen = SafeStrlen(lpsz);
		if (nLen != 0)
		{
			if(AllocBuffer(nLen))
				memcpy(m_pchData, lpsz, nLen * sizeof(TCHAR));
		}
	}
}

#ifdef _UNICODE
inline CAtsString::CAtsString(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 CAtsString::CAtsString(LPCWSTR lpsz)
{
	Init();
	int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0;
	if (nSrcLen != 0)
	{
		if(AllocBuffer(nSrcLen * 2))
		{
			_wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
			ReleaseBuffer();
		}
	}
}
#endif //!_UNICODE

// Assignment operators
//  All assign a new value to the string
//      (a) first see if the buffer is big enough
//      (b) if enough room, copy on top of old buffer, set size and type
//      (c) otherwise free old string data, and create a new one
//
//  All routines return the new string (but as a 'const CAtsString&' so that
//      assigning it again will cause a copy, eg: s1 = s2 = "hi there".
//

inline void CAtsString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
{
	if(AllocBeforeWrite(nSrcLen))
	{
		memcpy(m_pchData, lpszSrcData, nSrcLen * sizeof(TCHAR));
		GetData()->nDataLength = nSrcLen;
		m_pchData[nSrcLen] = '\0';
	}
}

inline const CAtsString& CAtsString::operator=(const CAtsString& stringSrc)
{
	if (m_pchData != stringSrc.m_pchData)
	{
		if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || 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();
			ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
			m_pchData = stringSrc.m_pchData;
			InterlockedIncrement(&GetData()->nRefs);
		}
	}
	return *this;
}

inline const CAtsString& CAtsString::operator=(LPCTSTR lpsz)
{
	ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
	AssignCopy(SafeStrlen(lpsz), lpsz);
	return *this;
}

#ifdef _UNICODE
inline const CAtsString& CAtsString::operator=(LPCSTR lpsz)
{
	int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
	if(AllocBeforeWrite(nSrcLen))
	{
		_mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
		ReleaseBuffer();
	}
	return *this;
}
#else //!_UNICODE
inline const CAtsString& CAtsString::operator=(LPCWSTR lpsz)
{
	int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0;
	if(AllocBeforeWrite(nSrcLen * 2))
	{
		_wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
		ReleaseBuffer();
	}
	return *this;
}
#endif  //!_UNICODE

// Concatenation
// NOTE: "operator+" is done as friend functions for simplicity
//      There are three variants:
//          CAtsString + CAtsString
// and for ? = TCHAR, LPCTSTR
//          CAtsString + ?
//          ? + CAtsString

inline BOOL CAtsString::ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data,
	int nSrc2Len, LPCTSTR lpszSrc2Data)
{
  // -- master concatenation routine
  // Concatenate two sources
  // -- assume that 'this' is a new CAtsString object

	BOOL bRet = TRUE;
	int nNewLen = nSrc1Len + nSrc2Len;
	if (nNewLen != 0)
	{
		bRet = AllocBuffer(nNewLen);
		if (bRet)
		{
			memcpy(m_pchData, lpszSrc1Data, nSrc1Len * sizeof(TCHAR));
			memcpy(m_pchData + nSrc1Len, lpszSrc2Data, nSrc2Len * sizeof(TCHAR));
		}
	}
	return bRet;
}

inline CAtsString __stdcall operator+(const CAtsString& string1, const CAtsString& string2)
{
	CAtsString s;
	s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData);
	return s;
}

inline CAtsString __stdcall operator+(const CAtsString& string, LPCTSTR lpsz)
{
	ATLASSERT(lpsz == NULL || CAtsString::_IsValidString(lpsz));
	CAtsString s;
	s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, CAtsString::SafeStrlen(lpsz), lpsz);
	return s;
}

inline CAtsString __stdcall operator+(LPCTSTR lpsz, const CAtsString& string)
{
	ATLASSERT(lpsz == NULL || CAtsString::_IsValidString(lpsz));
	CAtsString s;
	s.ConcatCopy(CAtsString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength, string.m_pchData);
	return s;
}

inline void CAtsString::ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData)
{
	//  -- the main routine for += operators

	// concatenating an empty string is a no-op!
	if (nSrcLen == 0)
		return;

	// if the buffer is too small, or we have a width mis-match, just
	//   allocate a new buffer (slow but sure)
	if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
	{
		// we have to grow the buffer, use the ConcatCopy routine
		CAtsStringData* pOldData = GetData();
		if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData))
		{
			ATLASSERT(pOldData != NULL);
			CAtsString::Release(pOldData);
		}
	}
	else
	{
		// fast concatenation when buffer big enough
		memcpy(m_pchData + GetData()->nDataLength, lpszSrcData, nSrcLen * sizeof(TCHAR));
		GetData()->nDataLength += nSrcLen;
		ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
		m_pchData[GetData()->nDataLength] = '\0';
	}
}

inline const CAtsString& CAtsString::operator+=(LPCTSTR lpsz)
{
	ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
	ConcatInPlace(SafeStrlen(lpsz), lpsz);
	return *this;
}

inline const CAtsString& CAtsString::operator+=(TCHAR ch)
{
	ConcatInPlace(1, &ch);
	return *this;
}

inline const CAtsString& CAtsString::operator+=(const CAtsString& string)
{
	ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
	return *this;
}

inline LPTSTR CAtsString::GetBuffer(int nMinBufLength)
{
	ATLASSERT(nMinBufLength >= 0);

	if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
	{
		// we have to grow the buffer
		CAtsStringData* pOldData = GetData();
		int nOldLen = GetData()->nDataLength;   // AllocBuffer will tromp it
		if (nMinBufLength < nOldLen)
			nMinBufLength = nOldLen;

		if(!AllocBuffer(nMinBufLength))
			return NULL;

		memcpy(m_pchData, pOldData->data(), (nOldLen + 1) * sizeof(TCHAR));
		GetData()->nDataLength = nOldLen;
		CAtsString::Release(pOldData);
	}
	ATLASSERT(GetData()->nRefs <= 1);

	// return a pointer to the character storage for this string
	ATLASSERT(m_pchData != NULL);
	return m_pchData;
}

inline void CAtsString::ReleaseBuffer(int nNewLength)
{
	CopyBeforeWrite();  // just in case GetBuffer was not called

	if (nNewLength == -1)
		nNewLength = lstrlen(m_pchData); // zero terminated

	ATLASSERT(nNewLength <= GetData()->nAllocLength);
	GetData()->nDataLength = nNewLength;
	m_pchData[nNewLength] = '\0';
}

inline LPTSTR CAtsString::GetBufferSetLength(int nNewLength)
{
	ATLASSERT(nNewLength >= 0);

	if(GetBuffer(nNewLength) == NULL)
		return NULL;

	GetData()->nDataLength = nNewLength;
	m_pchData[nNewLength] = '\0';
	return m_pchData;
}

inline void CAtsString::FreeExtra()
{
	ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
	if (GetData()->nDataLength != GetData()->nAllocLength)
	{
		CAtsStringData* pOldData = GetData();
		if(AllocBuffer(GetData()->nDataLength))
		{
			memcpy(m_pchData, pOldData->data(), pOldData->nDataLength * sizeof(TCHAR));
			ATLASSERT(m_pchData[GetData()->nDataLength] == '\0');
			CAtsString::Release(pOldData);
		}
	}
	ATLASSERT(GetData() != NULL);
}

inline LPTSTR CAtsString::LockBuffer()
{
	LPTSTR lpsz = GetBuffer(0);
	if(lpsz != NULL)
		GetData()->nRefs = -1;
	return lpsz;
}

inline void CAtsString::UnlockBuffer()
{
	ATLASSERT(GetData()->nRefs == -1);
	if (GetData() != _atltmpDataNil)
		GetData()->nRefs = 1;
}

inline int CAtsString::Find(TCHAR ch) const
{
	return Find(ch, 0);
}

inline int CAtsString::Find(TCHAR ch, int nStart) const
{
	int nLength = GetData()->nDataLength;
	if (nStart >= nLength)
		return -1;

	// find first single character
	LPTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch);

	// return -1 if not found and index otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

inline int CAtsString::FindOneOf(LPCTSTR lpszCharSet) const
{
	ATLASSERT(_IsValidString(lpszCharSet));
	LPTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet);
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

inline void CAtsString::MakeUpper()
{
	CopyBeforeWrite();
	CharUpper(m_pchData);
}

inline void CAtsString::MakeLower()
{
	CopyBeforeWrite();
	CharLower(m_pchData);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -