263 lines
6.5 KiB
C++
Executable File
263 lines
6.5 KiB
C++
Executable File
//bb.cpp
|
|
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <cerrno>
|
|
#include <sstream>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
|
|
#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<string, string> 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<std::string, std::string> &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;
|
|
} |