diff --git a/inc/hgl/util/xml/XMLParse.h b/inc/hgl/util/xml/XMLParse.h index 4d3d689..8e84f79 100644 --- a/inc/hgl/util/xml/XMLParse.h +++ b/inc/hgl/util/xml/XMLParse.h @@ -2,6 +2,10 @@ #define HGL_XML_PARSE_INCLUDE #include +#include +#include +#include + extern "C" { /** @@ -22,7 +26,107 @@ namespace hgl }//namespace io /** - * XML解析器(虚拟函数版)
+ * XML节点解析器 + */ + class XMLElementParse + { + public: + + virtual bool StartElement(const char *element_name)=0; + virtual void Attr(const char *flag,const char *info){}; + virtual void CharData(const char *str,int str_length){}; + virtual void EndElement(const char *element_name){}; + };//class XMLElementParse + + class XMLElementParseKV:public XMLElementParse + { + protected: + + using AttrsMap=Map; + using AttrItem=Pair; + + AttrsMap attrs_map; + + protected: + + const AttrItem *GetAttrItem(const AnsiString &name); + + template const bool GetInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stoi(ai->right.c_str(),value):false);} + template const bool GetUInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stou(ai->right.c_str(),value):false);} + template const bool GetFloat (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stof(ai->right.c_str(),value):false);} + + public: + + virtual void Attr(const char *flag,const char *info) override; + + public: + + const bool IsExist (const AnsiString &name)const{return attrs_map.KeyExist(name);} + + const char * ToCString (const AnsiString &name){const AttrItem *ai=GetAttrItem(name);return(ai?ai->right.c_str():nullptr);} + const char * operator[] (const AnsiString &name){return ToCString(name);} + + public: + + const bool Get(const AnsiString &name,AnsiString &str) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + str=ai->right; + return(true); + } + + const bool Get(const AnsiString &name,UTF16String &str) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + str=to_u16(ai->right); + return(true); + } + + const bool Get(const AnsiString &name,char &ch) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + ch=ai->right.GetBeginChar(); + return(true); + } + + const bool Get(const AnsiString &name,bool &value) + { + const AttrItem *ai=GetAttrItem(name); + + return(ai?stob(ai->right.c_str(),value):false); + } + + const bool Get(const AnsiString &name, int8 &value){return GetInteger < int8 >(name,value);} + const bool Get(const AnsiString &name,uint8 &value){return GetUInteger(name,value);} + const bool Get(const AnsiString &name, int16 &value){return GetInteger < int16>(name,value);} + const bool Get(const AnsiString &name,uint16 &value){return GetUInteger(name,value);} + const bool Get(const AnsiString &name, int32 &value){return GetInteger < int32>(name,value);} + const bool Get(const AnsiString &name,uint32 &value){return GetUInteger(name,value);} + const bool Get(const AnsiString &name, int64 &value){return GetInteger < int64>(name,value);} + const bool Get(const AnsiString &name,uint64 &value){return GetUInteger(name,value);} + + const bool GetHexStr(const AnsiString &name,uint8 *data) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + ParseHexStr(data,ai->right.c_str(),ai->right.Length()); + return(true); + } + };//class XMLElementParseKV:public XMLElementParse + + /** + * XML解析器
*/ class XMLParse { @@ -30,20 +134,18 @@ namespace hgl XML_Parser xml; - uint buffer_size; + int buffer_size; char *buffer; + protected: + + XMLElementParse *element_parse; + virtual void StartParse(); public: - virtual void StartElement(const char *element_name,const char **atts)=0; - virtual void CharData(const char *str,int str_length){}; - virtual void EndElement(const char *element_name){}; - - public: - - XMLParse(const uint size=HGL_SIZE_1KB*128); + XMLParse(XMLElementParse *,const int size=HGL_SIZE_1KB*128); virtual ~XMLParse(); virtual void Start(const char *charset="utf-8"); @@ -53,27 +155,6 @@ namespace hgl bool XMLParseFile(XMLParse *xml,const OSString &filename); - /** - * XML解析器(回调函数版) - */ - class XMLParseCB:public XMLParse - { - protected: - - virtual void StartParse(); - - public: - - DefEvent(void,OnStartElement,(const char *,const char **)); - DefEvent(void,OnCharData,(const char *,int)); - DefEvent(void,OnEndElement,(const char *)); - - public: - - XMLParseCB(); - virtual ~XMLParseCB()=default; - };//class XMLParseCB - #define XML_START_PARSE(name) while(*name) \ { \ const char *flag=*name;++name; \ diff --git a/src/xml/XMLParseClass.cpp b/src/xml/XMLParseClass.cpp index f1e58a7..88e100a 100644 --- a/src/xml/XMLParseClass.cpp +++ b/src/xml/XMLParseClass.cpp @@ -9,24 +9,51 @@ namespace hgl { namespace { - void XMLStartElement(XMLParse *xml,const XML_Char *name,const XML_Char **atts) + void XMLStartElement(XMLElementParse *ep,const XML_Char *name,const XML_Char **atts) { - xml->StartElement(name,atts); + if(!ep->StartElement(name)) + return; + + const char *flag; + const char *info; + + while(*atts) + { + flag=*atts;++atts; + info=*atts;++atts; + + ep->Attr(flag,info); + } } - void XMLCharData(XMLParse *xml,const XML_Char *str,int len) + void XMLCharData(XMLElementParse *ep,const XML_Char *str,int len) { - xml->CharData(str,len); + ep->CharData(str,len); } - void XMLEndElement(XMLParse *xml,const XML_Char *name) + void XMLEndElement(XMLElementParse *ep,const XML_Char *name) { - xml->EndElement(name); + ep->EndElement(name); } + }//namespace + + const XMLElementParseKV::AttrItem *XMLElementParseKV::GetAttrItem(const AnsiString &name) + { + const int pos=attrs_map.FindPos(name); + + if(pos<0)return(false); + + return attrs_map.GetItem(pos); } - XMLParse::XMLParse(const uint size) + void XMLElementParseKV::Attr(const char *flag,const char *info) { + attrs_map.Add(flag,info); + } + + XMLParse::XMLParse(XMLElementParse *ep,const int size) + { + element_parse=ep; xml=nullptr; if(size<=0) @@ -65,7 +92,7 @@ namespace hgl { xml=XML_ParserCreate(charset); - XML_SetUserData(xml,this); + XML_SetUserData(xml,element_parse); StartParse(); } @@ -157,35 +184,4 @@ namespace hgl return xml->Parse(&fis); } - - namespace - { - void StartElementCB(XMLParseCB *xml,const XML_Char *name,const XML_Char **atts) - { - SafeCallEvent(xml->OnStartElement,(name,atts)); - } - - void CharDataCB(XMLParseCB *xml,const XML_Char *str,int len) - { - SafeCallEvent(xml->OnCharData,(str,len)); - } - - void EndElementCB(XMLParseCB *xml,const XML_Char *name) - { - SafeCallEvent(xml->OnEndElement,(name)); - } - } - - XMLParseCB::XMLParseCB() - { - OnStartElement=nullptr; - OnCharData=nullptr; - OnEndElement=nullptr; - } - - void XMLParseCB::StartParse() - { - XML_SetElementHandler(xml,(XML_StartElementHandler)StartElementCB,(XML_EndElementHandler)EndElementCB); - XML_SetCharacterDataHandler(xml,(XML_CharacterDataHandler)CharDataCB); - } }//namespace hgl