new XML Parse tools
This commit is contained in:
@@ -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)
|
||||
|
28
src/xml/ElementCreater.cpp
Normal file
28
src/xml/ElementCreater.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include<hgl/util/xml/ElementParseCreater.h>
|
||||
|
||||
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
|
42
src/xml/ElementParseCreater.cpp
Normal file
42
src/xml/ElementParseCreater.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include<hgl/util/xml/ElementParseCreater.h>
|
||||
|
||||
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
|
69
src/xml/ElementParseKV.cpp
Normal file
69
src/xml/ElementParseKV.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include<hgl/util/xml/ElementParseKV.h>
|
||||
#include<hgl/CodePage.h>
|
||||
|
||||
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<char>(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
|
@@ -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(pos<full_size)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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(pos<full_size)
|
||||
{
|
||||
size=is->Read(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
|
||||
|
Reference in New Issue
Block a user