diff --git a/CMakeLists.txt b/CMakeLists.txt index faa3ff9..779f744 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,13 @@ project(CMUtil) include(path_config.cmake) CMUtilSetup(${CMAKE_CURRENT_SOURCE_DIR}) +if(CM_UTIL_SUPPORT_XML) + add_definitions(-DXML_STATIC) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdpty/expat/expat) +endif() + +if(CM_UTIL_SUPPORT_JSON) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdpty/jsoncpp) +endif() + add_subdirectory(${CMUTIL_ROOT_SOURCE_PATH}) diff --git a/inc/hgl/util/xml/ElementParse.h b/inc/hgl/util/xml/ElementParse.h new file mode 100644 index 0000000..df6056b --- /dev/null +++ b/inc/hgl/util/xml/ElementParse.h @@ -0,0 +1,24 @@ +#ifndef HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE +#define HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE + +namespace hgl +{ + namespace xml + { + /** + * XML节点解析器 + */ + class ElementParse + { + public: + + virtual ~ElementParse()=default; + + virtual bool Start (const char *element_name) {return(true);} + virtual void Attr (const char *flag,const char *info) {} + virtual void CharData (const char *str,const int str_length) {} + virtual void End (const char *element_name) {} + };//class ElementParse + }//namespace xml +}//namespace hgl +#endif//HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE diff --git a/inc/hgl/util/xml/ElementParseCreater.h b/inc/hgl/util/xml/ElementParseCreater.h new file mode 100644 index 0000000..d65aafe --- /dev/null +++ b/inc/hgl/util/xml/ElementParseCreater.h @@ -0,0 +1,73 @@ +#ifndef HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE +#define HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE + +#include +#include +#include +#include +namespace hgl +{ + namespace xml + { + class ElementCreater + { + friend class ElementParseCreater; + + AnsiString element_name; + + protected: + + Map ecs_map; + + virtual ElementCreater *GetSubElementCreater(const AnsiString &sub_name); + + public: + + const AnsiString &GetElementName()const{return element_name;} + + public: + + ElementCreater(const AnsiString &en){element_name=en;} + virtual ~ElementCreater()=default; + + bool Registry(const AnsiString &name,ElementCreater *ec); + + public: + + virtual bool Start (){return true;} + virtual void Attr (const char *flag,const char *info){} + virtual void CharData (const char *str,const int str_length){} + + virtual void End (){} + };//class ElementCreater + + /** + * Creater模式XML节点解析器 + */ + class ElementParseCreater:public ElementParse + { + Stack ecs_stack; + + ElementCreater *root_ec; + ElementCreater *cur_ec; + + public: + + ElementParseCreater(ElementCreater *rec) + { + root_ec=rec; + cur_ec=rec; + } + + virtual ~ElementParseCreater()=default; + + public: + + bool Start (const char *element_name) override; + void Attr (const char *flag,const char *info) override; + void CharData (const char *str,const int str_length) override; + void End (const char *element_name) override; + };//class ElementParseCreater:public ElementParse + }//namespace xml +}//namespace hgl +#endif//HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE diff --git a/inc/hgl/util/xml/ElementParseKV.h b/inc/hgl/util/xml/ElementParseKV.h new file mode 100644 index 0000000..a3ba700 --- /dev/null +++ b/inc/hgl/util/xml/ElementParseKV.h @@ -0,0 +1,64 @@ +#ifndef HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE +#define HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE + +#include +#include +#include +namespace hgl +{ + namespace xml + { + /** + * KV模式XML节点解析器 + */ + class ElementParseKV:public ElementParse + { + 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 ~ElementParseKV()=default; + + 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 bool Get(const AnsiString &name,UTF16String &str); + const bool Get(const AnsiString &name,char &ch); + const bool Get(const AnsiString &name,bool &value); + + 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); + };//class ElementParseKV:public ElementParse + }//namespace xml +}//namespace hgl +#endif//HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE diff --git a/inc/hgl/util/xml/XMLParse.h b/inc/hgl/util/xml/XMLParse.h index 8720efa..5a92af5 100644 --- a/inc/hgl/util/xml/XMLParse.h +++ b/inc/hgl/util/xml/XMLParse.h @@ -2,9 +2,7 @@ #define HGL_XML_PARSE_INCLUDE #include -#include -#include -#include +#include extern "C" { @@ -25,186 +23,89 @@ namespace hgl class InputStream; }//namespace io - /** - * XML节点解析器 - */ - class XMLElementParse + namespace xml { - public: + constexpr int XML_PARSE_BUFFER_SIZE=HGL_SIZE_1KB*128; ///; - 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) + /** + * XML解析器
+ */ + class XMLParse { - const AttrItem *ai=GetAttrItem(name); - - if(!ai)return(false); - - str=ai->right; - return(true); - } + protected: - const bool Get(const AnsiString &name,UTF16String &str) + XML_Parser xml; + + int buffer_size; + char *buffer; + + protected: + + ElementParse *element_parse; + + virtual void StartParse(); + + public: + + XMLParse(ElementParse *,const int size=XML_PARSE_BUFFER_SIZE); + virtual ~XMLParse(); + + virtual void Start(const char *charset="utf-8"); + virtual bool Parse(const char *buf,int len,bool isFin); + virtual bool Parse(io::InputStream *,bool isFin=true); + };//class XMLParse + + bool XMLParseFile(XMLParse *xml,const OSString &filename); + + #define XML_START_PARSE(name) while(*name) \ + { \ + const char *flag=*name;++name; \ + const char *info=*name;++name; + + #define XML_END_PARSE() LOG_ERROR(UTF8String(__FILE__)+U8_TEXT(":")+UTF8String(__LINE__)+U8_TEXT(" can't parse atts \"")+UTF8String(flag)+U8_TEXT("\" , info \"")+UTF8String(info)+U8_TEXT("\".")); \ + } + #define XML_END_PARSE_SKIP() ;} + + #define xml_parse_skip(name) if(hgl::strcmp(flag,#name)==0)continue;else + #define xml_parse_string_u16(name) if(hgl::strcmp(flag,#name)==0)name=to_u16(info);else + #define xml_parse_string_u8(name) if(hgl::strcmp(flag,#name)==0)name=info;else + #define xml_parse_int(name) if(hgl::strcmp(flag,#name)==0)hgl::stoi(info,name);else + #define xml_parse_uint(name) if(hgl::strcmp(flag,#name)==0)hgl::stou(info,name);else + #define xml_parse_float(name) if(hgl::strcmp(flag,#name)==0)hgl::stof(info,name);else + #define xml_parse_bool(name) if(hgl::strcmp(flag,#name)==0)hgl::stob(info,name);else + #define xml_parse_hexstr(name) if(hgl::strcmp(flag,#name)==0)hgl::ParseHexStr(name,info);else + + #define xml_parse_to_string_u8(name,value) if(hgl::strcmp(flag,name)==0)value=info;else + #define xml_parse_to_int(name,value) if(hgl::strcmp(flag,name)==0)hgl::stoi(info,value);else + #define xml_parse_to_uint(name,value) if(hgl::strcmp(flag,name)==0)hgl::stou(info,value);else + #define xml_parse_to_float(name,value) if(hgl::strcmp(flag,name)==0)hgl::stof(info,value);else + #define xml_parse_to_bool(name,value) if(hgl::strcmp(flag,name)==0)hgl::stob(info,value);else + + /** 使用范例: + + + + + + + void StartElement(const char *element_name,const char **atts) override { - const AttrItem *ai=GetAttrItem(name); - - if(!ai)return(false); - - str=to_u16(ai->right); - return(true); + if(strcmp(element_name,"role")==0) + { + std::string name; + bool sex; + int age; + + XML_START_PARSE(atts) + + xml_parse_string_u8(name) + xml_parse_bool(sex) + xml_parse_int(age) + + XML_END_PARSE + } } - - 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 - - constexpr int XML_PARSE_BUFFER_SIZE=HGL_SIZE_1KB*128; /// */ - class XMLParse - { - protected: - - XML_Parser xml; - - int buffer_size; - char *buffer; - - protected: - - XMLElementParse *element_parse; - - virtual void StartParse(); - - public: - - XMLParse(XMLElementParse *,const int size=XML_PARSE_BUFFER_SIZE); - virtual ~XMLParse(); - - virtual void Start(const char *charset="utf-8"); - virtual bool Parse(const char *buf,int len,bool isFin); - virtual bool Parse(io::InputStream *,bool isFin=true); - };//class XMLParse - - bool XMLParseFile(XMLParse *xml,const OSString &filename); - -#define XML_START_PARSE(name) while(*name) \ - { \ - const char *flag=*name;++name; \ - const char *info=*name;++name; - -#define XML_END_PARSE() LOG_ERROR(UTF8String(__FILE__)+U8_TEXT(":")+UTF8String(__LINE__)+U8_TEXT(" can't parse atts \"")+UTF8String(flag)+U8_TEXT("\" , info \"")+UTF8String(info)+U8_TEXT("\".")); \ - } -#define XML_END_PARSE_SKIP() ;} - -#define xml_parse_skip(name) if(hgl::strcmp(flag,#name)==0)continue;else -#define xml_parse_string_u16(name) if(hgl::strcmp(flag,#name)==0)name=to_u16(info);else -#define xml_parse_string_u8(name) if(hgl::strcmp(flag,#name)==0)name=info;else -#define xml_parse_int(name) if(hgl::strcmp(flag,#name)==0)hgl::stoi(info,name);else -#define xml_parse_uint(name) if(hgl::strcmp(flag,#name)==0)hgl::stou(info,name);else -#define xml_parse_float(name) if(hgl::strcmp(flag,#name)==0)hgl::stof(info,name);else -#define xml_parse_bool(name) if(hgl::strcmp(flag,#name)==0)hgl::stob(info,name);else -#define xml_parse_hexstr(name) if(hgl::strcmp(flag,#name)==0)hgl::ParseHexStr(name,info);else - -#define xml_parse_to_string_u8(name,value) if(hgl::strcmp(flag,name)==0)value=info;else -#define xml_parse_to_int(name,value) if(hgl::strcmp(flag,name)==0)hgl::stoi(info,value);else -#define xml_parse_to_uint(name,value) if(hgl::strcmp(flag,name)==0)hgl::stou(info,value);else -#define xml_parse_to_float(name,value) if(hgl::strcmp(flag,name)==0)hgl::stof(info,value);else -#define xml_parse_to_bool(name,value) if(hgl::strcmp(flag,name)==0)hgl::stob(info,value);else - -/** 使用范例: - - - - - - - void StartElement(const char *element_name,const char **atts) override - { - if(strcmp(element_name,"role")==0) - { - std::string name; - bool sex; - int age; - - XML_START_PARSE(atts) - - xml_parse_string_u8(name) - xml_parse_bool(sex) - xml_parse_int(age) - - XML_END_PARSE - } - } -*/ + }//namespace xml }//namespace hgl #endif//HGL_XML_PARSE_INCLUDE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5f346f4..e4df102 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,31 @@ option(CM_UTIL_SUPPORT_XML "Build XML Parse module." ON) -if(CM_UTIL_SUPPORT_XML) - SET(XML_PARSE_SOURCE ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/xml/XMLParse.h - xml/XMLParseClass.cpp) +SET(CM_XML_INCLUDE_PATH ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/xml) - SOURCE_GROUP("XML" FILES ${XML_PARSE_SOURCE}) +if(CM_UTIL_SUPPORT_XML) + + SET(XML_ELEMENT_PARSE_KV ${CM_XML_INCLUDE_PATH}/ElementParseKV.h + xml/ElementParseKV.cpp) + + SET(XML_ELEMENT_PARSE_CREATER ${CM_XML_INCLUDE_PATH}/ElementParseCreater.h + xml/ElementParseCreater.cpp + xml/ElementCreater.cpp) + + SET(XML_ELEMENT_PARSE_SOURCE ${CM_XML_INCLUDE_PATH}/ElementParse.h) + + SET(XML_PARSE_CLASS_SOURCE ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/xml/XMLParse.h + xml/XMLParseClass.cpp) + + SET(XML_PARSE_SOURCE ${XML_ELEMENT_PARSE_KV} + ${XML_ELEMENT_PARSE_CREATER} + ${XML_ELEMENT_PARSE_SOURCE} + + ${XML_PARSE_CLASS_SOURCE}) + + SOURCE_GROUP("XML\\ElementParse\\KV" FILES ${XML_ELEMENT_PARSE_KV}) + SOURCE_GROUP("XML\\ElementParse\\Creater" FILES ${XML_ELEMENT_PARSE_CREATER}) + SOURCE_GROUP("XML\\ElementParse" FILES ${XML_ELEMENT_PARSE_SOURCE}) + SOURCE_GROUP("XML" FILES ${XML_PARSE_CLASS_SOURCE}) IF(WIN32) SET(EXPAT_SOURCE_PATH ${CMUTIL_ROOT_3RDPTY_PATH}/expat/expat/lib) diff --git a/src/xml/ElementCreater.cpp b/src/xml/ElementCreater.cpp new file mode 100644 index 0000000..dc811e7 --- /dev/null +++ b/src/xml/ElementCreater.cpp @@ -0,0 +1,28 @@ +#include + +namespace hgl +{ + namespace xml + { + bool ElementCreater::Registry(const AnsiString &name,ElementCreater *ec) + { + if(name.Length()<=0||!ec)return(false); + if(ecs_map.KeyExist(name))return(false); + + ecs_map.Add(name,ec); + return(true); + } + + ElementCreater *ElementCreater::GetSubElementCreater(const AnsiString &sub_name) + { + if(sub_name.IsEmpty())return(nullptr); + + ElementCreater *ec; + + if(!ecs_map.Get(sub_name,ec)) + return(nullptr); + + return ec; + } + }//namespace xml +}//namespace hgl diff --git a/src/xml/ElementParseCreater.cpp b/src/xml/ElementParseCreater.cpp new file mode 100644 index 0000000..f44711c --- /dev/null +++ b/src/xml/ElementParseCreater.cpp @@ -0,0 +1,42 @@ +#include + +namespace hgl +{ + namespace xml + { + bool ElementParseCreater::Start (const char *element_name) + { + if(!element_name||!*element_name)return(false); + + if(!cur_ec) + return(false); + + ElementCreater *ec=cur_ec->GetSubElementCreater(element_name); + + ecs_stack.Push(cur_ec); + cur_ec=ec; + return(cur_ec); + } + + void ElementParseCreater::Attr(const char *flag,const char *info) + { + if(!cur_ec)return; + + cur_ec->Attr(flag,info); + } + + void ElementParseCreater::CharData(const char *str,const int str_length) + { + if(!cur_ec)return; + + cur_ec->CharData(str,str_length); + } + + void ElementParseCreater::End(const char *element_name) + { + cur_ec->End(); + cur_ec=nullptr; + ecs_stack.Pop(cur_ec); + } + }//namespace xml +}//namespace hgl diff --git a/src/xml/ElementParseKV.cpp b/src/xml/ElementParseKV.cpp new file mode 100644 index 0000000..3696466 --- /dev/null +++ b/src/xml/ElementParseKV.cpp @@ -0,0 +1,69 @@ +#include +#include + +namespace hgl +{ + namespace xml + { + const ElementParseKV::AttrItem *ElementParseKV::GetAttrItem(const AnsiString &name) + { + const int pos=attrs_map.FindPos(name); + + if(pos<0)return(false); + + return attrs_map.GetItem(pos); + } + + void ElementParseKV::Attr(const char *flag,const char *info) + { + attrs_map.Add(flag,info); + } + + const bool ElementParseKV::Get(const AnsiString &name,AnsiString &str) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + str=ai->right; + return(true); + } + + const bool ElementParseKV::Get(const AnsiString &name,UTF16String &str) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + str=to_u16(ai->right); + return(true); + } + + const bool ElementParseKV::Get(const AnsiString &name,char &ch) + { + const AttrItem *ai=GetAttrItem(name); + + if(!ai)return(false); + + ch=ai->right.GetBeginChar(); + return(true); + } + + const bool ElementParseKV::Get(const AnsiString &name,bool &value) + { + const AttrItem *ai=GetAttrItem(name); + + return(ai?stob(ai->right.c_str(),value):false); + } + + const bool ElementParseKV::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); + } + }//namespace xml +}//namespace hgl diff --git a/src/xml/XMLParseClass.cpp b/src/xml/XMLParseClass.cpp index e9ef54c..162e8e1 100644 --- a/src/xml/XMLParseClass.cpp +++ b/src/xml/XMLParseClass.cpp @@ -7,181 +7,170 @@ namespace hgl { - namespace + namespace xml { - void XMLStartElement(XMLElementParse *ep,const XML_Char *name,const XML_Char **atts) + namespace { - if(!ep->StartElement(name)) - return; - - const char *flag; - const char *info; - - while(*atts) + void XMLStartElement(ElementParse *ep,const XML_Char *name,const XML_Char **atts) { - flag=*atts;++atts; - info=*atts;++atts; + if(!ep->Start(name)) + return; + + const char *flag; + const char *info; + + while(*atts) + { + flag=*atts;++atts; + info=*atts;++atts; - ep->Attr(flag,info); - } - } - - void XMLCharData(XMLElementParse *ep,const XML_Char *str,int len) - { - ep->CharData(str,len); - } - - void XMLEndElement(XMLElementParse *ep,const XML_Char *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); - } - - 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) - buffer_size=XML_PARSE_BUFFER_SIZE; - else - buffer_size=size; - - buffer=new char[buffer_size]; - } - - XMLParse::~XMLParse() - { - delete[] buffer; - - if(!xml)return; - - XML_ParserFree(xml); - } - - void XMLParse::StartParse() - { - XML_SetElementHandler(xml,(XML_StartElementHandler)XMLStartElement,(XML_EndElementHandler)XMLEndElement); - XML_SetCharacterDataHandler(xml,(XML_CharacterDataHandler)XMLCharData); - } - - /** - * 重新开始一次解晰 - */ - void XMLParse::Start(const char *charset) - { - if(xml) - { - XML_ParserReset(xml,charset); - } - else - { - xml=XML_ParserCreate(charset); - - XML_SetUserData(xml,element_parse); - - StartParse(); - } - } - - /** - * 解晰一段xml文本 - * @param buf 文本缓冲区 - * @param len 文本长度 - * @param isFin 是否结束 - * @return 此次解晰是否成功 - */ - bool XMLParse::Parse(const char *buf,int len,bool isFin) - { - if(!xml)return(false); - - return XML_Parse(xml,buf,len,isFin); - } - - bool hgl::XMLParse::Parse(io::InputStream *is, bool isFin) - { - if(!is)return(false); - - if(is->CanSize()&&is->GetSize()<=buffer_size) //可以取长度的,并且<=指定长度的一次读完 - { - int full_size=is->Available(); - - int pos=0; - int size; - - bool result; - - while(posReadFully(buffer,full_size); - - if(size<0) - return(false); - - result=Parse(buffer,size,pos+size>=full_size); - - if(!result) - return(false); - - pos+=size; - } - - return(true); - } - else //不能取长度或是大于指定长度的 - { - int size; - bool result; - - for(;;) - { - size=is->Available(); - - if(size<=0)break; - - if(size>buffer_size) - { - size=is->Read(buffer,buffer_size); - result=Parse(buffer,buffer_size,false); + ep->Attr(flag,info); } - else + } + + void XMLCharData(ElementParse *ep,const XML_Char *str,int len) + { + ep->CharData(str,len); + } + + void XMLEndElement(ElementParse *ep,const XML_Char *name) + { + ep->End(name); + } + }//namespace + + XMLParse::XMLParse(ElementParse *ep,const int size) + { + element_parse=ep; + xml=nullptr; + + if(size<=0) + buffer_size=XML_PARSE_BUFFER_SIZE; + else + buffer_size=size; + + buffer=new char[buffer_size]; + } + + XMLParse::~XMLParse() + { + delete[] buffer; + + if(!xml)return; + + XML_ParserFree(xml); + } + + void XMLParse::StartParse() + { + XML_SetElementHandler(xml,(XML_StartElementHandler)XMLStartElement,(XML_EndElementHandler)XMLEndElement); + XML_SetCharacterDataHandler(xml,(XML_CharacterDataHandler)XMLCharData); + } + + /** + * 重新开始一次解晰 + */ + void XMLParse::Start(const char *charset) + { + if(xml) + { + XML_ParserReset(xml,charset); + } + else + { + xml=XML_ParserCreate(charset); + + XML_SetUserData(xml,element_parse); + + StartParse(); + } + } + + /** + * 解晰一段xml文本 + * @param buf 文本缓冲区 + * @param len 文本长度 + * @param isFin 是否结束 + * @return 此次解晰是否成功 + */ + bool XMLParse::Parse(const char *buf,int len,bool isFin) + { + if(!xml)return(false); + + return XML_Parse(xml,buf,len,isFin); + } + + bool XMLParse::Parse(io::InputStream *is, bool isFin) + { + if(!is)return(false); + + if(is->CanSize()&&is->GetSize()<=buffer_size) //可以取长度的,并且<=指定长度的一次读完 + { + int full_size=is->Available(); + + int pos=0; + int size; + + bool result; + + while(posRead(buffer,size); - result=Parse(buffer,size,true); + size=is->ReadFully(buffer,full_size); + + if(size<0) + return(false); + + result=Parse(buffer,size,pos+size>=full_size); + + if(!result) + return(false); + + pos+=size; } - if(!result)return(false); + return(true); } + else //不能取长度或是大于指定长度的 + { + int size; + bool result; - return(true); + for(;;) + { + size=is->Available(); + + if(size<=0)break; + + if(size>buffer_size) + { + size=is->Read(buffer,buffer_size); + result=Parse(buffer,buffer_size,false); + } + else + { + size=is->Read(buffer,size); + result=Parse(buffer,size,true); + } + + if(!result)return(false); + } + + return(true); + } } - } - /** - * 解晰一个XML文件 - */ - bool XMLParseFile(XMLParse *xml,const OSString &filename) - { - if(!xml)return(false); - if(filename.IsEmpty())return(false); - if(!filesystem::FileCanRead(filename))return(false); + /** + * 解晰一个XML文件 + */ + bool XMLParseFile(XMLParse *xml,const OSString &filename) + { + if(!xml)return(false); + if(filename.IsEmpty())return(false); + if(!filesystem::FileCanRead(filename))return(false); - io::OpenFileInputStream fis(filename); + io::OpenFileInputStream fis(filename); - return xml->Parse(&fis); - } + return xml->Parse(&fis); + } + }//namespace xml }//namespace hgl