萍乡邂逅酒吧:单实例模式的一个C++读取配置文件的类CConfig2Map - 高性能服务器开发;C++...

来源:百度文库 编辑:偶看新闻 时间:2024/04/20 17:05:55
由于项目中经常遇到读取配置文件的地方,为方便调用虽写了个功能简单,使用方便的配置文件类,基本思路是将配置文件缓冲到map当中,目前只支持一级配置,多级别的树形配置暂不支持,有需要的兄弟请完善。
为单实例模式。
config2map.h
// config2map.h
// 配置文件到map的映射类,单实例模式
// 创建: 2010-09-13 changym, changup@qq.com
// 修改: 
//       
/**///////////////////////////////////////////////////////////////////////
#ifndef _CONFIG2MAP_H_
#define _CONFIG2MAP_H_
#include 
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
{
public:
    virtual ~CNodeList()
    {
        PNODE pnode = NULL;
        list::iterator iter = begin();
        while(!empty())
        {
            pnode = front();
            delete pnode;
            pop_front();
        }
        clear();
    }
    void print(CLog* plog)
    {
        list::iterator iter = begin();
        while(iter != end())
        {
            (*iter++)->print(plog); 
        }
    }
};
typedef CNodeList* PNODELIST;
typedef 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);
}