ini库

代码主要是做练习用的,水平有限,路过的大神看到代码有哪里不好的请帮忙指出来,万分感谢。

​#pragma once

#include <map>
#include <list>
#include <unordered_map>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>

struct ValueElement
{
    std::string key = "";
    std::string value = "";
    std::string comment = "";
    std::string rcomment = "";
};

struct SectionElement
{
    std::string section = "";
    std::string comment = "";
    std::string rcomment = "";
    
    std::vector<ValueElement*> childs;
    std::unordered_map<std::string, ValueElement*> mapChilds;

    ~SectionElement()
    {
        for (auto e = childs.begin(); e != childs.end(); e++)
        {
            delete *e;
        }

        mapChilds.clear();
        childs.clear();
    }
};



class Setting
{
public:
    Setting(const char* file) : msFile(file)
    {
        //readSettings();
    }

    ~Setting()
    {
        save();
        clearAll();
    }

    void clearAll()
    {
        for (auto e = mvecElements.begin(); e != mvecElements.end(); e++)
        {
            delete* e;
        }
        mvecElements.clear();
        mmapElements.clear();
    }

    void removeGroup(const std::string&& group)
    {
        if (mmapElements.find(group) != mmapElements.end())
        {
            SectionElement* section = mmapElements[group];
            for (auto ss = mvecElements.begin(); ss != mvecElements.end(); ss++)
            {
                if ((*ss)->section == group)
                {
                    mvecElements.erase(ss);
                    mmapElements.erase(group);
                    delete section;
                    break;
                }
            } 
        }
    }

    bool contains(const std::string&& section, const std::string&& key)
    {
        if (mmapElements.find(section) != mmapElements.end() &&
            mmapElements.at(section)->mapChilds.find(key) != mmapElements.at(section)->mapChilds.end())
        {
            return true;
        }

        return false;
    }

    std::string fileName() const
    {
        return msFile;
    }

    void setValue(const std::string&& s, const std::string&& k, const std::string&& v)
    {
        std::string section(s);
        std::string key(k);
        std::string value(v);

        trim(section);
        trim(key);
        trim(value);

        if (mmapElements.find(section) != mmapElements.end())
        {
            if (mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
            {
                mmapElements[section]->mapChilds[key]->value = value;
            }
            else
            {
                ValueElement* op_elem = new ValueElement();
                op_elem->key = key;
                op_elem->value = value;
                mmapElements[section]->childs.push_back(op_elem);
                mmapElements[section]->mapChilds[key] = op_elem;
            }  
        }
        else
        {
            SectionElement* op_elem = new SectionElement();
            op_elem->section = section;
            op_elem->comment = "\n";
            mvecElements.push_back(op_elem);
            mmapElements[section] = op_elem;

            ValueElement* op_child_elem = new ValueElement();
            op_child_elem->key = key;
            op_child_elem->value = value;
            op_elem->childs.push_back(op_child_elem);
            op_elem->mapChilds[key] = op_child_elem;
        }

    }

    std::string value(const std::string&& section, const std::string&& key)
    {
        if (mmapElements.find(section) != mmapElements.end() && 
            mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
        {
            return mmapElements[section]->mapChilds[key]->value;
        }
        return std::string("");
    }

    void deleteKey(const std::string&& section, const std::string&& key)
    {
        if (mmapElements.find(section) != mmapElements.end() &&
            mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
        {
            ValueElement* child = mmapElements[section]->mapChilds[key];
            SectionElement* sec = mmapElements[section];

            for (auto ele = sec->childs.begin(); ele != sec->childs.end(); ele++)
            {
                if ((*ele)->key == key)
                {
                    sec->childs.erase(ele);
                    sec->mapChilds.erase(key);
                    delete (*ele);
                }
            }
        }   
    }

    std::list<std::string> allKeys()
    {
    }

    bool save()
    {
        return writeSettings();
    }

    bool load()
    {
        return readSettings();
    }

    std::string readStringValue(const std::string&& section, const std::string&& key)
    {
        return value(std::move(section), std::move(key));
    }

    int readIntValue(const std::string&& section, const std::string&& key)
    {
        std::string s = value(std::move(section), std::move(key));
        return stoi(s);
    }

    float readfloatValue(const std::string&& section, const std::string&& key)
    {
        std::string s = value(std::move(section), std::move(key));
        return stof(s);
    }

    double readDoubleValue(const std::string&& section, const std::string&& key)
    {
        std::string s = value(std::move(section), std::move(key));
        return stod(s);
    }

    bool readBoolValue(const std::string&& section, const std::string&& key)
    {
        std::string s = value(std::move(section), std::move(key));
        transform(s.begin(), s.end(), s.begin(), ::tolower);
        return s == "true" ? true : false;
    }

    void setIntValue(const std::string&& section, std::string&& key, int value)
    {
        setValue(std::move(section), std::move(key), std::to_string(value));
    }
    void setFloatValue(const std::string&& section, std::string&& key, float value)
    {
        setValue(std::move(section), std::move(key), std::to_string(value));
    }
    void setDoubleValue(const std::string&& section, std::string&& key, double value)
    {
        setValue(std::move(section), std::move(key), std::to_string(value));
    }
    void setBoolValue(const std::string&& section, std::string&& key, bool value)
    {
        std::string s = value == true ? "true" : "false";
        setValue(std::move(section), std::move(key), std::move(s));
    }

private:

    bool readSettings()
    {
        if (msFile.empty()) return false;

        std::ifstream ifs;
        ifs.open(msFile.c_str(), std::ios::in);
        if (!ifs.is_open())
        {
            return false;
        }

        std::string line;
        std::string s_comment = "";
        ValueElement* op_element = NULL;
        SectionElement* root_elem = NULL;
        
        while (std::getline(ifs, line))
        {
            trim(line);
            if (line == "" || line.at(0) == ';')
            {
                s_comment += line + "\n";
                continue;
            }

            if (line.at(0) == '[')
            {
                std::string str_session = "";
                std::string str_comment = "";
                parseSession(line, str_session, str_comment);
                root_elem = new SectionElement;
                root_elem->comment = s_comment;
                root_elem->rcomment = str_comment;
                root_elem->section = str_session;
                mvecElements.push_back(root_elem);
                mmapElements[str_session] = root_elem;
                s_comment = "";
                continue;
            }

            {
                std::string str_key = "";
                std::string str_value = "";
                std::string str_comment = "";
                parseChild(line, str_key, str_value, str_comment);
                op_element = new ValueElement;
                op_element->key = str_key;
                op_element->value = str_value;
                op_element->rcomment = str_comment;
                op_element->comment = s_comment;
                s_comment = "";

                if (root_elem == NULL)
                {
                    //error
                    return false;
                }
                else
                {
                    root_elem->childs.push_back(op_element);
                    root_elem->mapChilds[str_key] = op_element;
                }
            }
        }

        ifs.close();
        return true;
    }

    void parseSession(std::string& line, std::string& section, std::string& comment)
    {
        int i_index = line.find_first_of(']');
        if (i_index == -1)
        {
            return; //error
        }

        section = line.substr(1, i_index - 1);
        comment = line.substr(i_index + 1);
        trim(section);
        trim(comment);
    }

    void parseChild(std::string& line, std::string& key, std::string& value, std::string& comment)
    {
        int i_index_comment = line.find_first_of(';');
        int i_index_value = line.find_first_of('=');
        if (i_index_comment != -1)
        {
            comment = line.substr(i_index_comment);
            value = line.substr(i_index_value + 1, i_index_comment - 1 - i_index_value);
        }
        else
        {
            //comment = "";
            value = line.substr(i_index_value + 1);
        }
        
        
        key = line.substr(0, i_index_value);
        trim(key);
        trim(value);
        trim(comment);
        
    }

    bool writeSettings()
    {
        std::ofstream of;
        of.open(msFile, std::ios::out);
        if (!of.is_open())
        {
            return false;
        }

        for (SectionElement* elem : mvecElements)
        {
            of << elem->comment;
            of << "[" << elem->section << "]" << elem->rcomment + "\n";
            for (ValueElement* child : elem->childs)
            {
                of << child->comment;
                of << child->key << "=" << child->value << child->rcomment + "\n";
            }
        }

        of.close();
        return true;
    }

    void trim(std::string& s)
    {
        if (s.empty())
        {
            return;
        }
        s.erase(0, s.find_first_not_of(' '));
        s.erase(s.find_last_not_of(' ') + 1);
    }

private:
    std::vector<SectionElement*> mvecElements;
    std::unordered_map<std::string, SectionElement*> mmapElements;
    std::string msCurSection;
    std::string msFile;
    char* mBuff;
    int miFileSize;
};

void test()
{
    Setting s("Config.ini");
    s.load();
    s.setBoolValue(" sec1 ", "aa", false);
    s.setDoubleValue(" sys1 ", "bb", 1.1);
    //s.deleteKey("sec1", "bb");
    //s.removeGroup("sys1");
    s.save();
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值