Patch 2793067: fix trunk with OGRE_THREAD_SUPPORT=1 on non-Windows platforms (don...
[ogre3d.git] / OgreMain / src / OgreConfigFile.cpp
blob4f574506a41a88f527f36a525b5b02a3f81f560a
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/
7 Copyright (c) 2000-2006 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
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.
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.
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.
24 You may alternatively use this source under the terms of a specific version of
25 the OGRE Unrestricted License provided you have obtained such a license from
26 Torus Knot Software Ltd.
27 -----------------------------------------------------------------------------
29 #include "OgreStableHeaders.h"
30 #include "OgreConfigFile.h"
31 #include "OgreResourceGroupManager.h"
33 #include "OgreException.h"
35 #include <iostream>
37 namespace Ogre {
39 //-----------------------------------------------------------------------
40 ConfigFile::ConfigFile()
43 //-----------------------------------------------------------------------
44 ConfigFile::~ConfigFile()
46 SettingsBySection::iterator seci, secend;
47 secend = mSettings.end();
48 for (seci = mSettings.begin(); seci != secend; ++seci)
50 OGRE_DELETE_T(seci->second, SettingsMultiMap, MEMCATEGORY_GENERAL);
53 //-----------------------------------------------------------------------
54 void ConfigFile::clear(void)
56 for (SettingsBySection::iterator seci = mSettings.begin();
57 seci != mSettings.end(); ++seci)
59 OGRE_DELETE_T(seci->second, SettingsMultiMap, MEMCATEGORY_GENERAL);
61 mSettings.clear();
63 //-----------------------------------------------------------------------
64 void ConfigFile::load(const String& filename, const String& separators, bool trimWhitespace)
66 loadDirect(filename, separators, trimWhitespace);
68 //-----------------------------------------------------------------------
69 void ConfigFile::load(const String& filename, const String& resourceGroup,
70 const String& separators, bool trimWhitespace)
72 loadFromResourceSystem(filename, resourceGroup, separators, trimWhitespace);
74 //-----------------------------------------------------------------------
75 void ConfigFile::loadDirect(const String& filename, const String& separators,
76 bool trimWhitespace)
78 /* Open the configuration file */
79 std::ifstream fp;
80 // Always open in binary mode
81 fp.open(filename.c_str(), std::ios::in | std::ios::binary);
82 if(!fp)
83 OGRE_EXCEPT(
84 Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", "ConfigFile::load" );
86 // Wrap as a stream
87 DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &fp, false));
89 #if OGRE_PLATFORM == OGRE_PLATFORM_SYMBIAN
90 // seems readLine doesn't work correctly in SYMBIAN with files
91 DataStreamPtr memoryStream(OGRE_NEW MemoryDataStream(stream));
92 stream = memoryStream;
93 #endif
95 load(stream, separators, trimWhitespace);
98 //-----------------------------------------------------------------------
99 void ConfigFile::loadFromResourceSystem(const String& filename,
100 const String& resourceGroup, const String& separators, bool trimWhitespace)
102 DataStreamPtr stream =
103 ResourceGroupManager::getSingleton().openResource(filename, resourceGroup);
104 load(stream, separators, trimWhitespace);
106 //-----------------------------------------------------------------------
107 void ConfigFile::load(const DataStreamPtr& stream, const String& separators,
108 bool trimWhitespace)
110 /* Clear current settings map */
111 clear();
113 String currentSection = StringUtil::BLANK;
114 SettingsMultiMap* currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)();
115 mSettings[currentSection] = currentSettings;
118 /* Process the file line for line */
119 String line, optName, optVal;
120 while (!stream->eof())
122 line = stream->getLine();
123 /* Ignore comments & blanks */
124 if (line.length() > 0 && line.at(0) != '#' && line.at(0) != '@')
126 if (line.at(0) == '[' && line.at(line.length()-1) == ']')
128 // Section
129 currentSection = line.substr(1, line.length() - 2);
130 SettingsBySection::const_iterator seci = mSettings.find(currentSection);
131 if (seci == mSettings.end())
133 currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)();
134 mSettings[currentSection] = currentSettings;
136 else
138 currentSettings = seci->second;
141 else
143 /* Find the first seperator character and split the string there */
144 Ogre::String::size_type separator_pos = line.find_first_of(separators, 0);
145 if (separator_pos != Ogre::String::npos)
147 optName = line.substr(0, separator_pos);
148 /* Find the first non-seperator character following the name */
149 Ogre::String::size_type nonseparator_pos = line.find_first_not_of(separators, separator_pos);
150 /* ... and extract the value */
151 /* Make sure we don't crash on an empty setting (it might be a valid value) */
152 optVal = (nonseparator_pos == Ogre::String::npos) ? "" : line.substr(nonseparator_pos);
153 if (trimWhitespace)
155 StringUtil::trim(optVal);
156 StringUtil::trim(optName);
158 currentSettings->insert(SettingsMultiMap::value_type(optName, optVal));
164 //-----------------------------------------------------------------------
165 String ConfigFile::getSetting(const String& key, const String& section, const String& defaultValue) const
168 SettingsBySection::const_iterator seci = mSettings.find(section);
169 if (seci == mSettings.end())
171 return defaultValue;
173 else
175 SettingsMultiMap::const_iterator i = seci->second->find(key);
176 if (i == seci->second->end())
178 return defaultValue;
180 else
182 return i->second;
186 //-----------------------------------------------------------------------
187 StringVector ConfigFile::getMultiSetting(const String& key, const String& section) const
189 StringVector ret;
192 SettingsBySection::const_iterator seci = mSettings.find(section);
193 if (seci != mSettings.end())
195 SettingsMultiMap::const_iterator i;
197 i = seci->second->find(key);
198 // Iterate over matches
199 while (i != seci->second->end() && i->first == key)
201 ret.push_back(i->second);
202 ++i;
205 return ret;
209 //-----------------------------------------------------------------------
210 ConfigFile::SettingsIterator ConfigFile::getSettingsIterator(const String& section)
212 SettingsBySection::const_iterator seci = mSettings.find(section);
213 if (seci == mSettings.end())
215 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
216 "Cannot find section " + section,
217 "ConfigFile::getSettingsIterator");
219 else
221 return SettingsIterator(seci->second->begin(), seci->second->end());
224 //-----------------------------------------------------------------------
225 ConfigFile::SectionIterator ConfigFile::getSectionIterator(void)
227 return SectionIterator(mSettings.begin(), mSettings.end());