1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #include "OgreStableHeaders.h"
|
---|
26 | #include "OgreConfigFile.h"
|
---|
27 | #include "OgreResourceGroupManager.h"
|
---|
28 |
|
---|
29 | #include "OgreException.h"
|
---|
30 |
|
---|
31 | #include <iostream>
|
---|
32 |
|
---|
33 | namespace Ogre {
|
---|
34 |
|
---|
35 | //-----------------------------------------------------------------------
|
---|
36 | ConfigFile::ConfigFile()
|
---|
37 | {
|
---|
38 | }
|
---|
39 | //-----------------------------------------------------------------------
|
---|
40 | ConfigFile::~ConfigFile()
|
---|
41 | {
|
---|
42 | SettingsBySection::iterator seci, secend;
|
---|
43 | secend = mSettings.end();
|
---|
44 | for (seci = mSettings.begin(); seci != secend; ++seci)
|
---|
45 | {
|
---|
46 | delete seci->second;
|
---|
47 | }
|
---|
48 | }
|
---|
49 | //-----------------------------------------------------------------------
|
---|
50 | void ConfigFile::clear(void)
|
---|
51 | {
|
---|
52 | for (SettingsBySection::iterator seci = mSettings.begin();
|
---|
53 | seci != mSettings.end(); ++seci)
|
---|
54 | {
|
---|
55 | delete seci->second;
|
---|
56 | }
|
---|
57 | mSettings.clear();
|
---|
58 | }
|
---|
59 | //-----------------------------------------------------------------------
|
---|
60 | void ConfigFile::load(const String& filename, const String& separators, bool trimWhitespace)
|
---|
61 | {
|
---|
62 | loadDirect(filename, separators, trimWhitespace);
|
---|
63 | }
|
---|
64 | //-----------------------------------------------------------------------
|
---|
65 | void ConfigFile::load(const String& filename, const String& resourceGroup,
|
---|
66 | const String& separators, bool trimWhitespace)
|
---|
67 | {
|
---|
68 | loadFromResourceSystem(filename, resourceGroup, separators, trimWhitespace);
|
---|
69 | }
|
---|
70 | //-----------------------------------------------------------------------
|
---|
71 | void ConfigFile::loadDirect(const String& filename, const String& separators,
|
---|
72 | bool trimWhitespace)
|
---|
73 | {
|
---|
74 | /* Open the configuration file */
|
---|
75 | std::ifstream fp;
|
---|
76 | fp.open(filename.c_str());
|
---|
77 | if(!fp)
|
---|
78 | OGRE_EXCEPT(
|
---|
79 | Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", "ConfigFile::load" );
|
---|
80 |
|
---|
81 | // Wrap as a stream
|
---|
82 | DataStreamPtr stream(new FileStreamDataStream(filename, &fp, false));
|
---|
83 | load(stream, separators, trimWhitespace);
|
---|
84 |
|
---|
85 | }
|
---|
86 | //-----------------------------------------------------------------------
|
---|
87 | void ConfigFile::loadFromResourceSystem(const String& filename,
|
---|
88 | const String& resourceGroup, const String& separators, bool trimWhitespace)
|
---|
89 | {
|
---|
90 | DataStreamPtr stream =
|
---|
91 | ResourceGroupManager::getSingleton().openResource(filename, resourceGroup);
|
---|
92 | load(stream, separators, trimWhitespace);
|
---|
93 | }
|
---|
94 | //-----------------------------------------------------------------------
|
---|
95 | void ConfigFile::load(const DataStreamPtr& stream, const String& separators,
|
---|
96 | bool trimWhitespace)
|
---|
97 | {
|
---|
98 | /* Clear current settings map */
|
---|
99 | clear();
|
---|
100 |
|
---|
101 | String currentSection = StringUtil::BLANK;
|
---|
102 | SettingsMultiMap* currentSettings = new SettingsMultiMap();
|
---|
103 | mSettings[currentSection] = currentSettings;
|
---|
104 |
|
---|
105 |
|
---|
106 | /* Process the file line for line */
|
---|
107 | String line, optName, optVal;
|
---|
108 | while (!stream->eof())
|
---|
109 | {
|
---|
110 | line = stream->getLine();
|
---|
111 | /* Ignore comments & blanks */
|
---|
112 | if (line.length() > 0 && line.at(0) != '#' && line.at(0) != '@')
|
---|
113 | {
|
---|
114 | if (line.at(0) == '[' && line.at(line.length()-1) == ']')
|
---|
115 | {
|
---|
116 | // Section
|
---|
117 | currentSection = line.substr(1, line.length() - 2);
|
---|
118 | SettingsBySection::const_iterator seci = mSettings.find(currentSection);
|
---|
119 | if (seci == mSettings.end())
|
---|
120 | {
|
---|
121 | currentSettings = new SettingsMultiMap();
|
---|
122 | mSettings[currentSection] = currentSettings;
|
---|
123 | }
|
---|
124 | else
|
---|
125 | {
|
---|
126 | currentSettings = seci->second;
|
---|
127 | }
|
---|
128 | }
|
---|
129 | else
|
---|
130 | {
|
---|
131 | /* Find the first seperator character and split the string there */
|
---|
132 | std::string::size_type separator_pos = line.find_first_of(separators, 0);
|
---|
133 | if (separator_pos != std::string::npos)
|
---|
134 | {
|
---|
135 | optName = line.substr(0, separator_pos);
|
---|
136 | /* Find the first non-seperator character following the name */
|
---|
137 | std::string::size_type nonseparator_pos = line.find_first_not_of(separators, separator_pos);
|
---|
138 | /* ... and extract the value */
|
---|
139 | /* Make sure we don't crash on an empty setting (it might be a valid value) */
|
---|
140 | optVal = (nonseparator_pos == std::string::npos) ? "" : line.substr(nonseparator_pos);
|
---|
141 | if (trimWhitespace)
|
---|
142 | {
|
---|
143 | StringUtil::trim(optVal);
|
---|
144 | StringUtil::trim(optName);
|
---|
145 | }
|
---|
146 | currentSettings->insert(std::multimap<String, String>::value_type(optName, optVal));
|
---|
147 | }
|
---|
148 | }
|
---|
149 | }
|
---|
150 | }
|
---|
151 | }
|
---|
152 | //-----------------------------------------------------------------------
|
---|
153 | String ConfigFile::getSetting(const String& key, const String& section) const
|
---|
154 | {
|
---|
155 |
|
---|
156 | SettingsBySection::const_iterator seci = mSettings.find(section);
|
---|
157 | if (seci == mSettings.end())
|
---|
158 | {
|
---|
159 | return StringUtil::BLANK;
|
---|
160 | }
|
---|
161 | else
|
---|
162 | {
|
---|
163 | SettingsMultiMap::const_iterator i = seci->second->find(key);
|
---|
164 | if (i == seci->second->end())
|
---|
165 | {
|
---|
166 | return StringUtil::BLANK;
|
---|
167 | }
|
---|
168 | else
|
---|
169 | {
|
---|
170 | return i->second;
|
---|
171 | }
|
---|
172 | }
|
---|
173 | }
|
---|
174 | //-----------------------------------------------------------------------
|
---|
175 | StringVector ConfigFile::getMultiSetting(const String& key, const String& section) const
|
---|
176 | {
|
---|
177 | StringVector ret;
|
---|
178 |
|
---|
179 |
|
---|
180 | SettingsBySection::const_iterator seci = mSettings.find(section);
|
---|
181 | if (seci != mSettings.end())
|
---|
182 | {
|
---|
183 | SettingsMultiMap::const_iterator i;
|
---|
184 |
|
---|
185 | i = seci->second->find(key);
|
---|
186 | // Iterate over matches
|
---|
187 | while (i != seci->second->end() && i->first == key)
|
---|
188 | {
|
---|
189 | ret.push_back(i->second);
|
---|
190 | ++i;
|
---|
191 | }
|
---|
192 | }
|
---|
193 | return ret;
|
---|
194 |
|
---|
195 |
|
---|
196 | }
|
---|
197 | //-----------------------------------------------------------------------
|
---|
198 | ConfigFile::SettingsIterator ConfigFile::getSettingsIterator(const String& section)
|
---|
199 | {
|
---|
200 | SettingsBySection::const_iterator seci = mSettings.find(section);
|
---|
201 | if (seci == mSettings.end())
|
---|
202 | {
|
---|
203 | OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
|
---|
204 | "Cannot find section " + section,
|
---|
205 | "ConfigFile::getSettingsIterator");
|
---|
206 | }
|
---|
207 | else
|
---|
208 | {
|
---|
209 | return SettingsIterator(seci->second->begin(), seci->second->end());
|
---|
210 | }
|
---|
211 | }
|
---|
212 | //-----------------------------------------------------------------------
|
---|
213 | ConfigFile::SectionIterator ConfigFile::getSectionIterator(void)
|
---|
214 | {
|
---|
215 | return SectionIterator(mSettings.begin(), mSettings.end());
|
---|
216 | }
|
---|
217 |
|
---|
218 | }
|
---|