Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/orxonox/core/ConfigValueContainer.cc @ 434

Last change on this file since 434 was 434, checked in by landauf, 16 years ago

added a config-file-parser and a makro ( SetConfigValue(variable, defaultvalue) ) to get user-modified values from the config-file (or to write the defaultvalue into it if the variable isn't yet in the file).

File size: 13.6 KB
Line 
1#include <fstream>
2#include <string>
3#include "ConfigValueContainer.h"
4
5#define CONFIGFILEPATH "O:\\oh\\bin\\orxonox.ini"
6
7namespace orxonox
8{
9    std::list<std::string>* ConfigValueContainer::configFileLines_s = 0;
10    bool ConfigValueContainer::readConfigFile_s = false;
11
12    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, int defvalue)
13    {
14        std::ostringstream ostream;
15
16        if (ostream << defvalue)
17            this->defvalue_ = ostream.str();
18        else
19            this->defvalue_ = "0";
20
21        this->setDefaultValues(classname, varname);
22        std::string valueString = this->getValueString();
23
24        std::istringstream istream(valueString);
25        if (!(istream >> this->value_int_))
26        {
27            this->value_int_ = defvalue;
28            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
29            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
30        }
31    }
32
33    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, double defvalue)
34    {
35        std::ostringstream ostream;
36
37        if (ostream << defvalue)
38            this->defvalue_ = ostream.str();
39        else
40            this->defvalue_ = "0.000000";
41
42        this->setDefaultValues(classname, varname);
43        std::string valueString = this->getValueString();
44
45        std::istringstream istream(valueString);
46        if (!(istream >> this->value_double_))
47        {
48            this->value_double_ = defvalue;
49            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
50            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
51        }
52    }
53
54    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, bool defvalue)
55    {
56        if (defvalue)
57            this->defvalue_ = "true";
58        else
59            this->defvalue_ = "false";
60
61        this->setDefaultValues(classname, varname);
62        std::string valueString = this->getValueString();
63
64        if (valueString.find("true") < valueString.size() || valueString.find("yes") < valueString.size())
65            this->value_bool_ = true;
66        else if (valueString.find("false") < valueString.size() || valueString.find("no") < valueString.size())
67            this->value_bool_ = false;
68        else
69        {
70            std::istringstream istream(valueString);
71            if (!(istream >> this->value_bool_))
72            {
73                this->value_bool_ = defvalue;
74                (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
75                ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
76            }
77        }
78    }
79
80    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, const char* defvalue)
81    {
82        this->defvalue_ = defvalue;
83        this->setDefaultValues(classname, varname);
84        this->value_string_ = this->getValueString(false);
85    }
86
87    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, Ogre::Vector3 defvalue)
88    {
89        std::ostringstream ostream;
90        if (ostream << "(" << defvalue.x << "," << defvalue.y << "," << defvalue.z << ")")
91            this->defvalue_ = ostream.str();
92        else
93            this->defvalue_ = "(0,0,0)";
94
95        this->setDefaultValues(classname, varname);
96        std::string valueString = this->getValueString();
97
98        unsigned int pos;
99        while ((pos = valueString.find(" ")) < valueString.length())
100            valueString.erase(pos, 1);
101        while ((pos = valueString.find("(")) < valueString.length())
102            valueString.erase(pos, 1);
103        while ((pos = valueString.find(")")) < valueString.length())
104            valueString.erase(pos, 1);
105        while ((pos = valueString.find(",")) < valueString.length())
106            valueString.replace(pos, 1, " ");
107
108        std::istringstream istream(valueString);
109
110        if (!(istream >> this->value_vector3_.x))
111        {
112            this->value_vector3_.x = defvalue.x;
113            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
114            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
115        }
116        if (!(istream >> this->value_vector3_.y))
117        {
118            this->value_vector3_.y = defvalue.y;
119            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
120            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
121        }
122        if (!(istream >> this->value_vector3_.z))
123        {
124            this->value_vector3_.z = defvalue.z;
125            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
126            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
127        }
128    }
129
130    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, Ogre::ColourValue defvalue)
131    {
132        std::ostringstream ostream;
133        if (ostream << "(" << defvalue.r << "," << defvalue.g << "," << defvalue.b << "," << defvalue.a << ")")
134            this->defvalue_ = ostream.str();
135        else
136            this->defvalue_ = "(0,0,0,0)";
137
138        this->setDefaultValues(classname, varname);
139        std::string valueString = this->getValueString();
140
141        unsigned int pos;
142        while ((pos = valueString.find(" ")) < valueString.length())
143            valueString.erase(pos, 1);
144        while ((pos = valueString.find("(")) < valueString.length())
145            valueString.erase(pos, 1);
146        while ((pos = valueString.find(")")) < valueString.length())
147            valueString.erase(pos, 1);
148        while ((pos = valueString.find(",")) < valueString.length())
149            valueString.replace(pos, 1, " ");
150
151        std::istringstream istream(valueString);
152
153        if (!(istream >> this->value_colourvalue_.r))
154        {
155            this->value_colourvalue_.r = defvalue.r;
156            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
157            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
158        }
159        if (!(istream >> this->value_colourvalue_.g))
160        {
161            this->value_colourvalue_.g = defvalue.g;
162            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
163            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
164        }
165        if (!(istream >> this->value_colourvalue_.b))
166        {
167            this->value_colourvalue_.b = defvalue.b;
168            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
169            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
170        }
171        if (!(istream >> this->value_colourvalue_.a))
172        {
173            this->value_colourvalue_.a = defvalue.a;
174            (*this->configFileLine_) = this->varname_ + "=" + this->defvalue_;
175            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
176        }
177    }
178
179    void ConfigValueContainer::setDefaultValues(const std::string& classname, const std::string& varname)
180    {
181        this->classname_ = classname;
182        this->varname_ = varname;
183
184        this->searchConfigFileLine();
185
186        this->value_int_ = 0;
187        this->value_double_ = 0.000000;
188        this->value_bool_ = false;
189        this->value_string_ = "";
190        this->value_vector3_ = Ogre::Vector3(0, 0, 0);
191        this->value_colourvalue_ = Ogre::ColourValue(0, 0, 0, 0);
192    }
193
194    void ConfigValueContainer::searchConfigFileLine()
195    {
196        if (!ConfigValueContainer::readConfigFile_s)
197            ConfigValueContainer::readConfigFile(CONFIGFILEPATH);
198
199        this->configFileLine_ = 0;
200
201        std::string section = "";
202        section.append("[");
203        section.append(this->classname_);
204        section.append("]");
205
206        bool success = false;
207        std::list<std::string>::iterator it1;
208        for(it1 = ConfigValueContainer::configFileLines_s->begin(); it1 != ConfigValueContainer::configFileLines_s->end(); ++it1)
209        {
210            if (this->isComment(*it1))
211                continue;
212
213            if ((*it1).find(section) < (*it1).length())
214            {
215                bool bLineIsEmpty = false;
216                std::list<std::string>::iterator positionToPutNewLineAt;
217
218                std::list<std::string>::iterator it2;
219                for(it2 = ++it1; it2 != ConfigValueContainer::configFileLines_s->end(); ++it2)
220                {
221                    if (this->isComment(*it2))
222                        continue;
223
224                    if (this->isEmpty(*it2))
225                    {
226                        if (!bLineIsEmpty)
227                        {
228                            bLineIsEmpty = true;
229                            positionToPutNewLineAt = it2;
230                        }
231                    }
232                    else
233                    {
234                        if (!bLineIsEmpty)
235                            positionToPutNewLineAt = it2;
236
237                        bLineIsEmpty = false;
238                    }
239
240                    unsigned int open = (*it2).find("[");
241                    unsigned int close = (*it2).find("]");
242                    if ((open < (*it2).length()) && (close < (*it2).length()) && (open < close))
243                    {
244                        this->configFileLine_ = this->configFileLines_s->insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalue_);
245                        ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
246                        success = true;
247                        break;
248                    }
249
250                    if ((*it2).find(this->varname_) < (*it2).length())
251                    {
252                        this->configFileLine_ = it2;
253                        success = true;
254                        break;
255                    }
256                }
257                if (!success)
258                {
259                    this->configFileLine_ = this->configFileLines_s->insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalue_);
260                    ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
261                    success = true;
262                }
263                break;
264            }
265        }
266        if (!success)
267        {
268            this->configFileLines_s->push_back("[" + this->classname_ + "]");
269            this->configFileLines_s->push_back(this->varname_ + "=" + this->defvalue_);
270            this->configFileLine_ = --this->configFileLines_s->end();
271            success = true;
272            this->configFileLines_s->push_back("");
273            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
274        }
275    }
276
277    bool ConfigValueContainer::isComment(const std::string& line)
278    {
279        std::string teststring = getStrippedLine(line);
280
281        if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[0] == '/'))
282            return true;
283
284        return false;
285    }
286
287    bool ConfigValueContainer::isEmpty(const std::string& line)
288    {
289        return getStrippedLine(line) == "";
290    }
291
292    std::string ConfigValueContainer::getStrippedLine(const std::string& line)
293    {
294        std::string output = line;
295        unsigned int pos;
296        while ((pos = output.find(" ")) < output.length())
297            output.erase(pos, 1);
298
299        return output;
300    }
301
302    std::string ConfigValueContainer::getValueString(bool bStripped)
303    {
304        std::string output;
305        if (bStripped)
306            output = this->getStrippedLine(*this->configFileLine_);
307        else
308            output = *this->configFileLine_;
309
310        return output.substr(output.find("=") + 1);
311    }
312
313    void ConfigValueContainer::readConfigFile(const std::string& filename)
314    {
315        ConfigValueContainer::readConfigFile_s = true;
316
317        if (!ConfigValueContainer::configFileLines_s)
318            ConfigValueContainer::configFileLines_s = new std::list<std::string>;
319
320        std::ofstream createFile;
321        createFile.open(filename.c_str(), std::fstream::app);
322        createFile.close();
323
324        std::ifstream file;
325        file.open(filename.c_str(), std::fstream::in);
326
327        char line[1024];
328
329        while (file.good() && !file.eof())
330        {
331            file.getline(line, 1024);
332            ConfigValueContainer::configFileLines_s->push_back(line);
333            std::cout << "### ->" << line << "<- : empty: " << isEmpty(line) << " comment: " << isComment(line) << std::endl;
334        }
335
336        ConfigValueContainer::configFileLines_s->pop_back();
337
338        if ((ConfigValueContainer::configFileLines_s->size() > 0) && !isEmpty(*ConfigValueContainer::configFileLines_s->rbegin()))
339        {
340            std::cout << "### newline added" << std::endl;
341            ConfigValueContainer::configFileLines_s->push_back("");
342        }
343
344        file.close();
345    }
346
347    void ConfigValueContainer::writeConfigFile(const std::string& filename)
348    {
349        ConfigValueContainer::readConfigFile_s = true;
350
351        if (!ConfigValueContainer::configFileLines_s)
352            ConfigValueContainer::configFileLines_s = new std::list<std::string>;
353
354        std::ofstream createFile;
355        createFile.open(filename.c_str(), std::fstream::app);
356        createFile.close();
357
358        std::ofstream file;
359        file.open(filename.c_str(), std::fstream::out);
360
361        std::list<std::string>::iterator it;
362        for(it = ConfigValueContainer::configFileLines_s->begin(); it != ConfigValueContainer::configFileLines_s->end(); ++it)
363        {
364            file << (*it) << std::endl;
365        }
366
367        file.close();
368    }
369}
Note: See TracBrowser for help on using the repository browser.