C++内存INI文件

这套代码适用于从服务器拉取INI,而不用保存到文件,而且是跨平台的.支持Unicode和Ansi.

而Windows 那套INI API先不说和平台绑死,他一定要访问文件的.


/*
王锐.2012.8.31
*/

#pragma once

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



template<typename T>
class CMemIni
{
private:
template<typename T>
class CSection
{
public:
private:
friend CMemIni;
std::map<T, T> mValues;
};
std::map<T, CSection<T>> mSections;

std::vector<T>
split(const T& source,
const int delimiter)
{
std::vector<T> result;
T input = source;
int lastIndex = 0;
for (int index = 0; index < input.size(); index ++)
{
while(true)
{
if (input[lastIndex] == 0x0a)
{
lastIndex ++;
}
else
break;
}
int c = input[index];
if(c == delimiter)
{
T substr = input.substr(lastIndex, index - lastIndex);
lastIndex = index + 1;
result.push_back(substr);

}
}
T substr = input.substr(lastIndex, T::npos);
result.push_back(substr);

return result;
}

T trimleft(const T& str)
{
T::size_type pos = str.find_first_not_of(' ');
if (pos == T::npos)
{
return str;
}
return str.substr(pos);
}

T trim(const T& str)
{
T::size_type pos = str.find_first_not_of(' ');
if (pos == T::npos)
{
return str;
}
T::size_type pos2 = str.find_last_not_of(' ');
if (pos2 != T::npos)
{
return str.substr(pos, pos2 - pos + 1);
}
return str.substr(pos);
}

T breakline(T & v)
{
v+='\r';
v+='\n';
return v;
}
public:
CMemIni(T text)
{
setText(text);
}

CMemIni()
{
setText(text);
}

void setText(T text)
{
mSections.clear();
std::vector<T>? lines = split(text, 0x0d);

int ln = 0;

while(ln < lines.size())
{
T line? = trim(lines[ln]);
ln ++;
if(line.size() > 0)
{
if(line[0] == '[' && line[line.size()-1] == ']')
{
CSection<T>? currentSection;
T currentSectionName = line.substr(1, line.size() - 2);
while(ln < lines.size())
{
line = lines[ln];
if((line.size() > 0))
{
if((line[0] == '[' && line[line.size()-1] == ']'))
{
break;
}
else
{
std::vector<T> keyvalue = split(line, '=');
if(keyvalue.size()>0)
{
T _key = trim(keyvalue[0]);
T _value;
if(keyvalue.size()>1)
_value = keyvalue[1];
currentSection.mValues[_key] = _value;
}
}
}
ln++;
}
mSections[currentSectionName] = currentSection;
}
}
}
}

T getText()
{
T? ret;

//
for(std::map<T, CSection<T>>::iterator? i = mSections.begin(); i!= mSections.end(); ++i)
{
CSection<T> & currentSection = i->second;
if(currentSection.mValues.size() > 0)
{
//
T? line;
line = '[';
line += i->first;
line += ']';

ret += breakline(line);
//
for(std::map<T, T>::iterator i = currentSection.mValues.begin(); i!= currentSection.mValues.end();i++)
{
T? _key = i->first;
T? _value = i->second;
line = _key;
line += '=';
line += _value;
ret += breakline(line);
}
}
}

return ret;
}

void removeSection(T section)
{
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s != mSections.end())
mSections.erase(s);
}

void removeKey(T section, T key)
{
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s==mSections.end())
return;
CSection<T>&? currentSection = s->second;
std::map<T, T>::iterator? k = currentSection.mValues.find(key);
if (k != currentSection.mValues.end())
currentSection.mValues.erase(k);
}

bool hasSection(T section)
{
CSection<T>? currentSection;
std::map<T, CSection<T>>::iterator s = mSections.find(section);
return (s!=mSections.end());
}

bool hasKey(T section, T key)
{
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s==mSections.end())
return false;
CSection<T>&? currentSection = s->second;
std::map<T, T>::iterator? k = currentSection.mValues.find(key);
return (k != currentSection.mValues.end());
}

std::vector<T> getSections()
{
std::vector<T>? ret;
for(std::map<T, CSection<T>>::iterator s = mSections.begin(); s != mSections.end(); s++)
{
ret.push_back(s->first);
}
return ret;
}

std::vector<T> getKeys(T section)
{
std::vector<T>? ret;
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s != mSections.end())
{
CSection<T>&? currentSection = s->second;
for(std::map<T, T>::iterator? k = currentSection.mValues.begin();
k != currentSection.mValues.end(); k ++)
{
ret.push_back(k->first);
}
}
return ret;
}

T readStr(T section, T key, T defValue)
{
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s==mSections.end())
return defValue;
CSection<T>&? currentSection = s->second;
std::map<T, T>::iterator? k = currentSection.mValues.find(key);
if(k == currentSection.mValues.end())
return defValue;
return currentSection.mValues[key];
}

void writeStr(T section, T key, T _Value)
{
CSection<T>? currentSection;
std::map<T, CSection<T>>::iterator s = mSections.find(section);
if(s!=mSections.end())
currentSection = s->second;
currentSection.mValues[key] = _Value;
mSections[section] = currentSection;
}
};

typedef CMemIni<std::wstring> CWideMemIni;
typedef CMemIni<std::string>? CAnsiMemIni;

#ifdef UNICODE
#define?? CTMemIni CWideMemIni
#else
#define?? CTMemIni CAnsiMemIni
#endif

此条目发表在CPP, 未分类分类目录。将固定链接加入收藏夹。