#include "IniFile.h" // // TrimChars // // trim whitespace, or any, chars from both ends // template std::string TrimChars( const std::string& str, const S space ) { const size_t start = str.find_first_not_of( space ); if ( str.npos == start ) return ""; return str.substr( start, str.find_last_not_of( space ) - start + 1 ); } // // IniSection :: Set // // set key's value if it doesn't match the default // otherwise remove the key from the section if it exists // void IniSection::Set( const std::string& key, const std::string& val, const std::string& def ) { if ( val != def ) operator[](key) = val; else { iterator f = find(key); if ( f != end() ) erase( f ); } } // // IniSection :: Get // // return a key's value if it exists // otherwise return the default // std::string IniSection::Get( const std::string& key, const std::string& def ) { const const_iterator f = find(key); if ( f != end() ) if ( false == f->second.empty() ) return f->second; return def; } // // IniFile :: Save // // save a file // void IniFile::Save( std::ostream& file ) { const_iterator i = begin(), e = end(); for ( ; i != e; ++i ) { // skip a line at new sections file << "\n[" << i->first << "]\n"; Section::const_iterator si = i->second.begin(), se = i->second.end(); for ( ; si != se; ++si ) { file << si->first << " = "; // if value has quotes or whitespace, surround it with quotes if (si->second.find_first_of("\"\t ") != std::string::npos) file << '"' << si->second << '"'; else file << si->second; file << '\n'; } } } // // IniFile :: Load // // load a file // void IniFile::Load( std::istream& file ) { const char* const space = "\t\r "; std::string line; // start off with an empty section Section* section = &(*this)[""]; while ( std::getline( file, line ).good() ) // read a line { line = TrimChars(line,space); if ( line.size() ) { switch ( line[0] ) { // comment case '#' : case ';' : break; // section case '[' : // kinda odd trimming section = &(*this)[ TrimChars(line,"][\t\r ") ]; break; // key/value default : { std::istringstream ss(line); std::string key; std::getline( ss, key, '=' ); std::string val; std::getline( ss, val ); val = TrimChars(val,space); // handle quote surrounded values if (val.length() > 1) if ('"' == val[0]) val = val.substr(1, val.length()-2); (*section)[ TrimChars(key,space) ] = val; break; } } } } Clean(); } // // IniFile :: Clean // // remove empty key/values and sections // after trying to access ini sections/values, they are automatically allocated // this deletes the empty stuff // void IniFile::Clean() { iterator i = begin(), e = end(); for ( ; i != e; ) { Section::iterator si = i->second.begin(), se = i->second.end(); for ( ; si != se; ) { if ( si->second.empty() ) i->second.erase( si++ ); else ++si; } if ( i->second.empty() ) erase( i++ ); else ++i; } }