由于项目中经常遇到读取配置文件的地方,为方便调用虽写了个功能简单,使用方便的配置文件类,基本思路是将配置文件缓冲到map当中,目前只支持一级配置,多级别的树形配置暂不支持,有需要的兄弟请完善。
为单实例模式。
config2map.h
// config2map.h
// 配置文件到map的映射类,单实例模式
// 创建: 2010-09-13 changym, changup@qq.com
// 修改:
//
/**///////////////////////////////////////////////////////////////////////#ifndef _CONFIG2MAP_H_
#define _CONFIG2MAP_H_
#include <map>
using namespace std;
/**//*仅仅是为了能让编译通过添加日志相关部分*/
#define LOG_DBG 1
#define LOG_INFO 2
#define LOG_ERR 3
class CLog
{
public:
int log(int,const char*,)
{
return 0;
}
}
typedef struct tagNode
{
tagNode(const char* pname,const char* pvalue)
{
name=0;
value=0;
if(pname)
{
name = new char[strlen(pname)+1];
strcpy(name,pname);
name[strlen(pname)]='\0';
}
if(pvalue)
{
value = new char[strlen(pvalue)+1];
strcpy(value,pvalue);
value[strlen(pvalue)]='\0';
}
}
~tagNode()
{
if(name)
{
delete [] name;
name=0;
}
if(value)
{
delete [] value;
value=0;
}
}
void print(CLog* plog)
{
plog->log(LOG_DBG,"\t%s=%s",name,value);
}
char *name;
char *value;
}NODE,*PNODE;
class CNodeList : public list<PNODE>
{
public:
virtual ~CNodeList()
{
PNODE pnode = NULL;
list<PNODE>::iterator iter = begin();
while(!empty())
{
pnode = front();
delete pnode;
pop_front();
}
clear();
}
void print(CLog* plog)
{
list<PNODE>::iterator iter = begin();
while(iter != end())
{
(*iter++)->print(plog);
}
}
};
typedef CNodeList* PNODELIST;
typedef map<const char*,PNODELIST,eq_str_map> CIniMap;
class CConfig2Map : public CBase,public CIniMap
{
public:
~CConfig2Map()
{
PNODELIST pnodelist = NULL;
PNODE pnode = NULL;
char* pszname = NULL;
char* pszvalue = NULL;
CIniMap::iterator iter = begin();
while(iter!=end())
{
pszname = (char*)((*iter).first);
delete [] pszname;
delete (*iter).second;
iter++;
}
clear();
}
public:
static CConfig2Map* Instance(const char* pszinifilename)
{
if(!_instance)
_instance = new CConfig2Map(pszinifilename);
return _instance;
}
int getstring(const char* pszsection,const char* pszname,char* pszvalue,int buflen)
{
#ifdef _DEBUG
CLog log;
#endif
PNODELIST pnodelist = (*this)[pszsection];
if(pnodelist==NULL)
{
#ifdef _DEBUG
log.log(LOG_DBG,"section:%s not found",pszsection);
#endif
return 0;
}
#ifdef _DEBUG
log.log(LOG_DBG,"section:%s found",pszsection);
#endif
CNodeList::iterator iter = pnodelist->begin();
PNODE pnode = NULL;
int bfound = 0;
while(iter!=pnodelist->end())
{
#ifdef _DEBUG
log.log(LOG_DBG,"name=%s,value=%s",(*iter)->name,(*iter)->value);
#endif
if(!strcmp(pszname,(*iter)->name))
{
strncpy(pszvalue,(*iter)->value,buflen);
bfound = 1;
break;
}
iter++;
}
return bfound;
}
void print(CLog* plog)
{
const char* pszkey = NULL;
PNODELIST pnodelist = NULL;
CIniMap::iterator iter = begin();
plog->log(LOG_DBG,"++++++++++++++++begin print mapconfig+++++++++++++++++");
while(iter!=end())
{
plog->log(LOG_DBG,"section=%s",(*iter).first);
pnodelist = (*iter).second;
pnodelist->print(plog);
iter++;
}
plog->log(LOG_DBG,"++++++++++++++++print mapconfig end ++++++++++++++++++");
}
private:
CConfig2Map(const char* pszinifilename) throw(const char*);
private:
static CConfig2Map* _instance;
};
#endif //_CONFIG2MAP_H_
config2map.cpp
#include "config2map.h"
CConfig2Map* CConfig2Map::_instance = NULL;
CConfig2Map::CConfig2Map(const char* pszinifilename) throw(const char*)
{
#ifdef _DEBUG
CLog log;
#endif
FILE* pfile = fopen(pszinifilename, "r");
char* pszerrmsg;
if(!pfile)
{
pszerrmsg = new char[1024];
memset(pszerrmsg,0x00,1024);
SNPRINTF(pszerrmsg,1023,"failed to open file [%s]",pszinifilename);
throw(pszerrmsg);
}
#ifdef _DEBUG
int ireadline = 0;
#endif
char szBuf[1024] = {0};
int buflen = 0;
char* key;
char* keybegin,*keyend;
int bkeyendfound = 0;
PNODELIST pnodelist = NULL;
while(fgets(szBuf, 1023, pfile))
{
buflen = strlen(szBuf);
if(buflen<3)
continue;
if(buflen>=1)
{
if(szBuf[buflen-1]==0x0a || szBuf[buflen-1]==0x0d)
szBuf[buflen-1] = 0x00;
}
if(buflen>=2)
{
if(szBuf[buflen-2]==0x0a || szBuf[buflen-2]==0x0d)
szBuf[buflen-2] = 0x00;
}
#ifdef _DEBUG
log.log(LOG_DBG,"%d=%s",buflen,szBuf);
#endif
char* p = szBuf;
if(*p=='#' || *p=='\n' || *p=='\0') continue;
if(*p == '[')
{
#ifdef _DEBUG
printf("found [\n");
#endif
keybegin = p+1;
bkeyendfound = 0;
while(*p)
{
if(*p==']')
{
#ifdef _DEBUG
printf("found ]\n");
#endif
bkeyendfound = 1;
keyend = p-1;
break;
}
p++;
}
if(!bkeyendfound)
{
#ifdef _DEBUG
printf("key [] not match\n");
#endif
throw("key [] not match\n");
}
if(keybegin>keyend)
{
#ifdef _DEBUG
printf("invalid key[\"\"]\n");
#endif
throw("invalid key[""]");
}
key = new char[keyend-keybegin+1+1];
memset(key,0x00,keyend-keybegin+1+1);
strncpy(key,keybegin,keyend-keybegin+1);
//key[keyend-keybegin+1+1]='\0'; //2010-10-13:这个错误,找了一天啊
key[keyend-keybegin+1]='\0';
#ifdef _DEBUG
printf("new key=%s\n", key);
#endif
pnodelist = new CNodeList();
(*this)[key] = pnodelist;
continue;
}
while(*p && *p++!='=');
if(p==(szBuf+strlen(szBuf))) continue;
char name[256] = {0};
char value[1024] = {0};
strncpy(name, szBuf, p-szBuf-1);
strncpy(value, p, szBuf+strlen(szBuf)-p);
if(pnodelist==NULL)
{
#ifdef _DEBUG
printf("key not found,%s=%s discard\n",name,value);
#endif
}
else
{
PNODE pnode= new NODE(name,value);
pnodelist->push_back(pnode);
}
//proc(pvoid,key,value);
}
fclose(pfile);
}