configparser

来源:互联网 发布:acm杨辉三角c语言程序 编辑:程序博客网 时间:2024/05/16 12:52

#ifndef NEWSBEUTER_CONFIGPARSER__H
#define NEWSBEUTER_CONFIGPARSER__H

#include <vector>
#include <string>
#include <map>

//z 重点了解一下map 和 vector的使用。
namespace newsbeuter {

        enum action_handler_status { AHS_OK = 0, AHS_INVALID_PARAMS, AHS_TOO_FEW_PARAMS, AHS_INVALID_COMMAND };

        struct config_action_handler {
                //z action使用string,然后参数使用了vector来进行存储。
                virtual action_handler_status handle_action(const std::string& action, const std::vector<std::string>& params) = 0;//z 纯虚函数
                virtual ~config_action_handler() { }
        };

        //z 对配置文件进行解析
        class configparser {
                public:
                        configparser(const char * file);
                        ~configparser();
                        void parse();
                        void register_handler(const std::string& cmd, config_action_handler * handler);
                        void unregister_handler(const std::string& cmd);
                private:
                        //z 文件名称
                        std::string filename;
                        //z 解析的内容,每个vector中存放的是一个vector<string>
                        std::vector<std::vector<std::string> > parsed_content;
                        //z string对用config_action_handler指针。
                        std::map<std::string,config_action_handler *> action_handlers;
        };

}

#endif

 

 

 

#include <configparser.h>
#include <xmlpullparser.h>
#include <exceptions.h>
#include <utils.h>
#include <fstream>
#include <sstream>

namespace newsbeuter {

//z ctor 构造函数中有文件名称
configparser::configparser(const char * file) : filename(file) { }

configparser::~configparser() { }

//z 对文件进行解析
void configparser::parse() {
        //z 打开文件
        std::fstream f(filename.c_str());
        std::string line;
        //z 读取行
        getline(f,line);
        
        while (f.is_open() && !f.eof()) {
                //z 从line中得到token
                std::vector<std::string> tokens = utils::tokenize_config(line); // TODO: write other tokenizer
                //z 如果大于0
                if (tokens.size() > 0) {
                        //z 命令 参数1 参数2 参数3 。。。
                        std::string cmd = tokens[0];
                        //z 从cmd中得到相应的handler
                        config_action_handler * handler = action_handlers[cmd];
                        
                        //z 如果不为NULL
                        if (handler) {
                                //z 将第一个元素去除(cmd)
                                tokens.erase(tokens.begin()); // delete first element
                                //z 从然后调用handler的函数,通过将命令和参数传递给该函数。
                                action_handler_status status = handler->handle_action(cmd,tokens);
                                
                                //z 完事了检查状态。
                                if (status != AHS_OK) {
                                        std::ostringstream os;
                                        os << "Error while processing command `" << cmd << "': ";
                                        if (status == AHS_INVALID_PARAMS) {
                                                os << "invalid parameters.";
                                        } else if (status == AHS_TOO_FEW_PARAMS) {
                                                os << "too few parameters.";
                                        } else if (status == AHS_INVALID_COMMAND) {
                                                os << "unknown command (bug).";
                                        } else {
                                                os << "unknown error (bug).";
                                        }
                                        throw configexception(os.str());
                                }
                        } else {
                                //z 如果为NULL,没有找到该命令
                                std::ostringstream os;
                                os << "unknown command `" << cmd << "'";
                                throw configexception(os.str());
                        }
                }
                getline(f,line);        
        }
}

//z 注册命令
//z 从上一个函数来看,在调用之前需要先注册该函数。
void configparser::register_handler(const std::string& cmd, config_action_handler * handler) {
        action_handlers[cmd] = handler;
}

//z 取消对cmd的注册
void configparser::unregister_handler(const std::string& cmd) {
        action_handlers[cmd] = 0;
}

}