From a3c96ac42c4c2ce4a4cf2f5ca09a5ae9dd4bd303 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Thu, 3 Jun 2010 18:05:08 +0000 Subject: Warp back to 5578. Sorry for the lost changes, please re-apply. Reason: 5579 is a complete disaster. Not only does it change tons of files to switch to a new and non-working (it doesn't parse my ini files, at least) ini parser, it also reshuffles a lot of code and removes a plugin. The latter part is fine, but doing these two major switches in one revision, one of which is broken, is completely unacceptable. I said to merge tiny changes, not massive reworkings. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5589 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/InputPluginCommon/Src/IniFile.cpp | 156 +++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 Source/Plugins/InputPluginCommon/Src/IniFile.cpp (limited to 'Source/Plugins/InputPluginCommon/Src/IniFile.cpp') diff --git a/Source/Plugins/InputPluginCommon/Src/IniFile.cpp b/Source/Plugins/InputPluginCommon/Src/IniFile.cpp new file mode 100644 index 0000000000..0f10b25452 --- /dev/null +++ b/Source/Plugins/InputPluginCommon/Src/IniFile.cpp @@ -0,0 +1,156 @@ + +#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; + } +} -- cgit v1.2.3