Files
source/Utils/XML_Parser.h
Wanne 91087ca8c0 ************************************************************
* Merged Source Code from Development Trunk: Revision 4063 *
************************************************************
- Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- This will be the Source for the Beta 2011 Test

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2011-01-18 09:11:09 +00:00

224 lines
4.7 KiB
C++

#ifndef _XML_PARSER_H_
#define _XML_PARSER_H_
#include "expat.h"
//#include "XML.h"
#include <string>
template<typename OperandType>
class LazyCondition
{
public:
typedef bool (*cond_fct)(OperandType op1, OperandType op2);
LazyCondition(OperandType op1, OperandType op2, cond_fct fct)
: _op1(op1), _op2(op2), _fct(fct)
{};
bool check()
{
return _fct(_op1,_op2);
}
private:
OperandType _op1;
OperandType _op2;
cond_fct _fct;
};
inline bool lazyStrEqual(const char* str1, const char* str2)
{
return strcmp(str1,str2) == 0;
}
class LazyStrEqual : public LazyCondition<const char*>
{
public:
LazyStrEqual(const char* str1, const char* str2)
: LazyCondition<const char*>(str1, str2, lazyStrEqual)
{};
};
class LazyTrue : public LazyCondition<bool>
{
static bool True(bool a, bool b){return true;};
public:
LazyTrue() : LazyCondition<bool>(true,true,LazyTrue::True) {};
};
class IXMLParser
{
public:
const XML_Char* ElementName;
public:
IXMLParser(const XML_Char *element_name, XML_Parser* parser, IXMLParser* caller=NULL)
: _caller(caller), ElementName(element_name)
{
if(parser)
{
this->setParser(parser);
}
};
~IXMLParser() {};
/**
* Interface
*/
static void onStartCallback(void *userData, const XML_Char* name, const XML_Char** atts)
{
((IXMLParser*)userData)->onStartElement(name,atts);
}
static void onEndCallback(void *userData, const XML_Char* name)
{
((IXMLParser*)userData)->onEndElement(name);
// test if we are done here
if( ((IXMLParser*)userData)->_caller && (strcmp(name, ((IXMLParser*)userData)->ElementName) == 0) )
{
((IXMLParser*)userData)->_caller->grabParser();
}
}
static void onTextCallback(void *userData, const XML_Char *str, int len)
{
((IXMLParser*)userData)->onTextElement(str,len);
}
void grabParser()
{
XML_SetUserData(*_parser,this);
XML_SetElementHandler(*_parser, IXMLParser::onStartCallback, IXMLParser::onEndCallback);
XML_SetCharacterDataHandler(*_parser, IXMLParser::onTextCallback);
}
/**
* Override these methods in your parser
*/
virtual void onStartElement(const XML_Char* name, const XML_Char** atts)
{};
virtual void onEndElement(const XML_Char* name)
{};
virtual void onTextElement(const XML_Char *str, int len)
{
};
class Attributes
{
public:
Attributes(const XML_Char** atts) : _atts(atts) {};
XML_Char const* get(const XML_Char* attr_name) const
{
const XML_Char** atts = _atts;
while(*atts)
{
if(strcmp(*atts++,attr_name) == 0)
{
return *atts;
}
atts++;
}
return "";
}
bool getLong(const XML_Char* attr_name, long& attr) const
{
XML_Char const* result = this->get(attr_name);
if( strcmp(result,"") != 0)
{
attr = (int)atol(result);
return true;
}
return false;
}
bool getDouble(const XML_Char* attr_name, double &attr) const
{
XML_Char const* result = this->get(attr_name);
if( strcmp(result,"") != 0)
{
attr = atof(result);
return true;
}
return false;
}
private:
const XML_Char** _atts;
};
template<typename StateType>
class ParserState
{
public:
ParserState(const StateType start_state)
: _my_state(start_state)
{};
StateType const& state()
{
return _my_state;
}
template<typename ConditionOperandType>
bool stateTransition(const StateType current_state, LazyCondition<ConditionOperandType> condition, const StateType next_state)
{
if(_my_state == current_state && condition.check() )
{
_my_state = next_state;
return true;
}
return false;
}
private:
StateType _my_state;
};
XML_Parser& getParser()
{
return *_parser;
}
protected:
void setParser(XML_Parser* parser)
{
_parser = parser;
// grabParser(); ???
}
XML_Char const* getAttribute(const XML_Char* attr_name, const XML_Char** atts)
{
while(*atts)
{
if(strcmp(*atts++,attr_name) == 0)
{
return *atts;
}
atts++;
}
return "";
}
bool getAttributeAsInt(const XML_Char* attr_name, const XML_Char** attr, int &value)
{
XML_Char const* result = getAttribute(attr_name,attr);
if( strcmp(result,"") != 0)
{
value = (int)atol(result);
return true;
}
return false;
}
bool getAttributeAsFloat(const XML_Char* attr_name, const XML_Char** attr, float &value)
{
XML_Char const* result = getAttribute(attr_name,attr);
if( strcmp(result,"") != 0)
{
value = (float)atof(result);
return true;
}
return false;
}
int getCurrentLineNumber()
{
return XML_GetCurrentLineNumber(*this->_parser);
}
protected:
std::string sCharData;
XML_Parser* _parser;
IXMLParser* _caller;
};
#endif // _XML_PARSER_H_