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

📄 string.cpp

📁 一个更为先进的嵌入式操作系统.采用RMS线程调度算法,具有信号量等同步对象.亦包括GUI. 通过该系统您可以极大知道Windows的内部秘密.
💻 CPP
字号:
#include "GOS.h"
#include "String.h"

#define SF_START		0x010000
#define SF_LEFT			0x020000
#define SF_PSIGN		0x040000
#define SF_PREC			0x080000
#define SF_PRECMASK		0x000f00
#define SF_WIDTHMASK	0x00f000
#define SF_PRECSHIFT	8
#define SF_WIDTHSHIFT	12

#define SB_ALLOC(nLen) m_pData=(LPTSTR)realloc(m_pData,((nLen)+1)*sizeof(TCHAR))

#define SB_INIT() \
	int nSBLen=0; \
	CPlex *pSBBlock; \
	LPTSTR pSBCur,pSBEnd; \
	BYTE SBblock0[sizeof(CPlex)+sizeof(TCHAR)*StrBufGrowSize]; \
	pSBBlock=(CPlex*)SBblock0; \
	pSBBlock->m_pNext=NULL; \
	pSBCur=(LPTSTR)pSBBlock->data(); \
	pSBEnd=pSBCur+StrBufGrowSize;

#define SB_ADDCHAR(ch) \
	if(pSBCur>=pSBEnd) \
	{ \
		pSBCur=(LPTSTR)CPlex::CreateTail(pSBBlock,sizeof(TCHAR)*StrBufGrowSize); \
		pSBEnd=pSBCur+StrBufGrowSize; \
	} \
	*pSBCur++=ch;nSBLen++;

#define SB_UNLOAD() \
	pSBBlock=((CPlex*)SBblock0)->m_pNext; \
	pSBBlock->FreeDataChain(); 
#define SB_RELEASE(pOut) \
	free(pOut);pOut=(LPTSTR)malloc(nSBLen*sizeof(TCHAR)); \
	pSBEnd=pOut;pSBBlock=(CPlex*)SBblock0; \
	for(;;) \
	{ \
		pSBCur=(LPTSTR)pSBBlock->data(); \
		if(nSBLen>StrBufGrowSize)CopyMemory(pSBEnd,pSBCur,StrBufGrowSize); \
		else{CopyMemory(pSBEnd,pSBCur,nSBLen);break;} \
		pSBEnd+=StrBufGrowSize; \
		pSBBlock=pSBBlock->m_pNext; \
		nSBLen-=StrBufGrowSize; \
	} \
	SB_UNLOAD();

CString::CString(LPCTSTR psz)
{
	m_pData=NULL;
	StrCpyN(psz,StrLen(psz));
}

CString::CString(const CString& str)
{
	m_pData=NULL;
	StrCpyN(str.m_pData,str.GetLength());
}

CString::~CString()
{
	free(m_pData);
}

int CString::StrLen(LPCTSTR psz)
{
	if(psz)
	{
		LPTSTR s=(LPTSTR)psz;
		while(*s)
			s++;
		return s-psz;
	}
	return 0;
}

int CString::StrLenEx(LPCTSTR psz)
{
	int nLen;
	if(IsWritablePtr(psz))
		nLen=AllocSize(psz)/sizeof(TCHAR)-1;
	else 
		nLen=StrLen(LPTSTR(psz));
	return nLen;
}

LPCTSTR CString::StrAllocEx(LPCTSTR psz)
{
	if(IsWritablePtr(psz))
	{
		PVOID pData;
		int nBytes=(strlen(psz)+1)*sizeof(TCHAR);
		pData=malloc(nBytes);
		CopyMemory(pData,psz,nBytes);
		return LPCTSTR(pData);
	}
	return psz;
}

LPCTSTR CString::StrReAllocEx(LPCTSTR pszOld,LPCTSTR pszNew,int nCount)
{
	PVOID pData=PVOID(pszOld);
	if(nCount>0)
	{
		nCount++;
		nCount*=sizeof(TCHAR);
		if(IsWritablePtr(pData))
			pData=realloc(pData,nCount);
		else
			pData=malloc(nCount);
		CopyMemory(pData,pszNew,nCount);
	}
	else
	{
		if(IsWritablePtr(pData))
			free(pData);
		pData=PVOID(pszNew);
	}
	return LPCTSTR(pData);
}

void CString::StrFreeEx(LPCTSTR psz)
{
	if(IsWritablePtr(psz))
		free(PVOID(psz));
}

void CString::StrCpyN(LPCTSTR psz,int nCount)
{
	LPTSTR pData=m_pData;
	if(!psz || nCount<=0)
	{
		free(pData);
		m_pData=NULL;
	}
	else if(psz+nCount<pData || DWORD(psz)>DWORD(pData)+_msize(pData))
	{
		pData=(LPTSTR)realloc(pData,(nCount+1)*sizeof(TCHAR));
		CopyMemory(pData,psz,nCount);
		pData[nCount]=0;
		m_pData=pData;
	}
	else
	{
		pData=(LPTSTR)malloc((nCount+1)*sizeof(TCHAR));
		CopyMemory(pData,psz,nCount+1);
		free(m_pData);
		pData[nCount]=0;
		m_pData=pData;
	}
}

void CString::StrCatN(LPCTSTR psz, int nCount)
{
	LPTSTR pData=m_pData;
	int nSize=GetLength();
	SB_ALLOC(nSize+nCount);
	if(psz>=pData && psz<=pData+nSize)
		psz+=m_pData-pData;
	CopyMemory(pData+nSize,psz,nCount);
	m_pData[nSize+nCount]=0;
}

int CString::Compare(LPCTSTR psz,int nCount)
{
	TCHAR c1,c2;
	int r=0;
	LPTSTR s1=m_pData;
	LPTSTR s2=(LPTSTR)psz;
	if(!psz)
		r=m_pData?1:0;
	else if(!m_pData)
		r=-1;
	else if(nCount>0)
	{
		do
		{
			c1=*s1++;c2=*s2++;
			if(c1>c2)
			{
				r=1;
				break;
			}
			if(c1<c2)
			{
				r=-1;
				break;
			}
		}while(--nCount && c1 && c2);
	}
	else if(nCount<0)
	{
		nCount=-nCount;
		do
		{
			c1=*s1++;c2=*s2++;
			c1=c1>='a' && c1<='z'?c1-'a'+'A':c1;
			c2=c2>='a' && c1<='z'?c2-'a'+'A':c2;
			if(c1>c2)
			{
				r=1;
				break;
			}
			if(c1<c2)
			{
				r=-1;
				break;
			}
		}while(--nCount && c1 && c2);
	}
	return r;
}

void CString::Left(CString& strOut,int nCount)
{
	ASSERT(nCount>=0);
	ASSERT(nCount<=GetLength());
	strOut.StrCpyN(m_pData,nCount);
}

void CString::Right(CString& strOut,int nCount)
{
	ASSERT(nCount>=0);
	ASSERT(nCount<=GetLength());
	int nLen=GetLength();
	strOut.StrCpyN(m_pData+nLen-nCount,nCount);
}

void CString::Mid(CString& strOut,int nFirst)
{
	ASSERT(nFirst>=0);
	ASSERT(nFirst<=GetLength());
	int nCount=GetLength()-nFirst;
	strOut.StrCpyN(m_pData+nFirst,nCount);
}

void CString::Mid(CString& strOut,int nFirst, int nCount)
{
	ASSERT(nFirst>=0);
	ASSERT(nFirst<=GetLength());
	ASSERT(nCount>=0);
	ASSERT(nFirst+nCount<=GetLength());
	strOut.StrCpyN(m_pData+nFirst,nCount);
}

int CString::Find(LPCTSTR psz,int nStart)
{
	ASSERT(nStart>=0);
	ASSERT(nStart<=GetLength());
	LPTSTR s1,s2,str=m_pData+nStart;
	while(*str)
	{
		s1=str;
		s2=(LPTSTR)psz;
		while(*s1 && *s2 && *s1==*s2)
		{
			s1++;
			s2++;
		}
		if(!(*s2))
			return str-m_pData;
		str++;
	}
	return -1;
}

int CString::Find(TCHAR ch,int nStart)
{
	ASSERT(nStart>=0);
	ASSERT(nStart<=GetLength());
	LPTSTR s=m_pData+nStart;
	while(*s)
	{
		if(*s==ch)
			return s-m_pData;
		s++;
	}
	return -1;
}

int CString::ReverseFind(TCHAR ch)
{
	LPTSTR s=m_pData+GetLength();
	while(*(--s))
	{
		if(*s==ch)
			return s-m_pData;
	}
	return -1;
}

int CString::FindOneOf(LPCTSTR pszCharSet)
{
	TCHAR c;
	LPTSTR s2,str=m_pData;
	while(*str)
	{
		c=*str++;
		s2=(LPTSTR)pszCharSet;
		while(*s2)
		{
			if(*s2==c)
				return str-m_pData-1;
			s2++;
		}
	}
	return -1;
}

void CString::MakeUpper()
{
	LPTSTR s;
	for(s=m_pData;*s;s++)
	{
		if(*s>='a' && *s<='z')
			*s-='a'-'A';
	}
}

void CString::MakeLower()
{
	LPTSTR s;
	for(s=m_pData;*s;s++)
	{
		if(*s>='A' && *s<='Z')
			*s+='a'-'A';
	}
}

int CString::Replace(TCHAR chOld, TCHAR chNew)
{
	LPTSTR s;
	int nCount=0;
	for(s=m_pData;*s;s++)
	{
		if(*s==chOld)
		{
			nCount++;
			*s=chNew;
		}
	}
	return nCount;
}

int CString::Replace(LPCTSTR pszOld, LPCTSTR pszNew)
{
	ASSERT(pszOld);
	int nAT,nAT0=0;
	int i,nCount=0;
	int nOldLen=StrLen(pszOld);
	int nNewLen=StrLen(pszNew);
	LPTSTR s,pTmp,pData;

	if(nOldLen<nNewLen)
	{
		SB_INIT();
		pData=m_pData;
		while((nAT=Find(pszOld,nAT0))!=-1)
		{
			nCount++;
			for(i=nAT0,pTmp=pData+i;i<nAT;i++)
			{
				SB_ADDCHAR(*pTmp++);
			}
			nAT0=nAT+nOldLen;
			for(i=0,pTmp=LPTSTR(pszNew);i<nNewLen;i++)
			{
				SB_ADDCHAR(*pTmp++);
			}
		}
		if(nCount>0)
		{
			nAT=GetLength();
			for(i=nAT0,pTmp=pData+i;i<=nAT;i++)
			{
				SB_ADDCHAR(*pTmp++);
			}
			SB_RELEASE(m_pData);
		}
		else
		{
			SB_UNLOAD();
		}
	}
	else
	{
		s=pData=m_pData;
		while((nAT=Find(pszOld,nAT0))!=-1)
		{
			nCount++;
			for(i=nAT0,pTmp=pData+i;i<nAT;i++)
				*s++=*pTmp++;
			nAT0=nAT+nOldLen;
			for(i=0,pTmp=LPTSTR(pszNew);i<nNewLen;i++)
				*s++=*pTmp++;
		}
		if(nCount>0)
		{
			nAT=GetLength();
			for(i=nAT0,pTmp=pData+i;i<=nAT;i++)
				*s++=*pTmp++;
			SB_ALLOC(s-pData);
		}
	}
	return nCount;
}

void CString::TrimRight(LPCTSTR pszTarget)
{
	TCHAR c;
	LPTSTR s2,str=m_pData+GetLength();
	while(str>m_pData)
	{
		c=*(--str);
		s2=(LPTSTR)pszTarget;
		while(*s2 && *s2!=c)
		{
			s2++;
		}
		if(!*s2)
		{
			*(++str)=0;
			SB_ALLOC(str-m_pData);
			break;
		}
	}
}

void CString::TrimLeft(LPCTSTR pszTarget)
{
	LPTSTR s2,str=m_pData;
	while(*str)
	{
		s2=(LPTSTR)pszTarget;
		while(*s2 && *s2!=*str)
		{
			s2++;
		}
		if(!*s2)
		{
			s2=m_pData;
			do
			{
				*s2++=*str++;
			}while(*str);
			*s2=0;
			SB_ALLOC(s2-m_pData);
			break;
		}
		str++;
	}
}

LPTSTR CString::GetBuffer(int nMinBufLength)
{
	if(nMinBufLength>-1)
		SB_ALLOC(nMinBufLength);
	return m_pData;
}

void CString::ReleaseBuffer(int nNewLength)
{
	if(nNewLength>-1)
	{
		SB_ALLOC(nNewLength);
		m_pData[nNewLength]=0;
	}
	else
		SB_ALLOC(StrLen(m_pData));
}

int CString::toInt()
{
	TCHAR c;
	LPTSTR s=m_pData;
	int nSign=0;
	int nValue=0;
	while(*s)
	{
		c=*s++;
		if(c>='0' && c<='9')
		{
			nValue*=10;
			nValue+=c-'0';
		}
		else if(c=='-')
		{
			if(nSign)
				break;
			else
			{
				nSign=-1;
				continue;
			}
		}
		else if(c=='+')
		{
			if(nSign)
				break;
			else
			{
				nSign=1;
				continue;
			}
		}
		else break;
	}
	return nSign<0?-nValue:nValue;
}

int CString::toHex()
{
	TCHAR c;
	int nSign=1;
	int nBase,nValue=0;
	LPTSTR s=m_pData;
	while(*s)
	{
		c=*s++;
		if(c>='0' && c<='9')
			nBase=c-48;
		else if(c>='a' && c<='f')
			nBase=c-87;
		else if(c>='A' && c<='F')
			nBase=c-55;
		else if(c=='-')
		{
			nSign=-1;
			continue;
		}
		else continue;
		nValue<<=4;
		nValue+=nBase;
	}
	return nSign<0?-nValue:nValue;
}

double CString::toDouble()
{
	TCHAR c;
	LPTSTR s=m_pData;
	int nSign=0;
	int nFloat=0;
	double dValue=0;
	while(*s)
	{
		c=*s++;
		if(c>='0' && c<='9')
		{
			dValue*=10;
			dValue+=c-'0';
			if(nFloat)
				nFloat*=10;
		}
		else if(c=='.')
		{
			if(nFloat)
				break;
			else
			{
				nFloat=1;
				if(!nSign)
					nSign=1;
				continue;
			}
		}
		else if(c=='-')
		{
			if(nSign)
				break;
			else
			{
				nSign=-1;
				continue;
			}
		}
		else if(c=='+')
		{
			if(nSign)
				break;
			else
			{
				nSign=1;
				continue;
			}
		}
		else break;
	}
	dValue=nFloat>0?dValue/nFloat:dValue;
	return nSign<0?-dValue:dValue;
}

int CString::fmtInt(TCHAR aBuf[], int nValue,int nSign)
{
	TCHAR nBase;
	int j,i=0;
	int nVal=nValue;
	if(nValue)
	{
		nVal=(nVal<0)?-nVal:nVal;
		do
		{
			nBase=(TCHAR)(nVal%10);
			aBuf[i]=nBase+48;
			nVal/=10;
			i++;
		}while(nVal);
		if(nValue>0 && nSign>1)
			aBuf[i++]='+';
		if(nValue<0 && nSign>0)
			aBuf[i++]='-';
		for(j=(i-1)/2;j>=0;j--)
		{
			nBase=aBuf[j];
			aBuf[j]=aBuf[i-j-1];
			aBuf[i-j-1]=nBase;
		}
	}
	else
		aBuf[i++]='0';
	return i;
}

int CString::fmtHex(TCHAR aBuf[], int nValue,BOOL bUpper)
{
	TCHAR nBase;
	int j,i=0;
	UINT nVal=(UINT)nValue;
	if(nValue)
	{
		do
		{
			nBase=(TCHAR)(nVal & 0xf);
			if(nBase<10)
				aBuf[i]=nBase+48;
			else if(bUpper)
				aBuf[i]=nBase+55;
			else
				aBuf[i]=nBase+87;
			nVal>>=4;
			i++;
		}while(nVal);
		for(j=(i-1)/2;j>=0;j--)
		{
			nBase=aBuf[j];
			aBuf[j]=aBuf[i-j-1];
			aBuf[i-j-1]=nBase;
		}
	}
	else
		aBuf[i++]='0';
	return i;
}

int CString::fmtDouble(TCHAR aBuf[], double dValue,int nPrec,int nSign)
{
	TCHAR nBase;
	int k,j,i=0;

	if(dValue>0)
	{
		if(nSign>1)
			aBuf[i++]='+';
	}
	else if(dValue<0)
	{
		dValue=-dValue;
		if(nSign>0)
			aBuf[i++]='-';
	}
	j=(int)(nPrec?dValue:dValue+0.5);
	dValue-=j;
	i+=fmtInt(aBuf+i,j,0);
	j=(nPrec<0)?-nPrec-i-1:nPrec;
	if(j>0 && (nPrec>0 || dValue>0))
	{
		k=2;
		for(nBase=0;nBase<j;nBase++)
			k*=10;
		dValue+=1.0/k;
		aBuf[i++]='.';
		do
		{
			dValue*=10;
			nBase=(TCHAR)dValue;
			dValue-=nBase;
			if(dValue>0.9999999999)
			{
				dValue=0;
				nBase+=1;
			}
			aBuf[i]=nBase+48;
			i++;
			if(nPrec<0 && dValue==0)
				break;
		}while(--j);
	}
	return i;
}

void CString::Format(LPCTSTR pszFormat, ...)
{
	LPTSTR str,szFmt;
	TCHAR c,aFmt[64];
	int i,nCnt,nStyle=0;
	int* pVar;
	SB_INIT();

	szFmt=(LPTSTR)pszFormat;
	pVar=(int*)(&pszFormat+1);

	for(c=*szFmt;c;szFmt++,c=*szFmt)
	{
		if(nStyle & SF_START)
		{
			switch(c)
			{
			case 'c': //字符
			case 'C':
				SB_ADDCHAR(*pVar++);
				nStyle &= ~ SF_START;
				break;
			case 'd': //小数
			case 'i': //小数
			case 'u': //无符号
			case 'o': //八进制
			case 'x': //16进制小写
			case 'X': //16进制大写
			case 'n': //地址
			case 'p': //地址
				if(c=='x' || c=='o')
					nCnt=fmtHex(aFmt,*pVar++,FALSE);
				else if(c=='X')
					nCnt=fmtHex(aFmt,*pVar++,TRUE);
				else
					nCnt=fmtInt(aFmt,*pVar++,(nStyle & SF_PSIGN)?2:1);
				if(nStyle & SF_LEFT)
					for(i=0;i<nCnt;i++)
						{ SB_ADDCHAR(aFmt[i]); }
				i=(nStyle & SF_WIDTHMASK)>>SF_WIDTHSHIFT;
				c=(TCHAR)nStyle;c=c?c:' ';
				for(;i>nCnt;i--)
					{ SB_ADDCHAR(c); }
				if(!(nStyle & SF_LEFT))
					for(i=0;i<nCnt;i++)
						{ SB_ADDCHAR(aFmt[i]); }
				nStyle &= ~ SF_START;
				break;
			case 'e': //指数格式
			case 'E': //指数格式
			case 'f': //浮点格式
			case 'g': //常用格式
			case 'G': //常用标准格式
				if(c=='g' || c=='G')
				{
					i=(nStyle & SF_WIDTHMASK)>>SF_WIDTHSHIFT;
					i=i>0?-i:-6;
				}
				else
				{
					i=(nStyle & SF_PRECMASK)>>SF_PRECSHIFT;
					i=i>0?i:4;
				}
				nCnt=fmtDouble(aFmt,*(double*)pVar,
					i,(nStyle & SF_PSIGN)?2:1);
				pVar+=2;
				if(nStyle & SF_LEFT)
					for(i=0;i<nCnt;i++)
						{ SB_ADDCHAR(aFmt[i]); }
				i=(nStyle & SF_WIDTHMASK)>>SF_WIDTHSHIFT;
				if(c=='g' || c=='G')i=0;
				c=(TCHAR)nStyle;c=c?c:' ';
				for(;i>nCnt;i--)
					{ SB_ADDCHAR(c); }
				if(!(nStyle & SF_LEFT))
					for(i=0;i<nCnt;i++)
						{ SB_ADDCHAR(aFmt[i]); }
				nStyle &= ~ SF_START;
				break;
			case 's':
			case 'S':
				str=(LPTSTR)(*pVar++);
				while(*str)
					{ SB_ADDCHAR(*str++); }
				nStyle &= ~ SF_START;
				break;
			case '-': //数字左齐
				nStyle|= SF_LEFT;
				break;
			case '+': //启用+-符号
				nStyle |= SF_PSIGN; 
				break;
			case '.': //后面的数字是小数位宽度
				nStyle |= SF_PREC;
				break;
			case '%': //%的替用符号
				SB_ADDCHAR(c);
				nStyle &= ~ SF_START;
				break;
				break;
			case '0': //数字右齐时左边空白填0
			case '#': //数字右齐时左边空白填#
			case '$': //数字右齐时左边空白填$
				if(!(nStyle & 0xff))
				{
					nStyle &=~0xff;
					nStyle|=c;
					break;
				}
			default:
				if(c>='0' && c<='9')
				{
					if(!(nStyle & 0xff))nStyle &=~0xff;nStyle|=' ';
					if(nStyle & SF_PREC)//小数位精度
					{
						i=(nStyle & SF_PRECMASK)>>SF_PRECSHIFT;
						i=i*10+(c-'0');
						nStyle &=~SF_PRECMASK;
						nStyle |=i<<SF_PRECSHIFT;
					}
					else //总宽度
					{
						
						i=(nStyle & SF_WIDTHMASK)>>SF_WIDTHSHIFT;
						i=i*10+(c-'0');
						nStyle &=~SF_WIDTHMASK;
						nStyle |=i<<SF_WIDTHSHIFT;
					}
				}
			}
		}
		else if(c=='%')
				nStyle=SF_START;
		else
			{ SB_ADDCHAR(c); }
	}
	SB_ADDCHAR(0);
	SB_RELEASE(m_pData);
}

⌨️ 快捷键说明

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