rlm@1: // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. rlm@1: // Copyright (C) 1999-2003 Forgotten rlm@1: // Copyright (C) 2004 Forgotten and the VBA development team rlm@1: rlm@1: // This program is free software; you can redistribute it and/or modify rlm@1: // it under the terms of the GNU General Public License as published by rlm@1: // the Free Software Foundation; either version 2, or(at your option) rlm@1: // any later version. rlm@1: // rlm@1: // This program is distributed in the hope that it will be useful, rlm@1: // but WITHOUT ANY WARRANTY; without even the implied warranty of rlm@1: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rlm@1: // GNU General Public License for more details. rlm@1: // rlm@1: // You should have received a copy of the GNU General Public License rlm@1: // along with this program; if not, write to the Free Software Foundation, rlm@1: // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. rlm@1: rlm@1: #include "configfile.h" rlm@1: rlm@1: #include rlm@1: #include rlm@1: rlm@1: #include rlm@1: #include rlm@1: rlm@1: namespace VBA rlm@1: { rlm@1: namespace Config rlm@1: { rlm@1: rlm@1: using std::string; rlm@1: using Glib::IOChannel; rlm@1: rlm@1: Line::Line(const string & _rsKey, const string & _rsValue) : rlm@1: m_sKey(_rsKey), rlm@1: m_sValue(_rsValue) rlm@1: { rlm@1: } rlm@1: rlm@1: Section::Section(const string & _rsName) : rlm@1: m_sName(_rsName) rlm@1: { rlm@1: } rlm@1: rlm@1: bool Section::bKeyExists(const string & _rsKey) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->m_sKey == _rsKey) rlm@1: { rlm@1: return true; rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void Section::vSetKey(const string & _rsKey, const string & _rsValue) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->m_sKey == _rsKey) rlm@1: { rlm@1: it->m_sValue = _rsValue; rlm@1: return; rlm@1: } rlm@1: } rlm@1: push_back(Line(_rsKey, _rsValue)); rlm@1: } rlm@1: rlm@1: string Section::sGetKey(const string & _rsKey) const rlm@1: { rlm@1: for (const_iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->m_sKey == _rsKey) rlm@1: { rlm@1: return it->m_sValue; rlm@1: } rlm@1: } rlm@1: throw KeyNotFound(m_sName, _rsKey); rlm@1: } rlm@1: rlm@1: void Section::vRemoveKey(const string & _rsKey) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->m_sKey == _rsKey) rlm@1: { rlm@1: erase(it); rlm@1: return; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: File::File() rlm@1: { rlm@1: } rlm@1: rlm@1: File::File(const string & _rsFile) rlm@1: { rlm@1: vLoad(_rsFile); rlm@1: } rlm@1: rlm@1: File::~File() rlm@1: { rlm@1: } rlm@1: rlm@1: bool File::bSectionExists(const string & _rsName) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->sGetName() == _rsName) rlm@1: { rlm@1: return true; rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: Section * File::poAddSection(const string & _rsName) rlm@1: { rlm@1: Section * poSection = NULL; rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->sGetName() == _rsName) rlm@1: { rlm@1: poSection = &(*it); rlm@1: } rlm@1: } rlm@1: if (poSection == NULL) rlm@1: { rlm@1: push_back(Section(_rsName)); rlm@1: poSection = &back(); rlm@1: } rlm@1: return poSection; rlm@1: } rlm@1: rlm@1: Section * File::poGetSection(const string & _rsName) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->sGetName() == _rsName) rlm@1: { rlm@1: return &(*it); rlm@1: } rlm@1: } rlm@1: throw SectionNotFound(_rsName); rlm@1: } rlm@1: rlm@1: void File::vRemoveSection(const string & _rsName) rlm@1: { rlm@1: for (iterator it = begin(); it != end(); it++) rlm@1: { rlm@1: if (it->sGetName() == _rsName) rlm@1: { rlm@1: erase(it); rlm@1: return; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void File::vLoad(const string & _rsFile, rlm@1: bool _bAddSection, rlm@1: bool _bAddKey) rlm@1: { rlm@1: string sBuffer = Glib::file_get_contents(_rsFile); rlm@1: Section * poSection = NULL; rlm@1: char ** lines = g_strsplit(sBuffer.c_str(), "\n", 0); rlm@1: char * tmp; rlm@1: int i = 0; rlm@1: while (lines[i]) rlm@1: { rlm@1: if (lines[i][0] == '[') rlm@1: { rlm@1: if ((tmp = strchr(lines[i], ']'))) rlm@1: { rlm@1: *tmp = '\0'; rlm@1: if (_bAddSection) rlm@1: { rlm@1: poSection = poAddSection(&lines[i][1]); rlm@1: } rlm@1: else rlm@1: { rlm@1: try rlm@1: { rlm@1: poSection = poGetSection(&lines[i][1]); rlm@1: } rlm@1: catch (...) rlm@1: { rlm@1: poSection = NULL; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: else if (lines[i][0] != '#' && poSection != NULL) rlm@1: { rlm@1: if ((tmp = strchr(lines[i], '='))) rlm@1: { rlm@1: *tmp = '\0'; rlm@1: tmp++; rlm@1: if (_bAddKey || poSection->bKeyExists(lines[i])) rlm@1: { rlm@1: poSection->vSetKey(lines[i], tmp); rlm@1: } rlm@1: } rlm@1: } rlm@1: i++; rlm@1: } rlm@1: g_strfreev(lines); rlm@1: } rlm@1: rlm@1: void File::vSave(const string & _rsFile) rlm@1: { rlm@1: Glib::RefPtr poFile = IOChannel::create_from_file(_rsFile, "w"); rlm@1: poFile->set_encoding(""); rlm@1: rlm@1: for (const_iterator poSection = begin(); rlm@1: poSection != end(); rlm@1: poSection++) rlm@1: { rlm@1: string sName = "[" + poSection->sGetName() + "]\n"; rlm@1: poFile->write(sName); rlm@1: rlm@1: for (Section::const_iterator poLine = poSection->begin(); rlm@1: poLine != poSection->end(); rlm@1: poLine++) rlm@1: { rlm@1: string sLine = poLine->m_sKey + "=" + poLine->m_sValue + "\n"; rlm@1: poFile->write(sLine); rlm@1: } rlm@1: poFile->write("\n"); rlm@1: } rlm@1: } rlm@1: rlm@1: void File::vClear() rlm@1: { rlm@1: clear(); rlm@1: } rlm@1: rlm@1: std::ostream & operator<<(std::ostream & _roOut, const File & _roFile) rlm@1: { rlm@1: for (File::const_iterator poSection = _roFile.begin(); rlm@1: poSection != _roFile.end(); rlm@1: poSection++) rlm@1: { rlm@1: string sName = "[" + poSection->sGetName() + "]\n"; rlm@1: _roOut << sName; rlm@1: rlm@1: for (Section::const_iterator poLine = poSection->begin(); rlm@1: poLine != poSection->end(); rlm@1: poLine++) rlm@1: { rlm@1: string sLine = poLine->m_sKey + "=" + poLine->m_sValue + "\n"; rlm@1: _roOut << sLine; rlm@1: } rlm@1: _roOut << "\n"; rlm@1: } rlm@1: return _roOut; rlm@1: } rlm@1: rlm@1: } // namespace Config rlm@1: } // namespace VBA