confparse

来源:互联网 发布:js中给单选框点击事件 编辑:程序博客网 时间:2024/06/06 04:56
#example.confkey0=v0key1=v1,v2[TT]key2=v2key3=v3#example1.confkey0=v0key1=v1,v2key3=v3/*************************************************************************    > File Name: confparse.h    > Author: wangzhicheng    > Mail: 2363702560@qq.com     > Created Time: Wed 12 Jul 2017 08:29:26 PM AWST ************************************************************************/#ifndef CONF_PARSE_H#define CONF_PARSE_H#include <string>#include <vector>#include <map>#include <set>#include <fstream>#include <sstream>#include <algorithm>namespace confparse{using namespace std;class ConfParse;class InnerKey{friend class ConfParse;private:map<string, set<string> >m_mapInner;// key -- inner key value -- inner valueprivate:inline void Insert(const string &key, const set<string>&value){m_mapInner.insert(make_pair(key, value));}inline void Clear(){m_mapInner.clear();}inline bool Empty(){return m_mapInner.empty();}void GetValue(const string &key, vector<string>&value);};class ConfParse{private:char m_cCommentChar;// comment line generally #char m_cSplitChar_kv;// split char between key and value generally =char m_cSplitChar_vv;// split char between value and value generally ,map<string, InnerKey>m_mapConf;// key -- outside keypublic:ConfParse(char comment = '#', char split0 = '=', char split1 = ','):m_cCommentChar(comment), m_cSplitChar_kv(split0), m_cSplitChar_vv(split1){}/* * @brief read conf file and init m_mapConf * */bool Init(const char *filename);/* * @brief locate value * */void GetValue(const string &firstkey, const string &secondkey, vector<string>&values);~ConfParse(){}};}#endif/*************************************************************************    > File Name: confparse.cpp    > Author: wangzhicheng    > Mail: 2363702560@qq.com     > Created Time: Wed 12 Jul 2017 08:29:26 PM AWST ************************************************************************/#include "confparse.h"namespace confparse{void InnerKey::GetValue(const string &key, vector<string>&value){auto it = m_mapInner.find(key);if(it == m_mapInner.end()) return;set<string>&_value = it->second;value.clear();value.resize(_value.size());copy(begin(_value), end(_value), begin(value));}bool ConfParse::Init(const char *filename){if(!filename) return false;ifstream fstream(filename);if(!fstream) return false;string line;string newline;string lastfirstkey;string firstkey;string secondkey;string value;string::size_type size, pos;set<string>values;InnerKey innerKey;m_mapConf.clear();while(!fstream.eof()){fstream >> line;if(line.empty()) continue;// skip empty lineif('#' == line[0]) continue;// skip comment linesize = line.size();// get [key]if(('[' == line[0]) && (']' == line[size - 1])){firstkey.assign(line, 1, size - 2);if(lastfirstkey != firstkey)// a new [] begin{m_mapConf.insert(make_pair(lastfirstkey, innerKey));lastfirstkey = firstkey;innerKey.Clear();}continue;}// get inner key and valuesif((pos = line.find(m_cSplitChar_kv)) != string::npos){secondkey.assign(line, 0, pos);newline.assign(line, pos + 1, size);for(auto it = begin(newline);it != end(newline);++it){if(m_cSplitChar_vv == *it) *it = ' ';}istringstream ss(newline);values.clear();while(ss >> value) {values.insert(value);}innerKey.Insert(secondkey, values);}line.clear();}if(!innerKey.Empty()) m_mapConf.insert(make_pair(firstkey, innerKey));fstream.close();return !m_mapConf.empty();}void ConfParse::GetValue(const string &firstkey, const string &secondkey, vector<string>&values){values.clear();auto it = m_mapConf.find(firstkey);if(it == m_mapConf.end()) return;InnerKey &innerKey = it->second;innerKey.GetValue(secondkey, values);}}TEST(ConfParse, TestInit){const char *path = "/home/wangzhicheng/C++/simple/confParse/example.conf";ConfParse confParse;EXPECT_EQ(true, confParse.Init(path));}TEST(ConfParse, TestGet){vector<string>values;const char *path = "/home/wangzhicheng/C++/simple/confParse/example.conf";ConfParse confParse;EXPECT_EQ(true, confParse.Init(path));confParse.GetValue("", "key0", values);EXPECT_EQ(1, values.size());EXPECT_EQ("v0", values[0]);confParse.GetValue("", "key1", values);EXPECT_EQ(2, values.size());EXPECT_EQ("v2", values[1]);confParse.GetValue("TT", "key3", values);EXPECT_EQ("v3", values[0]);EXPECT_EQ(1, values.size());path = "/home/wangzhicheng/C++/simple/confParse/example1.conf";EXPECT_EQ(true, confParse.Init(path));confParse.GetValue("", "key1", values);EXPECT_EQ("v2", values[1]);EXPECT_EQ(2, values.size());}