rlm@1
|
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
rlm@1
|
2 // Copyright (C) 1999-2003 Forgotten
|
rlm@1
|
3 // Copyright (C) 2004 Forgotten and the VBA development team
|
rlm@1
|
4
|
rlm@1
|
5 // This program is free software; you can redistribute it and/or modify
|
rlm@1
|
6 // it under the terms of the GNU General Public License as published by
|
rlm@1
|
7 // the Free Software Foundation; either version 2, or(at your option)
|
rlm@1
|
8 // any later version.
|
rlm@1
|
9 //
|
rlm@1
|
10 // This program is distributed in the hope that it will be useful,
|
rlm@1
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
rlm@1
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
rlm@1
|
13 // GNU General Public License for more details.
|
rlm@1
|
14 //
|
rlm@1
|
15 // You should have received a copy of the GNU General Public License
|
rlm@1
|
16 // along with this program; if not, write to the Free Software Foundation,
|
rlm@1
|
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
rlm@1
|
18
|
rlm@1
|
19 #include "configfile.h"
|
rlm@1
|
20
|
rlm@1
|
21 #include <string.h>
|
rlm@1
|
22 #include <glib.h>
|
rlm@1
|
23
|
rlm@1
|
24 #include <glibmm/fileutils.h>
|
rlm@1
|
25 #include <glibmm/iochannel.h>
|
rlm@1
|
26
|
rlm@1
|
27 namespace VBA
|
rlm@1
|
28 {
|
rlm@1
|
29 namespace Config
|
rlm@1
|
30 {
|
rlm@1
|
31
|
rlm@1
|
32 using std::string;
|
rlm@1
|
33 using Glib::IOChannel;
|
rlm@1
|
34
|
rlm@1
|
35 Line::Line(const string & _rsKey, const string & _rsValue) :
|
rlm@1
|
36 m_sKey(_rsKey),
|
rlm@1
|
37 m_sValue(_rsValue)
|
rlm@1
|
38 {
|
rlm@1
|
39 }
|
rlm@1
|
40
|
rlm@1
|
41 Section::Section(const string & _rsName) :
|
rlm@1
|
42 m_sName(_rsName)
|
rlm@1
|
43 {
|
rlm@1
|
44 }
|
rlm@1
|
45
|
rlm@1
|
46 bool Section::bKeyExists(const string & _rsKey)
|
rlm@1
|
47 {
|
rlm@1
|
48 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
49 {
|
rlm@1
|
50 if (it->m_sKey == _rsKey)
|
rlm@1
|
51 {
|
rlm@1
|
52 return true;
|
rlm@1
|
53 }
|
rlm@1
|
54 }
|
rlm@1
|
55 return false;
|
rlm@1
|
56 }
|
rlm@1
|
57
|
rlm@1
|
58 void Section::vSetKey(const string & _rsKey, const string & _rsValue)
|
rlm@1
|
59 {
|
rlm@1
|
60 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
61 {
|
rlm@1
|
62 if (it->m_sKey == _rsKey)
|
rlm@1
|
63 {
|
rlm@1
|
64 it->m_sValue = _rsValue;
|
rlm@1
|
65 return;
|
rlm@1
|
66 }
|
rlm@1
|
67 }
|
rlm@1
|
68 push_back(Line(_rsKey, _rsValue));
|
rlm@1
|
69 }
|
rlm@1
|
70
|
rlm@1
|
71 string Section::sGetKey(const string & _rsKey) const
|
rlm@1
|
72 {
|
rlm@1
|
73 for (const_iterator it = begin(); it != end(); it++)
|
rlm@1
|
74 {
|
rlm@1
|
75 if (it->m_sKey == _rsKey)
|
rlm@1
|
76 {
|
rlm@1
|
77 return it->m_sValue;
|
rlm@1
|
78 }
|
rlm@1
|
79 }
|
rlm@1
|
80 throw KeyNotFound(m_sName, _rsKey);
|
rlm@1
|
81 }
|
rlm@1
|
82
|
rlm@1
|
83 void Section::vRemoveKey(const string & _rsKey)
|
rlm@1
|
84 {
|
rlm@1
|
85 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
86 {
|
rlm@1
|
87 if (it->m_sKey == _rsKey)
|
rlm@1
|
88 {
|
rlm@1
|
89 erase(it);
|
rlm@1
|
90 return;
|
rlm@1
|
91 }
|
rlm@1
|
92 }
|
rlm@1
|
93 }
|
rlm@1
|
94
|
rlm@1
|
95 File::File()
|
rlm@1
|
96 {
|
rlm@1
|
97 }
|
rlm@1
|
98
|
rlm@1
|
99 File::File(const string & _rsFile)
|
rlm@1
|
100 {
|
rlm@1
|
101 vLoad(_rsFile);
|
rlm@1
|
102 }
|
rlm@1
|
103
|
rlm@1
|
104 File::~File()
|
rlm@1
|
105 {
|
rlm@1
|
106 }
|
rlm@1
|
107
|
rlm@1
|
108 bool File::bSectionExists(const string & _rsName)
|
rlm@1
|
109 {
|
rlm@1
|
110 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
111 {
|
rlm@1
|
112 if (it->sGetName() == _rsName)
|
rlm@1
|
113 {
|
rlm@1
|
114 return true;
|
rlm@1
|
115 }
|
rlm@1
|
116 }
|
rlm@1
|
117 return false;
|
rlm@1
|
118 }
|
rlm@1
|
119
|
rlm@1
|
120 Section * File::poAddSection(const string & _rsName)
|
rlm@1
|
121 {
|
rlm@1
|
122 Section * poSection = NULL;
|
rlm@1
|
123 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
124 {
|
rlm@1
|
125 if (it->sGetName() == _rsName)
|
rlm@1
|
126 {
|
rlm@1
|
127 poSection = &(*it);
|
rlm@1
|
128 }
|
rlm@1
|
129 }
|
rlm@1
|
130 if (poSection == NULL)
|
rlm@1
|
131 {
|
rlm@1
|
132 push_back(Section(_rsName));
|
rlm@1
|
133 poSection = &back();
|
rlm@1
|
134 }
|
rlm@1
|
135 return poSection;
|
rlm@1
|
136 }
|
rlm@1
|
137
|
rlm@1
|
138 Section * File::poGetSection(const string & _rsName)
|
rlm@1
|
139 {
|
rlm@1
|
140 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
141 {
|
rlm@1
|
142 if (it->sGetName() == _rsName)
|
rlm@1
|
143 {
|
rlm@1
|
144 return &(*it);
|
rlm@1
|
145 }
|
rlm@1
|
146 }
|
rlm@1
|
147 throw SectionNotFound(_rsName);
|
rlm@1
|
148 }
|
rlm@1
|
149
|
rlm@1
|
150 void File::vRemoveSection(const string & _rsName)
|
rlm@1
|
151 {
|
rlm@1
|
152 for (iterator it = begin(); it != end(); it++)
|
rlm@1
|
153 {
|
rlm@1
|
154 if (it->sGetName() == _rsName)
|
rlm@1
|
155 {
|
rlm@1
|
156 erase(it);
|
rlm@1
|
157 return;
|
rlm@1
|
158 }
|
rlm@1
|
159 }
|
rlm@1
|
160 }
|
rlm@1
|
161
|
rlm@1
|
162 void File::vLoad(const string & _rsFile,
|
rlm@1
|
163 bool _bAddSection,
|
rlm@1
|
164 bool _bAddKey)
|
rlm@1
|
165 {
|
rlm@1
|
166 string sBuffer = Glib::file_get_contents(_rsFile);
|
rlm@1
|
167 Section * poSection = NULL;
|
rlm@1
|
168 char ** lines = g_strsplit(sBuffer.c_str(), "\n", 0);
|
rlm@1
|
169 char * tmp;
|
rlm@1
|
170 int i = 0;
|
rlm@1
|
171 while (lines[i])
|
rlm@1
|
172 {
|
rlm@1
|
173 if (lines[i][0] == '[')
|
rlm@1
|
174 {
|
rlm@1
|
175 if ((tmp = strchr(lines[i], ']')))
|
rlm@1
|
176 {
|
rlm@1
|
177 *tmp = '\0';
|
rlm@1
|
178 if (_bAddSection)
|
rlm@1
|
179 {
|
rlm@1
|
180 poSection = poAddSection(&lines[i][1]);
|
rlm@1
|
181 }
|
rlm@1
|
182 else
|
rlm@1
|
183 {
|
rlm@1
|
184 try
|
rlm@1
|
185 {
|
rlm@1
|
186 poSection = poGetSection(&lines[i][1]);
|
rlm@1
|
187 }
|
rlm@1
|
188 catch (...)
|
rlm@1
|
189 {
|
rlm@1
|
190 poSection = NULL;
|
rlm@1
|
191 }
|
rlm@1
|
192 }
|
rlm@1
|
193 }
|
rlm@1
|
194 }
|
rlm@1
|
195 else if (lines[i][0] != '#' && poSection != NULL)
|
rlm@1
|
196 {
|
rlm@1
|
197 if ((tmp = strchr(lines[i], '=')))
|
rlm@1
|
198 {
|
rlm@1
|
199 *tmp = '\0';
|
rlm@1
|
200 tmp++;
|
rlm@1
|
201 if (_bAddKey || poSection->bKeyExists(lines[i]))
|
rlm@1
|
202 {
|
rlm@1
|
203 poSection->vSetKey(lines[i], tmp);
|
rlm@1
|
204 }
|
rlm@1
|
205 }
|
rlm@1
|
206 }
|
rlm@1
|
207 i++;
|
rlm@1
|
208 }
|
rlm@1
|
209 g_strfreev(lines);
|
rlm@1
|
210 }
|
rlm@1
|
211
|
rlm@1
|
212 void File::vSave(const string & _rsFile)
|
rlm@1
|
213 {
|
rlm@1
|
214 Glib::RefPtr<IOChannel> poFile = IOChannel::create_from_file(_rsFile, "w");
|
rlm@1
|
215 poFile->set_encoding("");
|
rlm@1
|
216
|
rlm@1
|
217 for (const_iterator poSection = begin();
|
rlm@1
|
218 poSection != end();
|
rlm@1
|
219 poSection++)
|
rlm@1
|
220 {
|
rlm@1
|
221 string sName = "[" + poSection->sGetName() + "]\n";
|
rlm@1
|
222 poFile->write(sName);
|
rlm@1
|
223
|
rlm@1
|
224 for (Section::const_iterator poLine = poSection->begin();
|
rlm@1
|
225 poLine != poSection->end();
|
rlm@1
|
226 poLine++)
|
rlm@1
|
227 {
|
rlm@1
|
228 string sLine = poLine->m_sKey + "=" + poLine->m_sValue + "\n";
|
rlm@1
|
229 poFile->write(sLine);
|
rlm@1
|
230 }
|
rlm@1
|
231 poFile->write("\n");
|
rlm@1
|
232 }
|
rlm@1
|
233 }
|
rlm@1
|
234
|
rlm@1
|
235 void File::vClear()
|
rlm@1
|
236 {
|
rlm@1
|
237 clear();
|
rlm@1
|
238 }
|
rlm@1
|
239
|
rlm@1
|
240 std::ostream & operator<<(std::ostream & _roOut, const File & _roFile)
|
rlm@1
|
241 {
|
rlm@1
|
242 for (File::const_iterator poSection = _roFile.begin();
|
rlm@1
|
243 poSection != _roFile.end();
|
rlm@1
|
244 poSection++)
|
rlm@1
|
245 {
|
rlm@1
|
246 string sName = "[" + poSection->sGetName() + "]\n";
|
rlm@1
|
247 _roOut << sName;
|
rlm@1
|
248
|
rlm@1
|
249 for (Section::const_iterator poLine = poSection->begin();
|
rlm@1
|
250 poLine != poSection->end();
|
rlm@1
|
251 poLine++)
|
rlm@1
|
252 {
|
rlm@1
|
253 string sLine = poLine->m_sKey + "=" + poLine->m_sValue + "\n";
|
rlm@1
|
254 _roOut << sLine;
|
rlm@1
|
255 }
|
rlm@1
|
256 _roOut << "\n";
|
rlm@1
|
257 }
|
rlm@1
|
258 return _roOut;
|
rlm@1
|
259 }
|
rlm@1
|
260
|
rlm@1
|
261 } // namespace Config
|
rlm@1
|
262 } // namespace VBA
|