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
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"
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
);
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
,
78 /* Open the configuration file */
80 // Always open in binary mode
81 fp
.open(filename
.c_str(), std::ios::in
| std::ios::binary
);
84 Exception::ERR_FILE_NOT_FOUND
, "'" + filename
+ "' file not found!", "ConfigFile::load" );
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
;
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
,
110 /* Clear current settings map */
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) == ']')
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
;
138 currentSettings
= seci
->second
;
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
);
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())
175 SettingsMultiMap::const_iterator i
= seci
->second
->find(key
);
176 if (i
== seci
->second
->end())
186 //-----------------------------------------------------------------------
187 StringVector
ConfigFile::getMultiSetting(const String
& key
, const String
& section
) const
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
);
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");
221 return SettingsIterator(seci
->second
->begin(), seci
->second
->end());
224 //-----------------------------------------------------------------------
225 ConfigFile::SectionIterator
ConfigFile::getSectionIterator(void)
227 return SectionIterator(mSettings
.begin(), mSettings
.end());