#include "StdAfx.h"
#include "ExpatXmlParser.h"
#include "UTF8StringConvert.h"
#include "BinaryData.h"

CExpatXmlParser::CExpatXmlParser(void)
{
	m_init = FALSE;
}

CExpatXmlParser::~CExpatXmlParser(void)
{
	Close();
}



/////////////////////////////////////////////////////////////////////////////////////
//	開始
/////////////////////////////////////////////////////////////////////////////////////
/*!
	ファイルから取得
*/
CUTF8String CExpatXmlParser::LoadXmlFile(CUTF8String path)
{
	//	開く
	CBinaryData	load;
	if(load.LoadFromFile(path))
		throw CXMLTextParserException(_U16("ファイルのオープンに失敗しました"));

	return(load);
}


/*!
	スキャン
*/
void CExpatXmlParser::StartScan(CUTF8String xmlUtf8)
{
	//	初期化
	if(Init())
		throw CXMLTextParserException(_U16("XMLパーサーの初期化に失敗しました"));

	//	解析
	if(XML_Parse(m_parser, (const XML_Char*)xmlUtf8.GetString(), (int)xmlUtf8.GetLength(), TRUE) != XML_TRUE)
		throw CXMLTextParserException(_U16("XMLの解析に失敗しました"));
}


/////////////////////////////////////////////////////////////////////////////////////
//	補助
/////////////////////////////////////////////////////////////////////////////////////
/*!
	初期化
*/
int CExpatXmlParser::Init()
{
	if(!m_init)
	{
		//	初期化
		m_parser = XML_ParserCreate(NULL);
		if(m_parser == NULL)
			return(-1);

		//	ユーザーデータセット
		XML_SetUserData(m_parser, this);

		//	ハンドラセット
		XML_SetElementHandler(m_parser, StartElementHandler, EndElementHandler);
		XML_SetCharacterDataHandler(m_parser, CharacterDataHandler);
		m_init = TRUE;
	}
	else
	{
		//	リセット
		if(XML_ParserReset(m_parser, NULL) != XML_TRUE)
			return(-1);
	}
	return(0);
}

/*!
	終了
*/
void CExpatXmlParser::Close()
{
	if(m_init)
	{
		XML_ParserFree(m_parser);
	}
	m_init = FALSE;
}


/*!
	Attr数チェック
*/
int CExpatXmlParser::GetAttrCount(const XML_Char **atts)
{
	//	数える
	int i;
	for(i=0;atts[i];i++)
		;
	return(i);
}


/////////////////////////////////////////////////////////////////////////////////////
//	コールバック
/////////////////////////////////////////////////////////////////////////////////////
/*!
	開始タグ
*/
void CExpatXmlParser::StartElementHandler(void *userData, const XML_Char *name, const XML_Char **atts)
{
	CExpatXmlParser *obj = (CExpatXmlParser*)userData;

	//	コール
	obj->OnStartTag((LPCU8STR)name, (LPCU8STR*)atts, CExpatXmlParser::GetAttrCount(atts));
}

/*!
	終了タグ
*/
void CExpatXmlParser::EndElementHandler(void *userData, const XML_Char *name)
{
	CExpatXmlParser *obj = (CExpatXmlParser*)userData;

	//	コール
	obj->OnEndTag((LPCU8STR)name);
}

/*!
	データ
*/
void CExpatXmlParser::CharacterDataHandler(void *userData, const XML_Char *s, int len)
{
	CExpatXmlParser *obj = (CExpatXmlParser*)userData;

	//	コール
	obj->OnData((const utf8_char*)s, len);
}

