|
|
@ -0,0 +1,811 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include "inifile.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace inifile
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 构造函数,会初始化注释字符集合flags_(容器),目前只使用#和;作为注释前缀
|
|
|
|
|
|
|
|
IniFile::IniFile()
|
|
|
|
|
|
|
|
:commentDelimiter("#")
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//解析一行数据,得到键值
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief parse
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param content 数据源指针
|
|
|
|
|
|
|
|
* @param key 键名
|
|
|
|
|
|
|
|
* @param value 键值
|
|
|
|
|
|
|
|
* @param c 分隔符
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return bool
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
bool IniFile::parse(const string &content, string *key, string *value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return split(content, "=", key, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::UpdateSection(const string &cleanLine, const string &comment,
|
|
|
|
|
|
|
|
const string &rightComment, IniSection **section)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *newSection;
|
|
|
|
|
|
|
|
// 查找右中括号
|
|
|
|
|
|
|
|
size_t index = cleanLine.find_first_of(']');
|
|
|
|
|
|
|
|
if (index == string::npos) {
|
|
|
|
|
|
|
|
errMsg = string("no matched ] found");
|
|
|
|
|
|
|
|
return ERR_UNMATCHED_BRACKETS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int len = index - 1;
|
|
|
|
|
|
|
|
// 若段名为空,继续下一行
|
|
|
|
|
|
|
|
if (len <= 0) {
|
|
|
|
|
|
|
|
errMsg = string("section name is empty");
|
|
|
|
|
|
|
|
return ERR_SECTION_EMPTY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 取段名
|
|
|
|
|
|
|
|
string s(cleanLine, 1, len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trim(s);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//检查段是否已存在
|
|
|
|
|
|
|
|
if (getSection(s) != NULL) {
|
|
|
|
|
|
|
|
errMsg = string("section ") + s + string("already exist");
|
|
|
|
|
|
|
|
return ERR_SECTION_ALREADY_EXISTS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 申请一个新段,由于map容器会自动排序,打乱原有顺序,因此改用vector存储(sections_vt)
|
|
|
|
|
|
|
|
newSection = new IniSection();
|
|
|
|
|
|
|
|
// 填充段名
|
|
|
|
|
|
|
|
newSection->name = s;
|
|
|
|
|
|
|
|
// 填充段开头的注释
|
|
|
|
|
|
|
|
newSection->comment = comment;
|
|
|
|
|
|
|
|
newSection->rightComment = rightComment;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sections_vt.push_back(newSection);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*section = newSection;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::AddKeyValuePair(const string &cleanLine, const string &comment,
|
|
|
|
|
|
|
|
const string &rightComment, IniSection *section)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string key, value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!parse(cleanLine, &key, &value)) {
|
|
|
|
|
|
|
|
errMsg = string("parse line failed:") + cleanLine;
|
|
|
|
|
|
|
|
return ERR_PARSE_KEY_VALUE_FAILED;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IniItem item;
|
|
|
|
|
|
|
|
item.key = key;
|
|
|
|
|
|
|
|
item.value = value;
|
|
|
|
|
|
|
|
item.comment = comment;
|
|
|
|
|
|
|
|
item.rightComment = rightComment;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section->items.push_back(item);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::Load(const string &filePath)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
string line; // 带注释的行
|
|
|
|
|
|
|
|
string cleanLine; // 去掉注释后的行
|
|
|
|
|
|
|
|
string comment;
|
|
|
|
|
|
|
|
string rightComment;
|
|
|
|
|
|
|
|
IniSection *currSection = NULL; // 初始化一个字段指针
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
release();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
iniFilePath = filePath;
|
|
|
|
|
|
|
|
std::ifstream ifs(iniFilePath);
|
|
|
|
|
|
|
|
if (!ifs.is_open()) {
|
|
|
|
|
|
|
|
errMsg = string("open") +iniFilePath+ string(" file failed");
|
|
|
|
|
|
|
|
return ERR_OPEN_FILE_FAILED;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//增加默认段,即 无名段""
|
|
|
|
|
|
|
|
currSection = new IniSection();
|
|
|
|
|
|
|
|
currSection->name = "";
|
|
|
|
|
|
|
|
sections_vt.push_back(currSection);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 每次读取一行内容到line
|
|
|
|
|
|
|
|
while (std::getline(ifs, line)) {
|
|
|
|
|
|
|
|
trim(line);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// step 0,空行处理,如果长度为0,说明是空行,添加到comment,当作是注释的一部分
|
|
|
|
|
|
|
|
if (line.length() <= 0) {
|
|
|
|
|
|
|
|
comment += delim;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// step 1
|
|
|
|
|
|
|
|
// 如果行首不是注释,查找行尾是否存在注释
|
|
|
|
|
|
|
|
// 如果该行以注释开头,添加到comment,跳过当前循环,continue
|
|
|
|
|
|
|
|
if (IsCommentLine(line)) {
|
|
|
|
|
|
|
|
comment += line + delim;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果行首不是注释,查找行尾是否存在注释,若存在,切割该行,将注释内容添加到rightComment
|
|
|
|
|
|
|
|
split(line, commentDelimiter, &cleanLine, &rightComment);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// step 2,判断line内容是否为段或键
|
|
|
|
|
|
|
|
//段开头查找 [
|
|
|
|
|
|
|
|
if (cleanLine[0] == '[') {
|
|
|
|
|
|
|
|
err = UpdateSection(cleanLine, comment, rightComment, &currSection);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 如果该行是键值,添加到section段的items容器
|
|
|
|
|
|
|
|
err = AddKeyValuePair(cleanLine, comment, rightComment, currSection);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (err != 0) {
|
|
|
|
|
|
|
|
ifs.close();
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// comment清零
|
|
|
|
|
|
|
|
comment = "";
|
|
|
|
|
|
|
|
rightComment = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ifs.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::Save()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return SaveAs(iniFilePath);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SaveAs(const string &filePath)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string data = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 载入section数据 */
|
|
|
|
|
|
|
|
for (IniSection_it sect = sections_vt.begin(); sect != sections_vt.end(); ++sect) {
|
|
|
|
|
|
|
|
if ((*sect)->comment != "") {
|
|
|
|
|
|
|
|
data += (*sect)->comment;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((*sect)->name != "") {
|
|
|
|
|
|
|
|
data += string("[") + (*sect)->name + string("]");
|
|
|
|
|
|
|
|
data += delim;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((*sect)->rightComment != "") {
|
|
|
|
|
|
|
|
data += " " + commentDelimiter +(*sect)->rightComment;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 载入item数据 */
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it item = (*sect)->items.begin(); item != (*sect)->items.end(); ++item) {
|
|
|
|
|
|
|
|
if (item->comment != "") {
|
|
|
|
|
|
|
|
data += item->comment;
|
|
|
|
|
|
|
|
if (data[data.length()-1] != '\n') {
|
|
|
|
|
|
|
|
data += delim;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data += item->key + "=" + item->value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (item->rightComment != "") {
|
|
|
|
|
|
|
|
data += " " + commentDelimiter + item->rightComment;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data[data.length()-1] != '\n') {
|
|
|
|
|
|
|
|
data += delim;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::ofstream ofs(filePath);
|
|
|
|
|
|
|
|
ofs << data;
|
|
|
|
|
|
|
|
ofs.close();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IniSection *IniFile::getSection(const string §ion /*=""*/)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
|
|
|
|
|
|
|
|
if ((*it)->name == section) {
|
|
|
|
|
|
|
|
return *it;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetSections(vector<string> *sections)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
|
|
|
|
|
|
|
|
sections->push_back((*it)->name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sections->size();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetSectionNum()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return sections_vt.size();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetStringValue(const string §ion, const string &key, string *value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return getValue(section, key, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetIntValue(const string §ion, const string &key, int *intValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
string strValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = getValue(section, key, &strValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*intValue = atoi(strValue.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetDoubleValue(const string §ion, const string &key, double *value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
string strValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = getValue(section, key, &strValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*value = atof(strValue.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetBoolValue(const string §ion, const string &key, bool *value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
string strValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = getValue(section, key, &strValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (StringCmpIgnoreCase(strValue, "true") || StringCmpIgnoreCase(strValue, "1")) {
|
|
|
|
|
|
|
|
*value = true;
|
|
|
|
|
|
|
|
} else if (StringCmpIgnoreCase(strValue, "false") || StringCmpIgnoreCase(strValue, "0")) {
|
|
|
|
|
|
|
|
*value = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取section段第一个键为key的string值,成功返回获取的值,否则返回默认值 */
|
|
|
|
|
|
|
|
void IniFile::GetStringValueOrDefault(const string §ion, const string &key,
|
|
|
|
|
|
|
|
string *value, const string &defaultValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (GetStringValue(section, key, value) != 0) {
|
|
|
|
|
|
|
|
*value = defaultValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取section段第一个键为key的int值,成功返回获取的值,否则返回默认值 */
|
|
|
|
|
|
|
|
void IniFile::GetIntValueOrDefault(const string §ion, const string &key, int *value, int defaultValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (GetIntValue(section, key, value) != 0) {
|
|
|
|
|
|
|
|
*value = defaultValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取section段第一个键为key的double值,成功返回获取的值,否则返回默认值 */
|
|
|
|
|
|
|
|
void IniFile::GetDoubleValueOrDefault(const string §ion, const string &key, double *value, double defaultValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (GetDoubleValue(section, key, value) != 0) {
|
|
|
|
|
|
|
|
*value = defaultValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取section段第一个键为key的bool值,成功返回获取的值,否则返回默认值 */
|
|
|
|
|
|
|
|
void IniFile::GetBoolValueOrDefault(const string §ion, const string &key, bool *value, bool defaultValue)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (GetBoolValue(section, key, value) != 0) {
|
|
|
|
|
|
|
|
*value = defaultValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取注释,如果key=""则获取段注释 */
|
|
|
|
|
|
|
|
int IniFile::GetComment(const string §ion, const string &key, string *comment)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key == "") {
|
|
|
|
|
|
|
|
*comment = sect->comment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
*comment = it->comment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 获取行尾注释,如果key=""则获取段的行尾注释 */
|
|
|
|
|
|
|
|
int IniFile::GetRightComment(const string §ion, const string &key, string *rightComment)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key == "") {
|
|
|
|
|
|
|
|
*rightComment = sect->rightComment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
*rightComment = it->rightComment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+key;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::getValue(const string §ion, const string &key, string *value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string comment;
|
|
|
|
|
|
|
|
return getValue(section, key, value, &comment);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::getValue(const string §ion, const string &key, string *value, string *comment)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
*value = it->value;
|
|
|
|
|
|
|
|
*comment = it->comment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+key;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetValues(const string §ion, const string &key, vector<string> *values)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
vector<string> comments;
|
|
|
|
|
|
|
|
return GetValues(section, key, values, &comments);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::GetValues(const string §ion, const string &key, vector<string> *values, vector<string> *comments)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string value, comment;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
values->clear();
|
|
|
|
|
|
|
|
comments->clear();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
value = it->value;
|
|
|
|
|
|
|
|
comment = it->comment;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
values->push_back(value);
|
|
|
|
|
|
|
|
comments->push_back(comment);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (values->size() == 0) {
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+key;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IniFile::HasSection(const string §ion)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (getSection(section) != NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IniFile::HasKey(const string §ion, const string &key)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect != NULL) {
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::setValue(const string §ion, const string &key, const string &value, const string &comment /*=""*/)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string comt = comment;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (comt != "") {
|
|
|
|
|
|
|
|
comt = commentDelimiter + comt;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
//如果段不存在,新建一个
|
|
|
|
|
|
|
|
sect = new IniSection();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("no enough memory!");
|
|
|
|
|
|
|
|
return ERR_NO_ENOUGH_MEMORY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sect->name = section;
|
|
|
|
|
|
|
|
if (sect->name == "") {
|
|
|
|
|
|
|
|
// 确保空section在第一个
|
|
|
|
|
|
|
|
sections_vt.insert(sections_vt.begin(), sect);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sections_vt.push_back(sect);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
it->value = value;
|
|
|
|
|
|
|
|
it->comment = comt;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// not found key
|
|
|
|
|
|
|
|
IniItem item;
|
|
|
|
|
|
|
|
item.key = key;
|
|
|
|
|
|
|
|
item.value = value;
|
|
|
|
|
|
|
|
item.comment = comt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sect->items.push_back(item);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetStringValue(const string §ion, const string &key, const string &value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return setValue(section, key, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetIntValue(const string §ion, const string &key, int value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[64] = {0};
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%d", value);
|
|
|
|
|
|
|
|
return setValue(section, key, buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetDoubleValue(const string §ion, const string &key, double value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[64] = {0};
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%f", value);
|
|
|
|
|
|
|
|
return setValue(section, key, buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetBoolValue(const string §ion, const string &key, bool value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
|
|
|
|
return setValue(section, key, "true");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return setValue(section, key, "false");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetComment(const string §ion, const string &key, const string &comment)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("Not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key == "") {
|
|
|
|
|
|
|
|
sect->comment = comment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
it->comment = comment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+key;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int IniFile::SetRightComment(const string §ion, const string &key, const string &rightComment)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect == NULL) {
|
|
|
|
|
|
|
|
errMsg = string("Not find the section ")+section;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_SECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key == "") {
|
|
|
|
|
|
|
|
sect->rightComment = rightComment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
it->rightComment = rightComment;
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errMsg = string("not find the key ")+key;
|
|
|
|
|
|
|
|
return ERR_NOT_FOUND_KEY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IniFile::SetCommentDelimiter(const string &delimiter)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
commentDelimiter = delimiter;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IniFile::DeleteSection(const string §ion)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ) {
|
|
|
|
|
|
|
|
if ((*it)->name == section) {
|
|
|
|
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
it = sections_vt.erase(it);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
it++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IniFile::DeleteKey(const string §ion, const string &key)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IniSection *sect = getSection(section);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sect != NULL) {
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it it = sect->begin(); it != sect->end();) {
|
|
|
|
|
|
|
|
if (it->key == key) {
|
|
|
|
|
|
|
|
it = sect->items.erase(it);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
it++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@brief release: 释放全部资源,清空容器
|
|
|
|
|
|
|
|
@param none
|
|
|
|
|
|
|
|
@return none
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
void IniFile::release()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
iniFilePath = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
|
|
|
|
|
|
|
|
delete (*it); // 清除section
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sections_vt.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@brief 判断是否是注释
|
|
|
|
|
|
|
|
@param str 一个string变量
|
|
|
|
|
|
|
|
@return 如果是注释则为真
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
bool IniFile::IsCommentLine(const string &str)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return StartWith(str, commentDelimiter);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@brief print for debug
|
|
|
|
|
|
|
|
@param none
|
|
|
|
|
|
|
|
@return none
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
void IniFile::print()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("############ print start ############\n");
|
|
|
|
|
|
|
|
printf("filePath:[%s]\n", iniFilePath.c_str());
|
|
|
|
|
|
|
|
printf("commentDelimiter:[%s]\n", commentDelimiter.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
|
|
|
|
|
|
|
|
printf("comment :[\n%s]\n", (*it)->comment.c_str());
|
|
|
|
|
|
|
|
printf("section :\n[%s]\n", (*it)->name.c_str());
|
|
|
|
|
|
|
|
if ((*it)->rightComment != "") {
|
|
|
|
|
|
|
|
printf("rightComment:\n%s", (*it)->rightComment.c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (IniSection::IniItem_it i = (*it)->items.begin(); i != (*it)->items.end(); ++i) {
|
|
|
|
|
|
|
|
printf(" comment :[\n%s]\n", i->comment.c_str());
|
|
|
|
|
|
|
|
printf(" parm :%s=%s\n", i->key.c_str(), i->value.c_str());
|
|
|
|
|
|
|
|
if (i->rightComment != "") {
|
|
|
|
|
|
|
|
printf(" rcomment:[\n%s]\n", i->rightComment.c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("############ print end ############\n");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const string & IniFile::GetErrMsg()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return errMsg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IniFile::StartWith(const string &str, const string &prefix)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (strncmp(str.c_str(), prefix.c_str(), prefix.size()) == 0) {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IniFile::trimleft(string &str, char c /*=' '*/)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int len = str.length();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (str[i] == c && str[i] != '\0') {
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i != 0) {
|
|
|
|
|
|
|
|
str = string(str, i, len - i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IniFile::trimright(string &str, char c /*=' '*/)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
int len = str.length();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = len - 1; i >= 0; --i) {
|
|
|
|
|
|
|
|
if (str[i] != c) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
str = string(str, 0, i + 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@brief trim,整理一行字符串,去掉首尾空格
|
|
|
|
|
|
|
|
@param str string变量
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
void IniFile::trim(string &str)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int len = str.length();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while ((i < len) && isspace(str[i]) && (str[i] != '\0')) {
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i != 0) {
|
|
|
|
|
|
|
|
str = string(str, i, len - i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
len = str.length();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = len - 1; i >= 0; --i) {
|
|
|
|
|
|
|
|
if (!isspace(str[i])) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
str = string(str, 0, i + 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@brief split,用分隔符切割字符串
|
|
|
|
|
|
|
|
@param str 输入字符串
|
|
|
|
|
|
|
|
@param left_str 分隔后得到的左字符串
|
|
|
|
|
|
|
|
@param right_str 分隔后得到的右字符串(不包含seperator)
|
|
|
|
|
|
|
|
@param seperator 分隔符
|
|
|
|
|
|
|
|
@return pos
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
bool IniFile::split(const string &str, const string &sep, string *pleft, string *pright)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t pos = str.find(sep);
|
|
|
|
|
|
|
|
string left, right;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pos != string::npos) {
|
|
|
|
|
|
|
|
left = string(str, 0, pos);
|
|
|
|
|
|
|
|
right = string(str, pos+1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trim(left);
|
|
|
|
|
|
|
|
trim(right);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*pleft = left;
|
|
|
|
|
|
|
|
*pright = right;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
left = str;
|
|
|
|
|
|
|
|
right = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trim(left);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*pleft = left;
|
|
|
|
|
|
|
|
*pright = right;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IniFile::StringCmpIgnoreCase(const string &str1, const string &str2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string a = str1;
|
|
|
|
|
|
|
|
string b = str2;
|
|
|
|
|
|
|
|
transform(a.begin(), a.end(), a.begin(), towupper);
|
|
|
|
|
|
|
|
transform(b.begin(), b.end(), b.begin(), towupper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (a == b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} /* namespace inifile */
|