first add files
This commit is contained in:
parent
9c86489a35
commit
15db8e01c7
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[submodule "3rdpty/expat"]
|
||||||
|
path = 3rdpty/expat
|
||||||
|
url = https://github.com/libexpat/libexpat.git
|
||||||
|
[submodule "3rdpty/jsoncpp"]
|
||||||
|
path = 3rdpty/jsoncpp
|
||||||
|
url = https://github.com/open-source-parsers/jsoncpp.git
|
1
3rdpty/expat
Submodule
1
3rdpty/expat
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 83e1688c74ef4d9034e6b47a6595dee480be6147
|
1
3rdpty/jsoncpp
Submodule
1
3rdpty/jsoncpp
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 9e0d70aa66e6ba993dd05723ca64c26ab00f3572
|
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
|
project(CMUtil)
|
||||||
|
|
||||||
|
include(path_config.cmake)
|
||||||
|
CMUtilSetup(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
add_subdirectory(${CMUTIL_ROOT_SOURCE_PATH})
|
28
inc/hgl/util/cmd/CmdParse.h
Normal file
28
inc/hgl/util/cmd/CmdParse.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef HGL_COMMAND_LINE_PARSE_INCLUDE
|
||||||
|
#define HGL_COMMAND_LINE_PARSE_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/StringList.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 命令行参数解晰辅助类
|
||||||
|
*/
|
||||||
|
class CmdParse ///命令行参数解晰辅助类
|
||||||
|
{
|
||||||
|
OSStringList args;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CmdParse(const OSStringList &);
|
||||||
|
virtual ~CmdParse();
|
||||||
|
|
||||||
|
int Find(const OSString &)const; ///<查找一个指定字串开头的参数是否存在
|
||||||
|
|
||||||
|
bool GetInteger(const OSString &,int *)const; ///<取得一个数值参数
|
||||||
|
bool GetString(const OSString &,OSString &)const; ///<取得一个字符串参数
|
||||||
|
};//class CmdParse
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
||||||
|
#endif//HGL_COMMAND_LINE_PARSE_INCLUDE
|
19
inc/hgl/util/json/JsonTool.h
Normal file
19
inc/hgl/util/json/JsonTool.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include<json/json.h>
|
||||||
|
#include<hgl/type/BaseString.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 转换Json数据类型到普通UTF8字符串
|
||||||
|
*/
|
||||||
|
bool JsonToString(const Json::Value &jv_root,UTF8String &str,OSString &error_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解释一个json数据流
|
||||||
|
*/
|
||||||
|
bool ParseJson(Json::Value &root,const char *str,const int size,OSString &error_info);
|
||||||
|
|
||||||
|
bool LoadJson(Json::Value &,const hgl::OSString &filename,OSString &error_info);
|
||||||
|
bool SaveJson(Json::Value &,const hgl::OSString &filename,OSString &error_info);
|
||||||
|
};//
|
38
inc/hgl/util/time/Timer.h
Normal file
38
inc/hgl/util/time/Timer.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef HGL_TIMER_INCLUDE
|
||||||
|
#define HGL_TIMER_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/DataType.h>
|
||||||
|
#include<hgl/object/Object.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 计时器是一个简单封装的组件。通过操作OnTimer事件通知应用程序时间到了!
|
||||||
|
* 注意如果间隔时间为0那表示不使用定时器,但这样不如将Enable设为false更为高效。
|
||||||
|
*/
|
||||||
|
class Timer:public Object ///计时器类
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
double inter;
|
||||||
|
double next;
|
||||||
|
|
||||||
|
double GetInterval(){return inter;}
|
||||||
|
void SetInterval(double);
|
||||||
|
|
||||||
|
public: //属性
|
||||||
|
|
||||||
|
Property<double> Interval; ///<间隔时间虚拟变量,单位秒
|
||||||
|
|
||||||
|
public: //事件
|
||||||
|
|
||||||
|
DefEvent(void,OnTimer,(Object *)); ///<时间到了事件
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Timer(double=0);
|
||||||
|
virtual ~Timer()=default;
|
||||||
|
|
||||||
|
virtual void Update();
|
||||||
|
};//class Timer:public Object
|
||||||
|
}//namespace hgl
|
||||||
|
#endif//HGL_TIMER_INCLUDE
|
123
inc/hgl/util/xml/XMLParse.h
Normal file
123
inc/hgl/util/xml/XMLParse.h
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#ifndef HGL_XML_PARSE_INCLUDE
|
||||||
|
#define HGL_XML_PARSE_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/BaseString.h>
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 该XML解晰器使用Expat实现,根据MIT协议取得免费授权,授权协议参见 doc/license/MIT.txt
|
||||||
|
* Expat官方网站:http://expat.sourceforge.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct XML_ParserStruct;
|
||||||
|
typedef struct XML_ParserStruct *XML_Parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace io
|
||||||
|
{
|
||||||
|
class InputStream;
|
||||||
|
}//namespace io
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML解析器(虚拟函数版)<br>
|
||||||
|
*/
|
||||||
|
class XMLParse
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
XML_Parser xml;
|
||||||
|
|
||||||
|
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();
|
||||||
|
virtual ~XMLParse();
|
||||||
|
|
||||||
|
virtual void Start();
|
||||||
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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; \
|
||||||
|
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
|
||||||
|
|
||||||
|
/** 使用范例:
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<role name="Bill" sex="true" age="18"/>
|
||||||
|
<role name="Lucy" sex="false" age="17"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
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 hgl
|
||||||
|
#endif//HGL_XML_PARSE_INCLUDE
|
11
path_config.cmake
Normal file
11
path_config.cmake
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
macro(CMUtilSetup source_path)
|
||||||
|
|
||||||
|
message("CMUTIL_ROOT_PATH: " ${source_path})
|
||||||
|
|
||||||
|
set(CMUTIL_ROOT_INCLUDE_PATH ${source_path}/inc)
|
||||||
|
set(CMUTIL_ROOT_SOURCE_PATH ${source_path}/src)
|
||||||
|
|
||||||
|
set(CMUTIL_ROOT_3RDPTY_PATH ${source_path}/3rdpty)
|
||||||
|
|
||||||
|
include_directories(${CMUTIL_ROOT_INCLUDE_PATH})
|
||||||
|
endmacro()
|
3
src/CMakeLists.txt
Normal file
3
src/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
add_subdirectory(xml)
|
||||||
|
add_subdirectory(json)
|
||||||
|
|
77
src/cmd/CmdParse.cpp
Normal file
77
src/cmd/CmdParse.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include<hgl/ut/CmdParse.h>
|
||||||
|
#include<hgl/Str.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
CmdParse::CmdParse(const OSStringList &_args)
|
||||||
|
{
|
||||||
|
args=_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
CmdParse::~CmdParse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdParse::Find(const OSString &flag)const
|
||||||
|
{
|
||||||
|
return args.Find(flag,flag.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CmdParse::GetInteger(const OSString &flag,int *result)const
|
||||||
|
{
|
||||||
|
int index=Find(flag);
|
||||||
|
|
||||||
|
if(index==-1)return(false);
|
||||||
|
|
||||||
|
const OSString &str=args[index];
|
||||||
|
|
||||||
|
if(str.Length()>flag.Length())
|
||||||
|
{
|
||||||
|
stoi(str.c_str()+flag.Length(),*result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stoi(str.c_str(),*result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CmdParse::GetString(const OSString &flag,OSString &result)const
|
||||||
|
{
|
||||||
|
int index=Find(flag);
|
||||||
|
os_char *p=nullptr;
|
||||||
|
|
||||||
|
if(index==-1)return(false);
|
||||||
|
|
||||||
|
const OSString &str=args[index];
|
||||||
|
|
||||||
|
if(str.Length()>flag.Length())
|
||||||
|
{
|
||||||
|
p=str.c_str()+flag.Length();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p=args[index+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*p=='"') //有引号
|
||||||
|
{
|
||||||
|
int len=strchr(p+1,L'"')-p;
|
||||||
|
|
||||||
|
if(len>1)
|
||||||
|
result.Strcpy(p+1,len-1);
|
||||||
|
else
|
||||||
|
result=p+1;
|
||||||
|
}
|
||||||
|
else //无引号
|
||||||
|
{
|
||||||
|
result=p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
22
src/json/CMakeLists.txt
Normal file
22
src/json/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
set(JSON_TOOL_HEADER_FILES ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/json/JsonTool.h)
|
||||||
|
|
||||||
|
set(JSON_TOOL_SOURCE_FILES JsonTool.cpp)
|
||||||
|
SOURCE_GROUP("JSON" FILES JsonTool.cpp)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
SET(JSONCPP_PATH ${CMUTIL_ROOT_3RDPTY_PATH}/jsoncpp)
|
||||||
|
|
||||||
|
include_directories(${JSONCPP_PATH}/include)
|
||||||
|
include_directories(${JSONCPP_PATH}/src/lib_json)
|
||||||
|
|
||||||
|
SET(JSONCPP_SOURCE ${JSONCPP_PATH}/src/lib_json/json_reader.cpp
|
||||||
|
${JSONCPP_PATH}/src/lib_json/json_value.cpp
|
||||||
|
${JSONCPP_PATH}/src/lib_json/json_writer.cpp)
|
||||||
|
|
||||||
|
SET(JSON_TOOL_SOURCE_FILES ${JSON_TOOL_SOURCE_FILES} ${JSONCPP_SOURCE})
|
||||||
|
|
||||||
|
SOURCE_GROUP("JSON\\jsoncpp" FILES ${JSONCPP_SOURCE})
|
||||||
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
add_cm_library(CMUtil.JSON "CM/Util" ${JSON_TOOL_HEADER_FILES}
|
||||||
|
${JSON_TOOL_SOURCE_FILES})
|
92
src/json/JsonTool.cpp
Normal file
92
src/json/JsonTool.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include<string>
|
||||||
|
#include<sstream>
|
||||||
|
#include<json/json.h>
|
||||||
|
#include<hgl/filesystem/FileSystem.h>
|
||||||
|
#include<hgl/type/StdString.h>
|
||||||
|
|
||||||
|
using namespace hgl::filesystem;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
bool JsonToString(const Json::Value &jv_root,UTF8String &str,OSString &error_info)
|
||||||
|
{
|
||||||
|
Json::StreamWriterBuilder builder;
|
||||||
|
Json::StreamWriter *writer=builder.newStreamWriter();
|
||||||
|
|
||||||
|
JSONCPP_OSTRINGSTREAM json_result;
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writer->write(jv_root,&json_result);
|
||||||
|
result=true;
|
||||||
|
|
||||||
|
str=std_to_u8(json_result.str());
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
error_info=OS_TEXT("[C++ Exception][Json::StreamWriter::write] ")+std_to_os(e.what());
|
||||||
|
result=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete writer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseJson(Json::Value &root,const char *txt,const int size,OSString &error_str)
|
||||||
|
{
|
||||||
|
Json::CharReaderBuilder builder;
|
||||||
|
Json::CharReader *reader=builder.newCharReader();
|
||||||
|
|
||||||
|
Json::String errs;
|
||||||
|
|
||||||
|
const bool result=reader->parse(txt,txt+size,&root,&errs);
|
||||||
|
|
||||||
|
delete reader;
|
||||||
|
|
||||||
|
error_str=std_to_os(errs);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadJson(Json::Value &root,const OSString &filename,OSString &error_info)
|
||||||
|
{
|
||||||
|
char *txt;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size=LoadFileToMemory(filename,(void **)&txt);
|
||||||
|
|
||||||
|
if(size<=0)
|
||||||
|
{
|
||||||
|
error_info=OS_TEXT("[ERROR][LoadJson] Load file failed, filename: ")+filename;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
result=ParseJson(root,txt,size,error_info);
|
||||||
|
delete[] txt;
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SaveJson(Json::Value &root,const OSString &filename,OSString &error_info)
|
||||||
|
{
|
||||||
|
UTF8String txt;
|
||||||
|
|
||||||
|
if(!JsonToString(root,txt,error_info))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
const int64 result=SaveMemoryToFile(filename,txt.c_str(),txt.Length());
|
||||||
|
|
||||||
|
if(result!=txt.Length())
|
||||||
|
{
|
||||||
|
error_info=OS_TEXT("[ERROR][SaveJson] Save file failed, only write ")+OSString(result)+OS_TEXT("/")+OSString(txt.Length());
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}//namespace hgl
|
38
src/time/Timer.cpp
Normal file
38
src/time/Timer.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include<hgl/ut/Timer.h>
|
||||||
|
#include<hgl/Time.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
Timer::Timer(double t)
|
||||||
|
{
|
||||||
|
hglSetProperty(Interval,this,Timer::GetInterval,Timer::SetInterval);
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
Interval=t;
|
||||||
|
else
|
||||||
|
SetEnabled(false);
|
||||||
|
|
||||||
|
OnTimer=nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::SetInterval(double t)
|
||||||
|
{
|
||||||
|
inter=t;
|
||||||
|
next=GetDoubleTime()+t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::Update()
|
||||||
|
{
|
||||||
|
if(OnTimer==nullptr) //没有设置事件函数
|
||||||
|
SetEnabled(false);
|
||||||
|
|
||||||
|
double cur_time=GetDoubleTime();
|
||||||
|
|
||||||
|
if(inter&&cur_time>=next) //间隔大于0,且时间到了
|
||||||
|
{
|
||||||
|
SafeCallEvent(OnTimer,(this));
|
||||||
|
|
||||||
|
next=cur_time+inter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//namespace hgl
|
22
src/xml/CMakeLists.txt
Normal file
22
src/xml/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
SET(XML_PARSE_SOURCE XMLParseClass.cpp)
|
||||||
|
|
||||||
|
SOURCE_GROUP("XML" FILES XMLParseClass.cpp)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
SET(EXPAT_SOURCE_PATH ${CMUTIL_ROOT_3RDPTY_PATH}/expat/expat/lib)
|
||||||
|
|
||||||
|
include_directories(${EXPAT_SOURCE_PATH})
|
||||||
|
|
||||||
|
SET(EXPAT_SOURCE
|
||||||
|
${EXPAT_SOURCE_PATH}/xmlparse.c
|
||||||
|
${EXPAT_SOURCE_PATH}/xmlrole.c
|
||||||
|
${EXPAT_SOURCE_PATH}/xmltok.c
|
||||||
|
${EXPAT_SOURCE_PATH}/xmltok_impl.c
|
||||||
|
${EXPAT_SOURCE_PATH}/xmltok_ns.c)
|
||||||
|
|
||||||
|
SET(XML_PARSE_SOURCE ${XML_PARSE_SOURCE} ${EXPAT_SOURCE})
|
||||||
|
|
||||||
|
SOURCE_GROUP("XML\\Expat" FILES ${EXPAT_SOURCE})
|
||||||
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
add_cm_library(CMUtil.XML "CM/Util" ${XML_PARSE_SOURCE})
|
188
src/xml/XMLParseClass.cpp
Normal file
188
src/xml/XMLParseClass.cpp
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
//取名为XMLParseClass是为了避免与expat的xmlparse.c编译造成obj冲突
|
||||||
|
|
||||||
|
#include<hgl/util/xml/XMLParse.h>
|
||||||
|
#include<hgl/io/FileInputStream.h>
|
||||||
|
#include<hgl/filesystem/FileSystem.h>
|
||||||
|
#include<expat.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr uint HGL_XML_PARSE_MAX_SIZE=HGL_SIZE_1KB*128; //最大一次解晰长度
|
||||||
|
|
||||||
|
void XMLStartElement(XMLParse *xml,const XML_Char *name,const XML_Char **atts)
|
||||||
|
{
|
||||||
|
xml->StartElement(name,atts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLCharData(XMLParse *xml,const XML_Char *str,int len)
|
||||||
|
{
|
||||||
|
xml->CharData(str,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLEndElement(XMLParse *xml,const XML_Char *name)
|
||||||
|
{
|
||||||
|
xml->EndElement(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLParse::XMLParse()
|
||||||
|
{
|
||||||
|
xml=nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLParse::~XMLParse()
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
if(xml)
|
||||||
|
{
|
||||||
|
XML_ParserReset(xml,"utf-8");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml=XML_ParserCreate("utf-8");
|
||||||
|
|
||||||
|
XML_SetUserData(xml,this);
|
||||||
|
|
||||||
|
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()<=HGL_XML_PARSE_MAX_SIZE) //可以取长度的,并且<=指定长度的一次读完
|
||||||
|
{
|
||||||
|
int full_size=is->Available();
|
||||||
|
|
||||||
|
char *data=new char[full_size];
|
||||||
|
|
||||||
|
int pos=0;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
while(pos<full_size)
|
||||||
|
{
|
||||||
|
size=is->ReadFully(data,full_size);
|
||||||
|
|
||||||
|
if(size<0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
result=Parse(data,size,pos+size>=full_size);
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
pos+=size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
else //不能取长度或是大于指定长度的
|
||||||
|
{
|
||||||
|
char data[HGL_XML_PARSE_MAX_SIZE];
|
||||||
|
|
||||||
|
int size;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
size=is->Available();
|
||||||
|
|
||||||
|
if(size<=0)break;
|
||||||
|
|
||||||
|
if(size>HGL_XML_PARSE_MAX_SIZE)
|
||||||
|
{
|
||||||
|
size=is->Read(data,HGL_XML_PARSE_MAX_SIZE);
|
||||||
|
result=Parse(data,HGL_XML_PARSE_MAX_SIZE,false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size=is->Read(data,size);
|
||||||
|
result=Parse(data,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);
|
||||||
|
|
||||||
|
io::OpenFileInputStream fis(filename);
|
||||||
|
|
||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user