#ifndef __PARSE_INI_H__ #define __PARSE_INI_H__
#include <vector> #include <string> #include <fstream> #include <windows.h>
#define INI_KEY_LINE 1 #define INI_SECTION_LINE 2 #define INI_COMMENT_LINE 3 #define INI_NC_KEY_LINE 4 #define INI_WORNG_SYNTAX 0
using namespace std;
class CParseIniA {
public: CParseIniA() {} ~CParseIniA() {}
BOOL Open(const string &IniPath;, BOOL OpenAlways = TRUE); vector EnumSectionNames(); vector EnumKeyNamesInSection(const string &SectionName;); string GetSectionKeyValue(const string &SectionName;, const string &KeyName;, const string &DefaultValue;); int GetSectionKeyValueInt(const string &SectionName;, const string &KeyName;, int DefaultValue); BOOL SetSectionKeyValueInt(const string &SectionName;, const string &KeyName;, int value, BOOL CreateNew = TRUE); BOOL SetSectionKeyValue(const string &SectionName;, const string &KeyName;, const string &Value;, BOOL CreateNew = TRUE); BOOL Flush(); VOID Close();
private: ULONG SyntaxCheck(const string &KeyLine;); vector::iterator CreateSection(const string &SectionName;); VOID CreateKeyValue(vector::iterator it, const string &KeyName;, const string &Value;); BOOL IsSection(string &Line;); BOOL SetKeyValue(string &Line;, const string &Value;); string GetKeyValue(string &Line;); string GetSectionName(string &Line;); string GetKeyName(string &Line;); string trim(const string& s ,const string& drop = " "); vector m_IniContext; string m_IniPath; };
inline BOOL CParseIniA::Open( const string &IniPath;, BOOL OpenAlways) { ifstream IniFile(IniPath.c_str()); INT FileSize; vector::iterator it;
if (!IniFile.is_open()) {
if (!OpenAlways) {
return FALSE; }
m_IniPath = IniPath;
return TRUE;
}
m_IniPath = IniPath;
IniFile.seekg(0, std::ios_base::end); FileSize = IniFile.tellg(); IniFile.seekg(0, std::ios_base::beg); if (FileSize == 0) {
return TRUE; }
while (IniFile) { string IniLine; getline(IniFile, IniLine);
m_IniContext.push_back(IniLine); }
it = m_IniContext.end(); it--; while (trim(*it).empty()) {
m_IniContext.pop_back(); it = m_IniContext.end(); it--; } return TRUE; }
inline BOOL CParseIniA::IsSection( string &Line; ) { string SectionLine = trim(Line); BOOL Ret = FALSE; if (SectionLine[0] == '[' && SectionLine[SectionLine.length() - 1] == ']') {
Ret = TRUE; }
return Ret; }
inline vector CParseIniA::EnumSectionNames() { vector SectionNames; vector::iterator it;
for (it = m_IniContext.begin(); it != m_IniContext.end(); ++it) {
if (IsSection(*it)) {
SectionNames.push_back(GetSectionName(*it)); } }
return SectionNames; }
inline vector CParseIniA::EnumKeyNamesInSection(const string &SectionName; ) { vector::iterator it; vector KeyNames; ULONG ScanState = 0;
for (it = m_IniContext.begin(); it != m_IniContext.end(); ++it) {
if (ScanState == 0) {
if (!IsSection(*it) || GetSectionName(*it) != SectionName) {
continue; }
ScanState = 1; } else if (ScanState == 1) {
if (IsSection(*it)) {
break; }
KeyNames.push_back(GetKeyName(*it)); } }
return KeyNames; }
inline string CParseIniA::GetSectionName( string &Line; ) { INT Count = Line.length(); INT i; BOOL Start = FALSE; string SectionName;
for (i = 0; i < Count; i++) {
if (Line[i] == '[') {
Start = TRUE; } else if (Line[i] == ']') {
if (Start) {
break; } } else {
if (Start) {
SectionName += Line[i]; continue; } } }
return SectionName; }
inline string CParseIniA::GetKeyName( string &Line; ) { string KeyName;
KeyName = Line.substr(0, Line.find_first_of('='));
return trim(KeyName); }
inline string CParseIniA::trim(const string& s, const string& drop) { string t(s); string r = t.erase(t.find_last_not_of(drop) + 1); return r.erase(0,r.find_first_not_of(drop)); }
inline int CParseIniA::GetSectionKeyValueInt( const string &SectionName;, const string &KeyName;, int DefaultValue ) { char DefaultValueString[32] = {0}; sprintf_s(DefaultValueString, "%d", DefaultValue); string ValueString = GetSectionKeyValue(SectionName, KeyName, DefaultValueString); return atoi(ValueString.c_str()); }
inline string CParseIniA::GetSectionKeyValue(const string &SectionName;, const string &KeyName;, const string &DefaultValue; ) { vector::iterator it; ULONG ScanState = 0; string Value = DefaultValue;
for (it = m_IniContext.begin(); it != m_IniContext.end(); ++it) {
if (ScanState == 0) {
if (!IsSection(*it) || GetSectionName(*it) != SectionName) {
continue; }
ScanState = 1; } else if (ScanState == 1) {
if (IsSection(*it)) {
break; }
if (SyntaxCheck(*it) != INI_KEY_LINE) {
continue; }
if (GetKeyName(*it) == KeyName) {
Value = GetKeyValue(*it); } } }
return Value; }
inline string CParseIniA::GetKeyValue( string &Line; ) { string KeyName;
KeyName = Line.substr(Line.find_first_of('=') + 1); return trim(KeyName); }
inline BOOL CParseIniA::SetKeyValue( string &Line;, const string &Value; ) { INT Pos = Line.find_first_of('=');
if (Pos == string::npos) {
return FALSE; }
Pos = Line.find_first_not_of(' ', Pos + 1);
if (Pos == string::npos) {
Pos = Line.find_first_of('=') + 1; }
Line.erase(Pos); Line += Value;
return TRUE; }
inline BOOL CParseIniA::SetSectionKeyValueInt( const string &SectionName;, const string &KeyName;, int Value, BOOL CreateNew ) { char ValueString[32] = {0}; sprintf_s(ValueString, "%d", Value); return SetSectionKeyValue(SectionName, KeyName, ValueString, CreateNew); }
inline BOOL CParseIniA::SetSectionKeyValue( const string &SectionName;, const string &KeyName;, const string &Value;, BOOL CreateNew ) { vector::iterator it; ULONG ScanState = 0; BOOL Ret = FALSE;
for (it = m_IniContext.begin(); it != m_IniContext.end(); ++it) {
if (ScanState == 0) {
if (!IsSection(*it) || GetSectionName(*it) != SectionName) {
continue; }
ScanState = 1; } else if (ScanState == 1) {
if (IsSection(*it)) {
break; }
if (SyntaxCheck(*it) == INI_KEY_LINE || SyntaxCheck(*it) == INI_NC_KEY_LINE) {
if (GetKeyName(*it) == KeyName) {
Ret = SetKeyValue(*it, Value); } } } }
if (CreateNew && !Ret) {
if (ScanState == 0) {
it = CreateSection(SectionName); CreateKeyValue(it, KeyName, Value); } else if (ScanState == 1) {
it--; CreateKeyValue(it, KeyName, Value); }
Ret = TRUE; }
return Ret; }
inline BOOL CParseIniA::Flush() { ofstream IniFile(m_IniPath.c_str()); vector::iterator it;
if (!IniFile.is_open()) {
return FALSE; }
for (it = m_IniContext.begin(); it != m_IniContext.end(); ++it) {
IniFile << it->c_str() << endl; }
return TRUE; }
inline VOID CParseIniA::Close() { }
inline vector::iterator CParseIniA::CreateSection( const string &SectionName; ) { string FullSectionName; vector::iterator it;
FullSectionName += '['; FullSectionName += SectionName; FullSectionName += ']';
m_IniContext.push_back(FullSectionName); it = m_IniContext.begin() + m_IniContext.size() - 1;
return it; }
inline VOID CParseIniA::CreateKeyValue( vector::iterator it, const string &KeyName;, const string &Value; ) { string KeyInfo;
KeyInfo += KeyName; KeyInfo += " = "; KeyInfo += Value; while (it != m_IniContext.begin()) {
if (!trim(*it).empty()) {
break; }
it--; }
m_IniContext.insert(it + 1, KeyInfo); }
inline ULONG CParseIniA::SyntaxCheck( const string &KeyLine; ) { string Line = trim(KeyLine); INT Pos, CommentPos1, CommentPos2; string KeyName; string Value; if (IsSection(Line)) {
return INI_SECTION_LINE; } else if (Line[0] == ';' || Line[0] == '#') {
return INI_COMMENT_LINE; } else {
Pos = Line.find_first_of('='); if (string::npos == Pos) {
return INI_WORNG_SYNTAX; }
KeyName = trim(Line.substr(0, Pos)); if (KeyName.empty()) {
return INI_WORNG_SYNTAX; }
Value = trim(Line.substr(Pos + 1)); if (Value.empty()) {
return INI_NC_KEY_LINE; }
CommentPos1 = Value.find_first_of(';'); CommentPos2 = Value.find_first_of('#'); if (CommentPos1 == string::npos && CommentPos2 == string::npos) {
return INI_KEY_LINE; }
CommentPos1 = CommentPos1 < CommentPos2 ? CommentPos1 : CommentPos2;
if (Value.erase(CommentPos1).empty()) {
return INI_NC_KEY_LINE; } return INI_KEY_LINE; } }
#endif
|