类似于INI格式的配置文件的加载及解析

/*
 ******************************************************************
 *    NAME: config.cpp
 *    DESC:
 *  AUTHOR: Liu Dongguo([email protected])
 * VERSION: 1.0
 *  CREATE: 2015-04-13 01:06:28
 *  LUTIME: 2015-04-14 16:43:37
 *
 * Copyright (c) 2007 - 2015 Abodu.com, Inc. All Rights Reserved
 *
 *****************************************************************
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "config.h"
#define MAX_LINE_LEN  1024

//for read ini file
#define chCOMMENT1   ';'
#define chCOMMENT2   '#'
#define chSECT_START '['
#define chSPLITER    '='
#define chWHITESPACE ' '
#define strFmtREADLINE "\n%[^\n]"

#include <map>
#include <string>
using std::map;
using std::string;
static map<string,string> g_ppmap;

static bool g_bLoad=false;
static char g_szCfgFn[MAX_LINE_LEN]={0};
static char* g_pBufTotalFile=NULL;

static char* addItemIntoMap(char* beginOffset);

void load(const char* cfgname) {
    //read total file content into bufTotalFile
    FILE* fp= fopen(cfgname,"r");
    if(!fp) {
        printf("failed to open config file : %s\n",cfgname);
        return ;
    }
    fseek(fp, 0L,SEEK_END);
    int cfgLen=ftell(fp);
    fseek(fp, 0L,SEEK_SET);
    if(g_pBufTotalFile){
        delete g_pBufTotalFile;
    }
    g_pBufTotalFile= new char[cfgLen];
    fread(g_pBufTotalFile,sizeof(char),cfgLen,fp);
    fclose(fp);

    //add all valid items into map
    char* q=g_pBufTotalFile;
    char* p=0;
    while((p=addItemIntoMap(q))) 
        q=p;

    g_bLoad=true;
    strcpy(g_szCfgFn,cfgname); //save the loaded config filename
}
/*
 * @brief  : get key and val
 * @return :
 *     current offset from the beginning of bufTotalFile
 * @note   : if an item's format error, would not added into map
 */
char* addItemIntoMap(char* bos) {
    char line[1024]={0};
    char* pc=strchr(bos,'\n');
    if(!pc) {//reach the end of buf,return NULL
        strcpy(line,bos);
    } else { 
        strncpy(line,bos,pc-bos);
        while(*pc=='\n')
            pc++;
    }

    if(line[0]!=chCOMMENT1&&line[0]!=chCOMMENT2&&line[0]!=0
        &&line[0]!=chSPLITER&&line[0]!=chSECT_START)
    {
        char* key= line;
        char* val=strchr(key,chSPLITER);
        if(!val)
        {
            val=strchr(key,chWHITESPACE);
        }
        if(val)
        {
            *val++= 0;
            // remove extra whitespaces
            char valStore[512]= {0};
            char keyStore[512]= {0};
            sscanf(key,"%s",keyStore);
            sscanf(val,"%s",valStore);
            if(strlen(valStore) && strlen(keyStore)
                &&(valStore[0]!=chSPLITER)&&(valStore[0]!=chCOMMENT1)
                &&(valStore[0]!=chCOMMENT2))
            {
                g_ppmap[keyStore]=valStore;
            }
        }
    }
    return pc;
}
//////////////////////////////////////////////////////////
char* getParam(const char* Name) {
    if(g_bLoad && (g_ppmap.find(Name)!= g_ppmap.end())) {
        return (char*)g_ppmap[Name].data();
    }
    return (char*)"";
}

void  setParam(const char* Name,const char* Val) {
    if(g_bLoad) {
        g_ppmap[Name]=Val;
    }
}

void  listAllParams(void) {
    if(g_bLoad && g_ppmap.size()>0) {
        map<string,string>::iterator it=g_ppmap.begin();
        for(;it!=g_ppmap.end();it++)
            printf("%s=%s\n",it->first.data(),it->second.data());
    }
}

void  reload(void) {
    if(g_bLoad) {
        g_ppmap.clear(); //empty map first and load cfg again
        load(g_szCfgFn);
    }
}

#ifdef TEST_SO
int main(int argc, char* argv[]) {
    loadCfg(argv[1]);
    printf("\n1\n");
    listAll();
    setParam("ewt","baba");
    printf("\n2\n");
    listAll();
    printf( "\newt= %s\n",pget("ewt"));
    reload();
    printf("\n3\n");
    listAll();
    return 0;
}
#endif     /* -----  TEST_SO  ----- */

猜你喜欢

转载自blog.csdn.net/liudglink/article/details/45200685