#include "StdAfx.h"
#include "StackString.h"

CStackString::CStackString(void)
{
	m_strBuffer = m_stackBuf;
	m_strLen = 0;
}

CStackString::CStackString(const CStackString &other)
{
	m_strBuffer = m_stackBuf;
	m_strLen = 0;

	*this = other;
}

CStackString::CStackString(const CString &other)
{
	m_strBuffer = m_stackBuf;
	m_strLen = 0;

	*this = other;
}

CStackString::CStackString(const LPSTR other)
{
	m_strBuffer = m_stackBuf;
	m_strLen = 0;

	*this = other;
}

CStackString::~CStackString(void)
{
}

//////////////////////////////////////////////////////////////////////////////////////////
//	コピー
//////////////////////////////////////////////////////////////////////////////////////////
//!	CStackString
void CStackString::operator=(const CStackString &_other)
{
	CStackString &other = const_cast<CStackString&>(_other);
	Copy(other, other.GetLength());
}

//!	CString
void CStackString::operator=(const CString &_other)
{
	CString &other = const_cast<CString&>(_other);
	Copy(other, other.GetLength());
}

//!	LPCSTR
void CStackString::operator=(LPCSTR other)
{
	Copy(other, strlen(other));
}

//!	char
void CStackString::operator=(LPSTR other)
{
	Copy(other, strlen(other));
}

//////////////////////////////////////////////////////////////////////////////////////////
//	追加
//////////////////////////////////////////////////////////////////////////////////////////
//!	CStackString
CStackString CStackString::operator+(const CStackString &_other)
{
	CStackString	ret(*this);

	CStackString &other = const_cast<CStackString&>(_other);
	ret.Append(other, other.GetLength());
	
	return ret;
}

//!	CString
CStackString CStackString::operator+(const CString &_other)
{
	CStackString	ret(*this);

	CString &other = const_cast<CString&>(_other);
	ret.Append(other, other.GetLength());

	return ret;
}

//!	LPCSTR
CStackString CStackString::operator+(LPCSTR other)
{
	CStackString	ret(*this);

	ret.Append(other, strlen(other));

	return ret;
}

//!	LPCSTR
CStackString CStackString::operator+(LPSTR other)
{
	CStackString	ret(*this);

	ret.Append(other, strlen(other));

	return ret;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	追加(自分に)
//////////////////////////////////////////////////////////////////////////////////////////
//!	CStackString
void CStackString::operator+=(const CStackString &_other)
{
	CStackString &other = const_cast<CStackString&>(_other);
	Append(other, other.GetLength());
}

//!	CString
void CStackString::operator+=(const CString &_other)
{
	CString &other = const_cast<CString&>(_other);
	Append(other, other.GetLength());
}

//!	LPCSTR
void CStackString::operator+=(const LPCSTR other)
{
	Append(other, strlen(other));
}

//!	LPCSTR
void CStackString::operator+=(LPSTR other)
{
	Append(other, strlen(other));
}


//////////////////////////////////////////////////////////////////////////////////////////
//	比較
//////////////////////////////////////////////////////////////////////////////////////////
//!	CStackString
int CStackString::operator==(const CStackString &_other)
{
	CStackString &other = const_cast<CStackString&>(_other);
	if(_mbscmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)) == 0)
		return(TRUE);
	return(FALSE);
}

//!	CString
int CStackString::operator==(const CString &_other)
{
	CString &other = const_cast<CString&>(_other);
	if(_mbscmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)) == 0)
		return(TRUE);
	return(FALSE);
}

//!	LPCSTR
int CStackString::operator==(LPCSTR other)
{
	if(_mbscmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)) == 0)
		return(TRUE);
	return(FALSE);
}

//!	LPCSTR
int CStackString::operator==(LPSTR other)
{
	if(_mbscmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)) == 0)
		return(TRUE);
	return(FALSE);
}

//!	普通に比較
int CStackString::Compare(const CStackString &_other)
{
	CStackString &other = const_cast<CStackString&>(_other);
	return(_mbscmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)));
}

//!	比較
int CStackString::CompareNoCase(const CStackString &_other)
{
	CStackString &other = const_cast<CStackString&>(_other);
	return(_mbsicmp((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)other)));
}

//////////////////////////////////////////////////////////////////////////////////////////
//	削除
//////////////////////////////////////////////////////////////////////////////////////////
//!	削除
CStackString CStackString::Delete(int index, int count)
{
	if(index < 0)
		index = 0;
	if(index >= GetLength())
		return *this;
	if(index + count > GetLength())
		count = GetLength() - index;

	if(m_strLen - (index + count) > 0)
		memmove(m_strBuffer + index, m_strBuffer + index + count, m_strLen - (index + count));
	ReSize(m_strLen - count);
	
	return *this;
}



//////////////////////////////////////////////////////////////////////////////////////////
//	Trim
//////////////////////////////////////////////////////////////////////////////////////////
//!	右を削除
CStackString &CStackString::TrimLeft()
{
	int i;
	for(i=m_strLen-1; i>=0; i--)
	{
		if(!_ismbcspace(m_strBuffer[i]))
			break;
	}

	if(i != m_strLen - 1)
		Delete(i, m_strLen - i);

	return *this;
}

//!	左を削除
CStackString &CStackString::TrimRight()
{
	int i;
	for(i=0; i<m_strLen; i++)
	{
		if(!_ismbcspace(m_strBuffer[i]))
			break;
	}

	if(i != 0)
		Delete(0, i);

	return *this;
}


//////////////////////////////////////////////////////////////////////////////////////////
//	Left, Right
//////////////////////////////////////////////////////////////////////////////////////////
//!	右を削除
CStackString CStackString::Right(int count)
{
	if(count > m_strLen)
		count = m_strLen;

	CStackString	ret;

	ret.Append(m_strBuffer + (m_strLen - count), count);

	return ret;
}

//!	左を削除
CStackString CStackString::Left(int count)
{
	if(count > m_strLen)
		count = m_strLen;

	CStackString	ret;

	ret.Append(m_strBuffer, count);

	return ret;
}

/*!
	指定位置を取得
*/
CStackString CStackString::Mid(int index, int count)
{
	if(count < 0)
		count = m_strLen;
	if(index < 0)
		index = 0;
	if(index > m_strLen)
		return *this;
	if(index + count > m_strLen)
		count = m_strLen - index;

	CStackString	ret;
	ret.Append(m_strBuffer + index, count);
	return(ret);
}



//////////////////////////////////////////////////////////////////////////////////////////
//	検索
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	検索
*/
int CStackString::Find(LPSTR find, int start)
{
	unsigned char* ptr = _mbsstr((unsigned char*)m_strBuffer, (unsigned char*)((LPCSTR)find));
	if(ptr == NULL)
		return(-1);
	return(ptr - (unsigned char*)m_strBuffer);
}


/*!
	置き換え
*/
int CStackString::Replace(LPSTR oldTok, LPSTR newTok)
{
	CStackString	ret;

	int index = 0, count=0, tokLen = strlen(oldTok);
	while(1)
	{
		int oldIndex = index;
		index = Find(oldTok, index);
		if(index == -1)
		{
			ret.Append(m_strBuffer + oldIndex, m_strLen - oldIndex);
			*this = ret;
			return count;
		}

		count++;
		ret.Append(m_strBuffer + oldIndex, index - oldIndex);
		ret += newTok;
		index += tokLen;
	}
}


//////////////////////////////////////////////////////////////////////////////////////////
//	補助
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	メモリ確保
*/
void CStackString::ReSize(int size)
{
	if(size < STACK_MEMORY_SIEZ && m_strBuffer == m_stackBuf)
	{
		m_strLen = size;
	}
	else
	{
		//	ヒープに確保
		if(m_strBuffer == m_stackBuf)
			m_heapBuf.Append(m_strBuffer, m_strLen);

		m_heapBuf.ReSize(size + 1);
		m_strLen = size;
		m_strBuffer = m_heapBuf.GetPtr();
	}
	m_strBuffer[size] = 0;
}


/*!
	内部コピー
*/
void CStackString::Copy(LPCSTR src, int len)
{
	ReSize(len);

	//	コピー
	memcpy(m_strBuffer, src, len + 1);
}


/*!
	追加
*/
void CStackString::Append(LPCSTR src, int len)
{
	int	oldLen = m_strLen;
	ReSize(m_strLen + len); 

	//	コピー
	memcpy(m_strBuffer + oldLen, src, len + 1);
}
