/*!
	テキスト置き換えクラス
	基本的に、XML/HTMLタグ削除用
*/
#include "StdAfx.h"
#include "TextEscape.h"

///////////////////////////////////////////////////////////////////////////
//	エスケープトークン追加
///////////////////////////////////////////////////////////////////////////
/*!
	追加
*/
void CTextEscape::AddEscape(CUTF8String token, CUTF8String escape)
{
	m_escape.Add(CTextEscapeItem(token, escape));
	m_unescape.Add(CTextEscapeItem(escape, token));
}

/*!
	クリア
*/
void CTextEscape::Clear()
{
	m_escape.RemoveAll();
	m_unescape.RemoveAll();
}


///////////////////////////////////////////////////////////////////////////
//	文字列のエスケープ
///////////////////////////////////////////////////////////////////////////
/*!
	エスケープの実行
*/
LPCU8STR CTextEscape::Escape(LPCU8STR src)
{
	return(Escape(src, m_escape));
}


/*!
	エスケープの解除
*/
LPCU8STR CTextEscape::UnEscape(LPCU8STR src)
{
	return(Escape(src, m_unescape));
}

/*!
	エスケープの実行
*/
CUTF8String CTextEscape::Escape(CUTF8String src)
{
	return(Escape((LPCU8STR)src));
}

/*!
	エスケープの解除
*/
CUTF8String CTextEscape::UnEscape(CUTF8String src)
{
	return(UnEscape((LPCU8STR)src));
}


///////////////////////////////////////////////////////////////////////////
//	補助
///////////////////////////////////////////////////////////////////////////
/*!
	エスケープの実行
*/
LPCU8STR CTextEscape::Escape(LPCU8STR src, CSimpleArrayTemplate<CTextEscapeItem> &items)
{
	//	中身掃除
	m_destBuf.SetNoFreeEmpty(TRUE);
	m_destBuf.Empty();

	while(1)
	{
		int	findIndex;
		int itemIndex = MultiFind(findIndex, src, items);

		if(itemIndex != -1)
		{
			//	切り出し
			if(findIndex > 0)
				m_destBuf.Append((char*)src, findIndex);

			//	置き換え
			m_destBuf.AppendString(items[itemIndex].m_escape);
			src += items[itemIndex].m_token.GetLength();
		}
		else
		{
			m_destBuf.AppendLPCU8STR(src);
			m_destBuf.AppendByte(0);
			return((LPCU8STR)m_destBuf.GetPtr());
		}
	}
}



/*!
	一番最初に見つかったインデックスを取得
*/
int CTextEscape::MultiFind(int &findIndex, LPCU8STR src, CSimpleArrayTemplate<CTextEscapeItem> &items)
{
	//	下準備
	findIndex = 0;
	int	itemIndex = -1;

	//	全部検索してみる
	for(int i=0;i<items.GetCount();i++)
	{
		int index = Find(src, items[i].m_token);
		if(index != -1)
		{
			//	先頭に近い？
			if(itemIndex == -1 || findIndex > index)
			{
				itemIndex = i;
				findIndex = index;
			}
		}
	}

	return(itemIndex);
}


/*!
	検索
*/
int CTextEscape::Find(LPCU8STR src, LPCU8STR find)
{
	//	検索
	LPCSTR ptr = strstr((LPCSTR)src, (LPCSTR)find);
	if(ptr == NULL)
		return(-1);

	return(ptr - (LPCSTR)src);
}

