INI 配置读取库发布

Github地址: https://github.com/owt5008137/libiniloader

OSChina镜像: http://git.oschina.net/owent/libiniloader

项目中经常会碰到需要读取配置的情况,而用ini配置最大的优势就是简单易懂。
但是现在很多的配置读取库都过于庞大了,比如Boost.PropertyTree,功能很强大,但是基本不会用到里面所有的东西。
另外微软的INI读取,功能不是很强不说,还限制在Windows上,更重要的是API设计得实在不优雅。
于是libiniloader就诞生啦。

这个库主要是用于提供一个跨平台并且简单易用的配置读取和转储方式,另一方面希望兼容很多开源组件的配置方式。(比如apache的httpd用#来注释)
再有就是借鉴PHP框架Zend Framework对ini的多个层级关系的扩展。这些奇怪的特性导致了ini loader对ini的支持和最初设计的ini格式略微有所差异。
主要有:

  • 支持Section
  • Secion支持父子关系,即 [ A : B : C ] 语法
  • 支持多重父子关系,如 C.B.A = d
  • 支持字符串转义,其中以’包裹的不进行转义,以”包裹的可进行转义,如 C.B.A = “Hello \r\n World!”
  • 配置的Key名称不能包含引号(‘和”)、点(.)、冒号(:)和方括号([])
  • 配置的Key名称区分大小写
  • #符号也将是做行注释,与 ; 等价

另外为了转储便利,专门设计了一组API用于快速数据。dump_to。它可以用于快速提取数据和转换格式。
并且为了方便配置,对于bool类型有特殊处理。即除 空字符串、no、0、disable、disabled、false外,其他所有值再转换为bool类型时都被视为true。

示例:
test.ini:

a.b.c1 = 123  # 整数
a.b.c2 = 1.23 ; 小数

[a : b:c:d]
e.f = "123456" ; 可转义字符串

e.f2 = '123456'; 不可转义字符串

[a]
b.c3 = 带空格    的 字符      串

arr = 1
arr = 2   
arr = 3   
arr =       一坨屎
arr =       /usr/local/gcc-4.8.2


bool = true
bool = false
bool = yes
bool = no
bool = enable
bool = disable
bool = 1
bool = 0

C++文件:

#include <vector>
#include <list>
#include <cstdio>
#include "ini_loader.h"


int main(){
    util::config::ini_loader cfg_loader;

    cfg_loader.load_file("test.ini");


    // 转储整数
    {
        int t1 = 9999, t2 = 9999;
        cfg_loader.dump_to("a.b.c1", t1);
        cfg_loader.dump_to("a.b.c4", t2, true);
        printf("a.b.c1 = %d\na.b.c4 = %d\n", t1, t2);
    }

    // 转储浮点数
    {
        float t1 = 0.0;
        cfg_loader.dump_to("a.b.c2", t1);
        printf("a.b.c2 = %f\n", t1);
    }

    // 转储字符串
    {
        char t1[32] = {0};
        std::string t2, t3 = "0000000000000000";
        std::string t4;

        cfg_loader.dump_to("d.c.b.a.e.f", t2); // 字符串
        cfg_loader.dump_to("d.c.b.a.e.f", t3.begin(), t3.end()); // 字符串迭代器
        cfg_loader.dump_to("d.c.b.a.e.f2", t1); // 字符串
        cfg_loader.dump_to("d.c.b.a.e.f2", t1 + 16, t1 + 32); // 字符串指针迭代器
        cfg_loader.dump_to("a.b.c3", t4); // 带不可打印字符的字符串

        printf("len(t2) = %d\nlen(t3) = %d\n", (int)t2.size(), (int)t3.size());
        printf("d.c.b.a.e.f2 = %s\n", t1);
        printf("d.c.b.a.e.f2 = %s(+16)\n", t1 + 16);
        printf("a.b.c3 = %s\n", t4.c_str());
    }

    // 转储到 vector
    {
        std::vector<std::string> t1;
        std::list<bool> t2;
        cfg_loader.dump_to("a.arr", t1);
        cfg_loader.dump_to("a.bool", t2);

        for (size_t i = 0; i < t1.size(); ++i) {
            printf("t1[%d] = %s\n", (int)i, t1[i].c_str());
        }

        size_t index = 0;
        for (std::list<bool>::iterator iter = t2.begin(); iter != t2.end(); ++iter) {
            printf("t2[%d] = %s\n", (int) index ++, (*iter) ? "true" : "false");
        }

    }

    return 0;
}

其他详细文档清参照 githuboschina 里的项目说明和ini_loader.h文件内注释。