ok, I completely re-did it. Is what I did any better than before?
INIFile.h
Code:
#ifndef INIFILE_H
#define INIFILE_H
#include <vector>
#include <map>
#include <string>
#include <fstream>
using namespace std;
struct KeyNode
{
string key;
map<string, string> vars;
};
class CINIFile
{
public:
vector<KeyNode> m_Keys;
public:
CINIFile();
~CINIFile();
bool LoadFile ( string filename );
bool ParseFile ( string filename );
bool GetIntValue ( string key, string var, int &val );
bool GetStringValue ( string key, string var, string &val );
bool GetBoolValue ( string key, string var, bool &val );
bool AddKey ( string key );
bool InsertKeyValues ( string key, string var, string val );
bool InsertKeyValues ( string key, map<string, string> m );
bool InsertKeyValues ( string var, string val );
bool InsertKeyValues ( map<string,string> m );
string StripChars ( string tags, string source );
map<string, string> SeparateAtChar ( const char separator, string source );
};
#endif
INIFile.cpp
Code:
#include "INIFile.h"
#include <iostream>
CINIFile::CINIFile()
{
}
CINIFile::~CINIFile()
{
}
//Main Functions
bool CINIFile::LoadFile ( string filename )
{
return ParseFile ( filename );
}
bool CINIFile::ParseFile ( string filename )
{
ifstream in ( filename.c_str() );
string buffer;
if ( !in.is_open() )
{
return false;
}
while ( in.good() )
{
getline ( in, buffer, '\n' );
//
//Figure out what to do based on the first character
//
if ( buffer.empty() )
{
}
else if ( buffer.at(0) == '[' ) //start new header
{
AddKey ( StripChars ( "[]", buffer ) );
}
else if ( buffer.at(0) == ';' || buffer.at(0) == '#' || buffer.at(0) == ' ' || buffer.at(0) == '\n') //comments or nothing
{
}
else //everything else!
{
InsertKeyValues ( SeparateAtChar ( '=', buffer ) );
}
}
return true;
}
bool CINIFile::AddKey ( string key )
{
KeyNode kn;
kn.key = key;
m_Keys.push_back ( kn );
return true;
}
bool CINIFile::InsertKeyValues ( string key, string var, string val )
{
vector<KeyNode>::iterator i;
for ( i = m_Keys.begin(); i != m_Keys.end(); ++i )
{
if ( i->key.compare ( key ) )
{
i->vars.insert ( map<string, string>::value_type ( var, val ) );
}
}
return true;
}
bool CINIFile::InsertKeyValues ( string var, string val )
{
m_Keys.back().vars.insert ( map<string, string>::value_type ( var, val ) );
return true;
}
bool CINIFile::InsertKeyValues ( map<string,string> m )
{
for ( map<string, string>::iterator i = m.begin(); i != m.end(); ++i )
{
m_Keys.back().vars.insert ( map<string, string>::value_type ( i->first, i->second ) );
}
return true;
}
bool CINIFile::InsertKeyValues ( string key, map<string,string> m )
{
vector<KeyNode>::iterator i;
for ( i = m_Keys.begin(); i != m_Keys.end(); ++i )
{
if ( i->key.compare ( key ) )
{
for ( map<string, string>::iterator j = m.begin(); j != m.end(); ++j )
{
i->vars.insert ( map<string, string>::value_type ( j->first, j->second ) );
}
}
}
return true;
}
string CINIFile::StripChars ( string tags, string source )
{
string stripped;
bool fail;
for ( string::iterator i = source.begin(); i != source.end(); ++i )
{
fail = false;
for ( string::iterator j = tags.begin(); j != tags.end(); ++j )
{
if ( *i == *j )
fail = true;
}
if ( fail == false )
{
stripped.push_back ( *i );
}
}
return stripped;
}
map<string, string> CINIFile::SeparateAtChar ( const char separator, string source )
{
string a, b;
map<string, string> m;
bool afterSeparator = false;
for ( string::iterator i = source.begin(); i != source.end(); ++i )
{
if ( *i == separator )
{
afterSeparator = true;
}
else if ( afterSeparator == true && *i != separator )
{
b.push_back ( *i );
}
else
{
a.push_back ( *i );
}
}
m.insert ( map<string, string>::value_type ( a, b ) );
return m;
}
It took me like an hour and a half to write this (and it works). I'm just curious if it's any more effeciant than the other one.