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

📄 strclass.cpp

📁 墨香最新私服
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*===========================================================================
 *
 *	Copyright (C) 1997 Hicom Corporation.Ltd. All Rights Reserved.
 *
 *
 *	File   : strclass.cpp
 *	Content: String routine
 *	Program: Lee Jon suk
 *
 ****************************************************************************/
#include "stdafx.h"
//#include <windows.h>
#include <atlbase.h>
//#include <limits.h>
//#include <tchar.h>
#include "stdio.h"
#include "strclass.h"

/////////////////////////////////////////////////////////////////////////////
// static class data, special inlines

// For an empty string, m_???Data will point here
// (note: avoids a lot of NULL pointer tests when we call standard
//	C runtime libraries
TCHAR jazzidChNil = '\0';

// for creating empty key strings
const CStrClass jazzidEmptyString;

void CStrClass::Init()
{
	m_nDataLength = m_nAllocLength = 0;
	m_pchData = (LPTSTR)&jazzidChNil;
}

// declared static
void CStrClass::SafeDelete(LPTSTR lpch)
{
	if (lpch != (LPTSTR)&jazzidChNil)
		delete[] lpch;
}

//////////////////////////////////////////////////////////////////////////////
// Construction/Destruction

CStrClass::CStrClass()
{
	Init();
}

CStrClass::CStrClass(const CStrClass& stringSrc)
{
	// if constructing a CStrClass from another CStrClass, we make a copy of the
	// original string data to enforce value semantics (i.e. each string
	// gets a copy of its own

	stringSrc.AllocCopy(*this, stringSrc.m_nDataLength, 0, 0);
}

void CStrClass::AllocBuffer(int nLen)
 // always allocate one extra character for '\0' termination
 // assumes [optimistically] that data length will equal allocation length
{
	if (nLen == 0)
	{
		Init();
	}
	else
	{
		m_pchData = new TCHAR[nLen+1];		 // may throw an exception
		m_pchData[nLen] = '\0';
		m_nDataLength = nLen;
		m_nAllocLength = nLen;
	}
}

void CStrClass::Empty()
{
	SafeDelete(m_pchData);
	Init();
}

CStrClass::~CStrClass()
 //  free any attached data
{
	SafeDelete(m_pchData);
}

//////////////////////////////////////////////////////////////////////////////
// Helpers for the rest of the implementation

int SafeStrlen(LPCTSTR lpsz)
{
	return (lpsz == NULL) ? NULL : _tcslen(lpsz);
}

int CStrClass::GetLength() const
{
	return m_nDataLength;
}

void CStrClass::AllocCopy(CStrClass& 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
	{
		dest.AllocBuffer(nNewLen);
		memcpy(dest.m_pchData, &m_pchData[nCopyIndex], nCopyLen*sizeof(TCHAR));
	}
}

//////////////////////////////////////////////////////////////////////////////
// More sophisticated construction

CStrClass::CStrClass(LPCTSTR lpsz)
{
	int nLen;
	if ((nLen = SafeStrlen(lpsz)) == 0)
		Init();
	else
	{
		AllocBuffer(nLen);
		memcpy(m_pchData, lpsz, nLen*sizeof(TCHAR));
	}
}

/////////////////////////////////////////////////////////////////////////////
// Special conversion constructors

#ifdef _UNICODE
CStrClass::CStrClass(LPCSTR lpsz)
{
	int nSrcLen = lpsz != NULL ? lstrlenA(lpsz) : 0;
	if (nSrcLen == 0)
		Init();
	else
	{
		AllocBuffer(nSrcLen);
		_mbstowcsz_(m_pchData, lpsz, nSrcLen+1);
	}
}
#else //_UNICODE
CStrClass::CStrClass(LPCWSTR lpsz)
{
	int nSrcLen = lpsz != NULL ? wcslen(lpsz) : 0;
	if (nSrcLen == 0)
		Init();
	else
	{
		AllocBuffer(nSrcLen);
		_wcstombsz_(m_pchData, lpsz, nSrcLen+1);
	}
}
#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 CStrClass&' so that
//		assigning it again will cause a copy, eg: s1 = s2 = "hi there".
//

void CStrClass::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
{
	// check if it will fit
	if (nSrcLen > m_nAllocLength)
	{
		// it won't fit, allocate another one
		Empty();
		AllocBuffer(nSrcLen);
	}
	if (nSrcLen != 0)
		memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR));
	m_nDataLength = nSrcLen;
	m_pchData[nSrcLen] = '\0';
}

const CStrClass& CStrClass::operator=(const CStrClass& stringSrc)
{
	AssignCopy(stringSrc.m_nDataLength, stringSrc.m_pchData);
	return *this;
}

const CStrClass& CStrClass::operator=(LPCTSTR lpsz)
{
	AssignCopy(SafeStrlen(lpsz), lpsz);
	return *this;
}

/////////////////////////////////////////////////////////////////////////////
// Special conversion assignment

#ifdef _UNICODE
const CStrClass& CStrClass::operator=(LPCSTR lpsz)
{
	int nSrcLen = lpsz != NULL ? lstrlenA(lpsz) : 0;
	// check if it will fit
	if (nSrcLen > m_nAllocLength)
	{
		// it won't fit, allocate another one
		Empty();
		AllocBuffer(nSrcLen);
	}
	if (nSrcLen != 0)
		_mbstowcsz_(m_pchData, lpsz, nSrcLen+1);
	m_nDataLength = nSrcLen;
	m_pchData[nSrcLen] = '\0';
	return *this;
}
#else //!_UNICODE
const CStrClass& CStrClass::operator=(LPCWSTR lpsz)
{
	int nSrcLen = lpsz != NULL ? wcslen(lpsz) : 0;
	// check if it will fit
	if (nSrcLen > m_nAllocLength)
	{
		// it won't fit, allocate another one
		Empty();
		AllocBuffer(nSrcLen);
	}
	if (nSrcLen != 0)
		_wcstombsz_(m_pchData, lpsz, nSrcLen+1);
	m_nDataLength = nSrcLen;
	m_pchData[nSrcLen] = '\0';
	return *this;
}
#endif	//!_UNICODE

//////////////////////////////////////////////////////////////////////////////
// concatenation

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

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

	int nNewLen = nSrc1Len + nSrc2Len;
	AllocBuffer(nNewLen);
	memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(TCHAR));
	memcpy(&m_pchData[nSrc1Len], lpszSrc2Data, nSrc2Len*sizeof(TCHAR));
}

CStrClass __cdecl operator+(const CStrClass& string1, const CStrClass& string2)
{
	CStrClass s;
	s.ConcatCopy(string1.m_nDataLength, string1.m_pchData,
		string2.m_nDataLength, string2.m_pchData);
	return s;
}

CStrClass __cdecl operator+(const CStrClass& string, LPCTSTR lpsz)
{
	CStrClass s;
	s.ConcatCopy(string.m_nDataLength, string.m_pchData, SafeStrlen(lpsz), lpsz);
	return s;
}

CStrClass __cdecl operator+(LPCTSTR lpsz, const CStrClass& string)
{
	CStrClass s;
	s.ConcatCopy(SafeStrlen(lpsz), lpsz, string.m_nDataLength, string.m_pchData);
	return s;
}

//////////////////////////////////////////////////////////////////////////////
// concatenate in place

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

	// if the buffer is too small, or we have a width mis-match, just
	//	 allocate a new buffer (slow but sure)
	if (m_nDataLength + nSrcLen > m_nAllocLength)
	{
		// we have to grow the buffer, use the Concat in place routine
		LPTSTR lpszOldData = m_pchData;
		ConcatCopy(m_nDataLength, lpszOldData, nSrcLen, lpszSrcData);
		SafeDelete(lpszOldData);
	}
	else
	{
		// fast concatenation when buffer big enough
		memcpy(&m_pchData[m_nDataLength], lpszSrcData, nSrcLen*sizeof(TCHAR));
		m_nDataLength += nSrcLen;
	}
	m_pchData[m_nDataLength] = '\0';
}

const CStrClass& CStrClass::operator+=(LPCTSTR lpsz)
{
	ConcatInPlace(SafeStrlen(lpsz), lpsz);
	return *this;
}

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

const CStrClass& CStrClass::operator+=(const CStrClass& string)
{
	ConcatInPlace(string.m_nDataLength, string.m_pchData);
	return *this;
}

///////////////////////////////////////////////////////////////////////////////
// Advanced direct buffer access

LPTSTR CStrClass::GetBuffer(int nMinBufLength)
{
	if (nMinBufLength > m_nAllocLength)
	{
		// we have to grow the buffer
		LPTSTR lpszOldData = m_pchData;
		int nOldLen = m_nDataLength;		// AllocBuffer will tromp it

		AllocBuffer(nMinBufLength);
		memcpy(m_pchData, lpszOldData, nOldLen*sizeof(TCHAR));
		m_nDataLength = nOldLen;
		m_pchData[m_nDataLength] = '\0';	

		SafeDelete(lpszOldData);
	}

	// return a pointer to the character storage for this string
	return m_pchData;
}

void CStrClass::ReleaseBuffer(int nNewLength)
{
	if (nNewLength == -1)
		nNewLength = lstrlen(m_pchData); // zero terminated

	m_nDataLength = nNewLength;
	m_pchData[m_nDataLength] = '\0';
}

LPTSTR CStrClass::GetBufferSetLength(int nNewLength)
{

	GetBuffer(nNewLength);
	m_nDataLength = nNewLength;
	m_pchData[m_nDataLength] = '\0';
	return m_pchData;
}

void CStrClass::FreeExtra()
{
	if (m_nDataLength != m_nAllocLength)
	{
		LPTSTR lpszOldData = m_pchData;
		AllocBuffer(m_nDataLength);
		memcpy(m_pchData, lpszOldData, m_nDataLength*sizeof(TCHAR));
		SafeDelete(lpszOldData);
	}
}

///////////////////////////////////////////////////////////////////////////////
// Commonly used routines (rarely used routines in STREX.CPP)

int CStrClass::Find(TCHAR ch) const
{
	// find first single character
	LPTSTR lpsz = _tcschr(m_pchData, ch);

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

int CStrClass::FindOneOf(LPCTSTR lpszCharSet) const
{
	LPTSTR lpsz = _tcspbrk(m_pchData, lpszCharSet);
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

///////////////////////////////////////////////////////////////////////////////
// CStrClass conversion helpers (these use the current system locale)

int _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, count, NULL, NULL);
	if (result > 0)
		mbstr[result-1] = 0;
	return result;
}

int _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, count);
	if (result > 0)
		wcstr[result-1] = 0;
	return result;
}

//////////////////////////////////////////////////////////////////////////////
// More sophisticated construction

CStrClass::CStrClass(TCHAR ch, int nLength)
{
	if (nLength < 1)
	{
		// return empty string if invalid repeat count
		Init();
	}
	else
	{
		AllocBuffer(nLength);
#ifdef _UNICODE

⌨️ 快捷键说明

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