Public feed
#892859
#include <config.h>#include <cstdio>#include <cstdlib> //for strtol#include <string>#include "init_data.h"#include "xml/oop-expat.h"class InitDataParser : public XMLParser{private: InitData* init_data; int depth; std::string cdata_buffer; enum { UNKNOWN, APP_NAME, APP_VERSION, WU_NAME, USER_NAME, TEAM_NAME } in_tag;public: explicit InitDataParser(InitData* init_data); virtual void start_element_handler(const XML_Char *name, const XML_Char **atts); virtual void end_element_handler(const XML_Char *name); virtual void character_data_handler(const XML_Char *s, int len);};InitDataParser::InitDataParser(InitData* init_data): init_data(init_data), depth(0), in_tag(UNKNOWN){ enable_element_handler(); enable_chardata_handler();}void InitDataParser::start_element_handler(const XML_Char *name, const XML_Char **atts){//avoid repetitive code#define MATCH(str, en) if (strcmp(name, str) == 0) { in_tag = en; } else if (depth == 1) { MATCH("app_name", APP_NAME) MATCH("app_version", APP_VERSION) MATCH("wu_name", WU_NAME) MATCH("user_name", USER_NAME) MATCH("team_name", TEAM_NAME) { fprintf(stderr, "Unrecognized tag: <%s>\n", name); in_tag = UNKNOWN; } cdata_buffer.clear(); } depth++;#undef MATCH}//avoid repetitive code#define COPY_CDATA(varname) { \ init_data->varname = new char[strsize + 1]; \ cdata_buffer.copy(init_data->varname, strsize); \ init_data->varname[strsize] = '\0'; \}void InitDataParser::end_element_handler(const XML_Char *name){ depth--; size_t strsize; strsize = cdata_buffer.size(); switch (in_tag) { case UNKNOWN: return; case APP_NAME: COPY_CDATA(app_name); break; case WU_NAME: COPY_CDATA(wu_name); break; case USER_NAME: COPY_CDATA(user_name); break; case TEAM_NAME: COPY_CDATA(team_name); break; case APP_VERSION: { char* tail = 0; init_data->app_version = strtoul(cdata_buffer.c_str(), &tail, 10); if (tail == 0) { throw __LINE__; } break; }//case }//switch}#undef COPY_CDATAvoid InitDataParser::character_data_handler(const XML_Char *s, int len){ if (in_tag == UNKNOWN) return; cdata_buffer.append(s, len);}InitData::InitData(const char* filename): app_version(0), app_name(NULL), wu_name(NULL), user_name(NULL), team_name(NULL){ InitDataParser p(this); FILE* fp = fopen(filename, "rb"); while (!feof(fp)) { char buf[4096]; size_t read_data = fread(buf, 1, 4096, fp); p.parse(buf, read_data); } p.end_of_document();}InitData::~InitData(){ delete app_name; delete wu_name; delete user_name; delete team_name;}unsigned short InitData::get_app_version() const{ return app_version;}const char* InitData::get_app_name() const{ return app_name;}void InitData::get_app_info(const char*& name, unsigned short& version) const{ name = app_name; version = app_version;}const char* InitData::get_wu_name() const{ return wu_name;}const char* InitData::get_user_name() const{ return user_name;}const char* InitData::get_team_name() const{ return team_name;}