[692] | 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 | }
|
---|