summaryrefslogtreecommitdiff
path: root/Source/Plugins/InputPluginCommon/Src/IniFile.cpp
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2010-06-03 18:05:08 +0000
committerhrydgard <hrydgard@gmail.com>2010-06-03 18:05:08 +0000
commita3c96ac42c4c2ce4a4cf2f5ca09a5ae9dd4bd303 (patch)
treeda7ca1f64fce704934d581c82a9533fe38b103f1 /Source/Plugins/InputPluginCommon/Src/IniFile.cpp
parent3236aa9e73cf6d0bc798cce6f5224cff40eb6955 (diff)
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
Diffstat (limited to 'Source/Plugins/InputPluginCommon/Src/IniFile.cpp')
-rw-r--r--Source/Plugins/InputPluginCommon/Src/IniFile.cpp156
1 files changed, 156 insertions, 0 deletions
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 <typename S>
+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;
+ }
+}