mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 22:09:19 -07:00
e4085f0f04
Switch to Billiard's IniFile implementation throughout Dolphin (it's faster!!). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5579 8ced0084-cf51-0410-be5f-012b33b47a6e
255 lines
4.8 KiB
C++
255 lines
4.8 KiB
C++
// Copyright (C) 2003 Dolphin Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
// http://code.google.com/p/dolphin-emu/
|
|
// see IniFile.h
|
|
|
|
#include "IniFile.h"
|
|
|
|
template <typename S>
|
|
void StripChars(std::string& str, const S space)
|
|
{
|
|
const size_t start = str.find_first_not_of(space);
|
|
|
|
if (str.npos == start)
|
|
str.clear();
|
|
else
|
|
str = str.substr(start, str.find_last_not_of(space) - start + 1);
|
|
}
|
|
|
|
bool Section::Get(const std::string& key, std::string* const val, const std::string& def) const
|
|
{
|
|
const const_iterator f = find(key);
|
|
if (f != end())
|
|
{
|
|
*val = f->second;
|
|
return true;
|
|
}
|
|
if (false == def.empty())
|
|
*val = def;
|
|
return false;
|
|
}
|
|
|
|
void Section::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);
|
|
}
|
|
}
|
|
|
|
bool IniFile::Save(const std::string& filename) const
|
|
{
|
|
return Save(filename.c_str());
|
|
}
|
|
|
|
bool IniFile::Save(const char filename[]) const
|
|
{
|
|
std::ofstream file;
|
|
file.open(filename);
|
|
if (file.is_open())
|
|
{
|
|
Save(file);
|
|
file.close();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void IniFile::Save(std::ostream& file) const
|
|
{
|
|
const_iterator
|
|
si = begin(),
|
|
se = end();
|
|
for ( ; si != se; ++si )
|
|
{
|
|
// skip a line at new sections
|
|
file << "\n[" << si->first << "]\n";
|
|
si->second.Save(file);
|
|
}
|
|
}
|
|
|
|
void Section::Save(std::ostream& file) const
|
|
{
|
|
if (m_use_lines) // this is used when GetLines or SetLines has been called
|
|
{
|
|
std::vector<std::string>::const_iterator
|
|
i = m_lines.begin(),
|
|
e = m_lines.end();
|
|
for ( ; i!=e; ++i)
|
|
file << *i << '\n';
|
|
}
|
|
else
|
|
{
|
|
Section::const_iterator
|
|
vi = begin(),
|
|
ve = end();
|
|
for ( ; vi!=ve; ++vi)
|
|
{
|
|
file << vi->first << " = ";
|
|
// if value has quotes or whitespace, surround it with quotes
|
|
if (vi->second.find_first_of("\"\t ") != std::string::npos)
|
|
file << '"' << vi->second << '"';
|
|
else
|
|
file << vi->second;
|
|
file << '\n';
|
|
}
|
|
}
|
|
}
|
|
|
|
bool IniFile::Load(const std::string& filename)
|
|
{
|
|
return Load(filename.c_str());
|
|
}
|
|
|
|
bool IniFile::Load(const char filename[])
|
|
{
|
|
std::ifstream file;
|
|
file.open(filename);
|
|
if (file.is_open())
|
|
{
|
|
Load(file);
|
|
file.close();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void IniFile::Load(std::istream& file)
|
|
{
|
|
std::vector<std::string> lines;
|
|
|
|
Section sectmp;
|
|
Section* section = §mp;
|
|
|
|
std::string line;
|
|
while (std::getline(file, line)) // read a line
|
|
{
|
|
if (line.size())
|
|
{
|
|
switch (line[0])
|
|
{
|
|
// section
|
|
case '[' :
|
|
section->m_lines = lines;
|
|
// kinda odd trimming
|
|
StripChars(line, "][\t\r ");
|
|
section = &(*this)[line];
|
|
lines.clear();
|
|
break;
|
|
|
|
// key/value
|
|
default :
|
|
{
|
|
std::istringstream ss(line);
|
|
|
|
std::string key; std::getline(ss, key, '=');
|
|
std::string val; std::getline(ss, val);
|
|
|
|
StripChars(val, "\t\r ");
|
|
// handle quote surrounded values
|
|
if (val.length() > 1)
|
|
if ('"' == val[0])
|
|
val.assign(val.begin()+1, val.end()-1);
|
|
|
|
StripChars(key, "\t\r ");
|
|
(*section)[key] = val;
|
|
}
|
|
//break; // no break
|
|
|
|
// comment
|
|
case '#' :
|
|
case ';' :
|
|
lines.push_back(line);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//Clean();
|
|
}
|
|
|
|
//
|
|
// IniFile :: Clean
|
|
//
|
|
// remove empty key/values and sections
|
|
// after trying to access ini sections/values with the [] operator, 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() && i->second.m_lines.empty())
|
|
erase( i++ );
|
|
else
|
|
++i;
|
|
}
|
|
}
|
|
|
|
bool IniFile::Exists(const std::string& section) const
|
|
{
|
|
return find(section) != end();
|
|
}
|
|
|
|
void IniFile::Delete(const std::string& section)
|
|
{
|
|
const iterator f = find(section);
|
|
if (end() != f)
|
|
erase(f);
|
|
}
|
|
|
|
bool Section::Exists(const std::string& key) const
|
|
{
|
|
return find(key) != end();
|
|
}
|
|
|
|
void Section::Delete(const std::string& key)
|
|
{
|
|
const iterator f = find(key);
|
|
if (end() != f)
|
|
erase(f);
|
|
}
|
|
|
|
void Section::SetLines(const std::vector<std::string>& lines)
|
|
{
|
|
m_lines = lines;
|
|
m_use_lines = true;
|
|
}
|
|
|
|
void Section::GetLines(std::vector<std::string>& lines)
|
|
{
|
|
lines = m_lines;
|
|
m_use_lines = true;
|
|
}
|