#include #include #include //for strtol #include #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_CDATA void 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; }