//bb.cpp #include #include #include #include #include #include #include #include "CCfgFileParser.h" using namespace std; static inline bool istab(int c) { return (c == '\t'); } static inline char *strltrim(char *str) { while (isspace(*str) || istab(*str)) { ++str; } return str; } static inline char *strrtrim(char *str) { int len = strlen(str) - 1; while (isspace(str[len]) || istab(str[len])) { str[len--] = '\0'; } return str; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// int CCfgFileParser::parseFile(const char *lpszFilename) { using std::string; std::ifstream in1(lpszFilename); if (!in1.is_open()) return errno; char line[2048]; char *pline; bool bInSection = false; SECTION_CONTENT *pSC = NULL; string strSection; std::pair pairKeyValue; m_error_line = 0; m_content.clear(); pSC = &m_content["default"]; bInSection = true; string base64str(""); string mystr(""); while (!in1.eof()) { in1.getline(line, sizeof(line)); if (line[strlen(line)] != '\n') mystr += line + string("\n"); else mystr += line; } in1.close(); stringstream in; in.str(mystr); while (!in.eof()) { /*if(base64str.size() > sizeof(line)) { printf("error in config parser!\n"); return -1; } memcpy(line, base64str.c_str(), base64str.size()); */ in.getline(line, sizeof(line)); pline = line; ++m_error_line; pline = strltrim(pline); if (pline[0] == '\0') continue; //white line, skip if (pline[0] == m_chCommentMark) continue; //comment line, skip if (bInSection) { //is new-section begin? if (pline[0] == m_chSectionBMark && extractSection(pline, strSection)) { pSC = &m_content[strSection]; } else if (extractKeyValue(pline, pairKeyValue)) { //key-value pair pSC->insert(pairKeyValue); } else { //in.close(); return SYNTAX_ERROR; } } else { //NOT in section //is a valid section? if (extractSection(pline, strSection)) { pSC = &m_content[strSection]; bInSection = true; } else { //in.close(); return SYNTAX_ERROR; } } } // in.close(); return 0; } bool CCfgFileParser::getValue(const std::string &strSection, const std::string &strKey, const char * &Value) const { FILE_CONTENT::const_iterator it; if ((it = m_content.find(strSection)) != m_content.end()) { SECTION_CONTENT::const_iterator p; const SECTION_CONTENT §ion = (*it).second;//m_content[strSection]; if ((p = section.find(strKey)) != section.end()) { Value = ((*p).second).c_str(); return true; } } if (m_bShowError) fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); return false; } bool CCfgFileParser::getValue(const std::string &strKey, const char * &pValue) const { return getValue("default", strKey, pValue); } bool CCfgFileParser::getIntValue(const std::string &strSection, const std::string& strKey, long& Value) const { const char* pstr; if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0) { if (strlen(pstr) > 0) { Value = atol(pstr); return true; } } if (m_bShowError) fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); return false; } bool CCfgFileParser::getIntValue(const std::string &strKey, long &Value) const { return getIntValue("default", strKey, Value); } bool CCfgFileParser::getDoubleValue(const std::string &strSection, const std::string &strKey, double &Value) const { const char *pstr; if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0) { Value = atof(pstr); return true; } else { if (m_bShowError) fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); return false; } } bool CCfgFileParser::getDoubleValue(const std::string &strKey, double &Value) const { return getDoubleValue("default", strKey, Value); } /* * Description: Extract section name * Parameters: line[IN]---A string line to be parsed * strSection[OUT]---Section name * * Return Value: if section name is in the line return true,or return false */ bool CCfgFileParser::extractSection(char *line, std::string &strSection) { char *tmp; if (line[0] == m_chSectionBMark) { if ((tmp = strchr(++line, m_chSectionEMark)) != NULL) { *tmp = '\0'; strSection = line; return true; } } return false; } /* * Description: Parse a record line into a std:pair as key and value * Parameters: line[IN]---A string to be parsed * pairKeyValue[OUT]---Parsing result * * Return Value: If parse successfully return true,or return false */ bool CCfgFileParser::extractKeyValue(char *line, std::pair &pairKeyValue) { char *tmp; if ((tmp = strchr(line, m_chRecordEMark)) != NULL || (tmp = strchr(line, '\r')) != NULL || (tmp = strchr(line, '='))) { if (*tmp == '=') tmp = line + strlen(line); // tmp++; *tmp = '\0'; //ignore content after ';'(the RecordEMark) if ((tmp = strchr(line, '=')) != NULL) { *tmp++ = '\0'; tmp = strltrim(tmp); tmp = strrtrim(tmp); line = strrtrim(line); pairKeyValue.first = line; pairKeyValue.second = tmp; return true; } } return false; } const char *CCfgFileParser::getErrorString(int err) { static char buf[100]; if (err == SYNTAX_ERROR) { sprintf(buf, "configuration file format is invalid at line %d", m_error_line); return buf; } else { return strerror(err); } } void CCfgFileParser::printContent() { using std::cout; using std::endl; FILE_CONTENT::const_iterator pf; SECTION_CONTENT::const_iterator ps; for (pf = m_content.begin(); pf != m_content.end(); ++pf) { cout << "section:" << (*pf).first << endl; const SECTION_CONTENT &sc = (*pf).second; for (ps = sc.begin(); ps != sc.end(); ++ps) { cout << '\t' << (*ps).first << "=" << (*ps).second << endl; } } } // 在库中定义一个工厂函数 createParser extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser() { return new CCfgFileParser(); // 在工厂函数中调用构造函数创建对象并返回指针 } // 在库中定义一个销毁函数 deleteParser extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser) { // 在销毁函数中调用析构函数销毁对象 delete parser; }