Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/core/ConfigValueContainer.cc @ 698

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

hopefully replaced all static pre-main variables with more secure wrapper functions. and now i'll sleep.

File size: 31.7 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#include <fstream>
29
30#include "../../misc/Tokenizer.h"
31#include "../../misc/String2Number.h"
32#include "ConfigValueContainer.h"
33
34#define CONFIGFILEPATH "orxonox.ini"
35
36namespace orxonox
37{
38    /**
39        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
40        @param value This is only needed to determine the right type.
41        @param classname The name of the class the variable belongs to
42        @param varname The name of the variable
43        @param defvalue The default-value
44    */
45    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, int defvalue)
46    {
47        this->classname_ = classname;
48        this->varname_ = varname;
49        this->type_ = Int;
50
51        this->defvalueString_ = number2String(defvalue, "0");                   // Try to convert the default-value to a string
52        this->searchConfigFileLine();                                           // Search the entry in the config-file
53
54        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
55        if (!string2Number(this->value_.value_int_, valueString, defvalue))     // Try to convert the string to a value
56            this->setConfigFileEntyToDefault();                                 // The conversion failed
57    }
58
59    /**
60        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
61        @param value This is only needed to determine the right type.
62        @param classname The name of the class the variable belongs to
63        @param varname The name of the variable
64        @param defvalue The default-value
65    */
66    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, unsigned int defvalue)
67    {
68        this->classname_ = classname;
69        this->varname_ = varname;
70        this->type_ = uInt;
71
72        this->defvalueString_ = number2String(defvalue, "0");                   // Try to convert the default-value to a string
73        this->searchConfigFileLine();                                           // Search the entry in the config-file
74
75        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
76        if (!string2Number(this->value_.value_uint_, valueString, defvalue))    // Try to convert the string to a value
77            this->setConfigFileEntyToDefault();                                 // The conversion failed
78    }
79
80    /**
81        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
82        @param value This is only needed to determine the right type.
83        @param classname The name of the class the variable belongs to
84        @param varname The name of the variable
85        @param defvalue The default-value
86    */
87    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, char defvalue)
88    {
89        this->classname_ = classname;
90        this->varname_ = varname;
91        this->type_ = Char;
92
93        this->defvalueString_ = number2String((int)defvalue, "0");              // Try to convert the default-value to a string
94        this->searchConfigFileLine();                                           // Search the entry in the config-file
95
96        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
97        // I used value_int_ instead of value_char_ to avoid number <-> char confusion in the config-file
98        if (!string2Number(this->value_.value_int_, valueString, (int)defvalue))// Try to convert the string to a value
99            this->setConfigFileEntyToDefault();                                 // The conversion failed
100    }
101
102    /**
103        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
104        @param value This is only needed to determine the right type.
105        @param classname The name of the class the variable belongs to
106        @param varname The name of the variable
107        @param defvalue The default-value
108    */
109    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, unsigned char defvalue)
110    {
111        this->classname_ = classname;
112        this->varname_ = varname;
113        this->type_ = uChar;
114
115        this->defvalueString_ = number2String((unsigned int)defvalue, "0");     // Try to convert the default-value to a string
116        this->searchConfigFileLine();                                           // Search the entry in the config-file
117
118        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
119        // I used value_uint_ instead of value_uchar_ to avoid number <-> char confusion in the config-file
120        if (!string2Number(this->value_.value_uint_, valueString, (unsigned int)defvalue)) // Try to convert the string to a value
121            this->setConfigFileEntyToDefault();                                 // The conversion failed
122    }
123
124    /**
125        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
126        @param value This is only needed to determine the right type.
127        @param classname The name of the class the variable belongs to
128        @param varname The name of the variable
129        @param defvalue The default-value
130    */
131    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, float defvalue)
132    {
133        this->classname_ = classname;
134        this->varname_ = varname;
135        this->type_ = Float;
136
137        this->defvalueString_ = number2String(defvalue, "0.000000");            // Try to convert the default-value to a string
138        this->searchConfigFileLine();                                           // Search the entry in the config-file
139
140        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
141        if (!string2Number(this->value_.value_float_, valueString, defvalue))   // Try to convert the string to a value
142            this->setConfigFileEntyToDefault();                                 // The conversion failed
143    }
144
145    /**
146        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
147        @param value This is only needed to determine the right type.
148        @param classname The name of the class the variable belongs to
149        @param varname The name of the variable
150        @param defvalue The default-value
151    */
152    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, double defvalue)
153    {
154        this->classname_ = classname;
155        this->varname_ = varname;
156        this->type_ = Double;
157
158        this->defvalueString_ = number2String(defvalue, "0.000000");            // Try to convert the default-value to a string
159        this->searchConfigFileLine();                                           // Search the entry in the config-file
160
161        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
162        if (!string2Number(this->value_.value_double_, valueString, defvalue))  // Try to convert the string to a value
163            this->setConfigFileEntyToDefault();                                 // The conversion failed
164    }
165
166    /**
167        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
168        @param value This is only needed to determine the right type.
169        @param classname The name of the class the variable belongs to
170        @param varname The name of the variable
171        @param defvalue The default-value
172    */
173    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, bool defvalue)
174    {
175        this->classname_ = classname;
176        this->varname_ = varname;
177        this->type_ = Bool;
178
179        // Convert the default-value from bool to string
180        if (defvalue)
181            this->defvalueString_ = "true";
182        else
183            this->defvalueString_ = "false";
184
185        this->searchConfigFileLine();                                           // Search the entry in the config-file
186
187        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
188
189        // Try to parse the value-string - is it a word?
190        if (valueString.find("true") < valueString.size()
191         || valueString.find("True") < valueString.size()
192         || valueString.find("yes") < valueString.size()
193         || valueString.find("Yes") < valueString.size())
194            this->value_.value_bool_ = true;
195        else if (valueString.find("false") < valueString.size()
196              || valueString.find("False") < valueString.size()
197              || valueString.find("no") < valueString.size()
198              || valueString.find("No") < valueString.size())
199            this->value_.value_bool_ = false;
200        else
201        {
202            // Its not a known word - is it a number?
203            std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
204            if (!string2Number(this->value_.value_bool_, valueString, defvalue))    // Try to convert the string to a value
205                this->setConfigFileEntyToDefault();                                 // The conversion failed
206        }
207    }
208
209    /**
210        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
211        @param value This is only needed to determine the right type.
212        @param classname The name of the class the variable belongs to
213        @param varname The name of the variable
214        @param defvalue The default-value
215    */
216    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, const std::string& defvalue)
217    {
218        this->classname_ = classname;
219        this->varname_ = varname;
220        this->type_ = String;
221
222        this->defvalueString_ = "\"" + defvalue + "\"";                         // Convert the string to a "config-file-string" with quotes
223
224        this->searchConfigFileLine();                                           // Search the entry in the config-file
225        std::string valueString = this->parseValueString(false);                // Parses the value string from the config-file-entry
226
227        // Strip the quotes
228        unsigned int pos1 = valueString.find("\"") + 1;
229        unsigned int pos2 = valueString.find("\"", pos1);
230
231        // Check if the entry was correctly quoted
232        if (pos1 < valueString.length() && pos2 < valueString.length() && !(valueString.find("\"", pos2 + 1) < valueString.length()))
233        {
234            // It was - get the string between the quotes
235            valueString = valueString.substr(pos1, pos2 - pos1);
236            this->value_string_ = valueString;
237        }
238        else
239        {
240            // It wasn't - use the default-value and restore the entry in the config-file.
241            this->value_string_ = defvalue;
242            this->setConfigFileEntyToDefault();
243        }
244    }
245
246    /**
247        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
248        @param value This is only needed to determine the right type.
249        @param classname The name of the class the variable belongs to
250        @param varname The name of the variable
251        @param defvalue The default-value
252    */
253    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, const char* defvalue)
254    {
255        this->classname_ = classname;
256        this->varname_ = varname;
257        this->type_ = ConstChar;
258
259        this->defvalueString_ = "\"" + std::string(defvalue) + "\"";            // Convert the string to a "config-file-string" with quotes
260
261        this->searchConfigFileLine();                                           // Search the entry in the config-file
262        std::string valueString = this->parseValueString(false);                // Parses the value string from the config-file-entry
263
264        // Strip the quotes
265        unsigned int pos1 = valueString.find("\"") + 1;
266        unsigned int pos2 = valueString.find("\"", pos1);
267
268        // Check if the entry was correctly quoted
269        if (pos1 < valueString.length() && pos2 < valueString.length() && !(valueString.find("\"", pos2 + 1) < valueString.length()))
270        {
271            // It was - get the string between the quotes
272            valueString = valueString.substr(pos1, pos2 - pos1);
273            this->value_string_ = valueString;
274        }
275        else
276        {
277            // It wasn't - use the default-value and restore the entry in the config-file.
278            this->value_string_ = defvalue;
279            this->setConfigFileEntyToDefault();
280        }
281    }
282
283    /**
284        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
285        @param value This is only needed to determine the right type.
286        @param classname The name of the class the variable belongs to
287        @param varname The name of the variable
288        @param defvalue The default-value
289    */
290    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, Ogre::Vector2 defvalue)
291    {
292        this->classname_ = classname;
293        this->varname_ = varname;
294        this->type_ = Vector2;
295
296        // Try to convert the default-value from Vector2 to string
297        std::ostringstream ostream;
298        if (ostream << "(" << defvalue.x << "," << defvalue.y << ")")
299            this->defvalueString_ = ostream.str();
300        else
301            this->defvalueString_ = "(0,0)";
302
303        this->searchConfigFileLine();                                           // Search the entry in the config-file
304        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
305
306        // Strip the value-string
307        unsigned int pos1 = valueString.find("(") + 1;
308        unsigned int pos2 = valueString.find(")", pos1);
309
310        // Try to convert the stripped value-string to Vector2
311        if (pos1 < valueString.length() && pos2 < valueString.length() && pos1 < pos2)
312        {
313            valueString = valueString.substr(pos1, pos2 - pos1);
314            std::vector<std::string> tokens = tokenize(valueString, ",");
315            if (!string2Number(this->value_vector2_.x, tokens[0], defvalue.x))
316                this->setConfigFileEntyToDefault();
317            if (!string2Number(this->value_vector2_.y, tokens[1], defvalue.y))
318                this->setConfigFileEntyToDefault();
319        }
320        else
321        {
322            this->value_vector2_ = defvalue;
323            this->setConfigFileEntyToDefault();
324        }
325    }
326
327    /**
328        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
329        @param value This is only needed to determine the right type.
330        @param classname The name of the class the variable belongs to
331        @param varname The name of the variable
332        @param defvalue The default-value
333    */
334    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, Ogre::Vector3 defvalue)
335    {
336        this->classname_ = classname;
337        this->varname_ = varname;
338        this->type_ = Vector3;
339
340        // Try to convert the default-value from Vector3 to string
341        std::ostringstream ostream;
342        if (ostream << "(" << defvalue.x << "," << defvalue.y << "," << defvalue.z << ")")
343            this->defvalueString_ = ostream.str();
344        else
345            this->defvalueString_ = "(0,0,0)";
346
347        this->searchConfigFileLine();                                           // Search the entry in the config-file
348        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
349
350        // Strip the value-string
351        unsigned int pos1 = valueString.find("(") + 1;
352        unsigned int pos2 = valueString.find(")", pos1);
353
354        // Try to convert the stripped value-string to Vector3
355        if (pos1 < valueString.length() && pos2 < valueString.length() && pos1 < pos2)
356        {
357            valueString = valueString.substr(pos1, pos2 - pos1);
358            std::vector<std::string> tokens = tokenize(valueString, ",");
359            if (!string2Number(this->value_vector3_.x, tokens[0], defvalue.x))
360                this->setConfigFileEntyToDefault();
361            if (!string2Number(this->value_vector3_.y, tokens[1], defvalue.y))
362                this->setConfigFileEntyToDefault();
363            if (!string2Number(this->value_vector3_.z, tokens[2], defvalue.z))
364                this->setConfigFileEntyToDefault();
365        }
366        else
367        {
368            this->value_vector3_ = defvalue;
369            this->setConfigFileEntyToDefault();
370        }
371    }
372
373    /**
374        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
375        @param value This is only needed to determine the right type.
376        @param classname The name of the class the variable belongs to
377        @param varname The name of the variable
378        @param defvalue The default-value
379    */
380    ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, Ogre::ColourValue defvalue)
381    {
382        this->classname_ = classname;
383        this->varname_ = varname;
384        this->type_ = ColourValue;
385
386        // Try to convert the default-value from ColourValue to string
387        std::ostringstream ostream;
388        if (ostream << "(" << defvalue.r << "," << defvalue.g << "," << defvalue.b << "," << defvalue.a << ")")
389            this->defvalueString_ = ostream.str();
390        else
391            this->defvalueString_ = "(0,0,0,0)";
392
393        this->searchConfigFileLine();                                           // Search the entry in the config-file
394        std::string valueString = this->parseValueString();                     // Parses the value string from the config-file-entry
395
396        // Strip the value-string
397        unsigned int pos1 = valueString.find("(") + 1;
398        unsigned int pos2 = valueString.find(")", pos1);
399
400        // Try to convert the stripped value-string to Vector3
401        if (pos1 < valueString.length() && pos2 < valueString.length() && pos1 < pos2)
402        {
403            valueString = valueString.substr(pos1, pos2 - pos1);
404            std::vector<std::string> tokens = tokenize(valueString, ",");
405            if (!string2Number(this->value_colourvalue_.r, tokens[0], defvalue.r))
406                this->setConfigFileEntyToDefault();
407            if (!string2Number(this->value_colourvalue_.g, tokens[1], defvalue.g))
408                this->setConfigFileEntyToDefault();
409            if (!string2Number(this->value_colourvalue_.b, tokens[2], defvalue.b))
410                this->setConfigFileEntyToDefault();
411            if (!string2Number(this->value_colourvalue_.a, tokens[3], defvalue.a))
412                this->setConfigFileEntyToDefault();
413        }
414        else
415        {
416            this->value_colourvalue_ = defvalue;
417            this->setConfigFileEntyToDefault();
418        }
419    }
420
421    /**
422        @brief Sets the corresponding enty in the config-file back to the default value.
423    */
424    void ConfigValueContainer::setConfigFileEntyToDefault()
425    {
426        (*this->configFileLine_) = this->varname_ + "=" + this->defvalueString_;
427        ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
428    }
429
430
431    /**
432        @brief Searches the corresponding entry in the config-file and creates it, if there is no entry.
433    */
434    void ConfigValueContainer::searchConfigFileLine()
435    {
436        // Read the file if needed
437        if (!ConfigValueContainer::finishedReadingConfigFile())
438            ConfigValueContainer::readConfigFile(CONFIGFILEPATH);
439
440        // The string of the section we're searching
441        std::string section = "";
442        section.append("[");
443        section.append(this->classname_);
444        section.append("]");
445
446        // Iterate through all config-file-lines
447        bool success = false;
448        std::list<std::string>::iterator it1;
449        for(it1 = ConfigValueContainer::getConfigFileLines().begin(); it1 != ConfigValueContainer::getConfigFileLines().end(); ++it1)
450        {
451            // Don't try to parse comments
452            if (this->isComment(*it1))
453                continue;
454
455            if ((*it1).find(section) < (*it1).length())
456            {
457                // We found the right section
458                bool bLineIsEmpty = false;
459                std::list<std::string>::iterator positionToPutNewLineAt;
460
461                // Iterate through all lines in the section
462                std::list<std::string>::iterator it2;
463                for(it2 = ++it1; it2 != ConfigValueContainer::getConfigFileLines().end(); ++it2)
464                {
465                    // Don't try to parse comments
466                    if (this->isComment(*it2))
467                        continue;
468
469                    // This if-else block is used to write a new line right after the last line of the
470                    // section but in front of the following empty lines before the next section.
471                    // (So this helps to keep a nice formatting with empty-lines between sections in the config-file)
472                    if (this->isEmpty(*it2))
473                    {
474                        if (!bLineIsEmpty)
475                        {
476                            bLineIsEmpty = true;
477                            positionToPutNewLineAt = it2;
478                        }
479                    }
480                    else
481                    {
482                        if (!bLineIsEmpty)
483                            positionToPutNewLineAt = it2;
484
485                        bLineIsEmpty = false;
486                    }
487
488                    // Look out for the beginning of the next section
489                    unsigned int open = (*it2).find("[");
490                    unsigned int close = (*it2).find("]");
491                    if ((open < (*it2).length()) && (close < (*it2).length()) && (open < close))
492                    {
493                        // The next section startet, so our line isn't yet in the file - now we add it and safe the file
494                        this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_);
495                        ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
496                        success = true;
497                        break;
498                    }
499
500                    // Look out for the variable-name
501                    if ((*it2).find(this->varname_) < (*it2).length())
502                    {
503                        // We found the right line - safe it and return
504                        this->configFileLine_ = it2;
505                        success = true;
506                        break;
507                    }
508                }
509
510                // Check if we succeeded
511                if (!success)
512                {
513                    // Looks like we found the right section, but the file ended without containing our variable - so we add it and safe the file
514                    this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_);
515                    ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
516                    success = true;
517                }
518                break;
519            }
520        }
521
522        // Check if we succeeded
523        if (!success)
524        {
525            // We obviously didn't found the right section, so we'll create it
526            this->getConfigFileLines().push_back("[" + this->classname_ + "]");                   // Create the section
527            this->getConfigFileLines().push_back(this->varname_ + "=" + this->defvalueString_);   // Create the line
528            this->configFileLine_ = --this->getConfigFileLines().end();                           // Set the pointer to the last element
529            success = true;
530            this->getConfigFileLines().push_back("");                                             // Add an empty line - this is needed for the algorithm in the searchConfigFileLine-function
531            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);                              // Save the changed config-file
532        }
533    }
534
535    /**
536        @brief Determines if a line in the config-file is a comment.
537        @param line The line to check
538        @return True = it's a comment
539    */
540    bool ConfigValueContainer::isComment(const std::string& line)
541    {
542        // Strip the line, whitespaces are disturbing
543        std::string teststring = getStrippedLine(line);
544
545        // There are four possible comment-symbols:
546        //  1) #comment in script-language style
547        //  2) %comment in matlab style
548        //  3) ;comment in unreal tournament config-file style
549        //  4) //comment in code style
550        if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[0] == '/'))
551            return true;
552
553        return false;
554    }
555
556    /**
557        @brief Determines if a line in the config-file is empty (contains only whitespaces).
558        @param line The line to check
559        @return True = it's empty
560    */
561    bool ConfigValueContainer::isEmpty(const std::string& line)
562    {
563        return getStrippedLine(line) == "";
564    }
565
566    /**
567        @brief Removes all whitespaces from a line.
568        @param line The line to strip
569        @return The stripped line
570    */
571    std::string ConfigValueContainer::getStrippedLine(const std::string& line)
572    {
573        std::string output = line;
574        unsigned int pos;
575        while ((pos = output.find(" ")) < output.length())
576            output.erase(pos, 1);
577        while ((pos = output.find("\t")) < output.length())
578            output.erase(pos, 1);
579
580        return output;
581    }
582
583    /**
584        @brief Returns the part in the corresponding config-file-entry of the container that defines the value.
585        @param bStripped True = strip the value-string
586        @return The value-string
587    */
588    std::string ConfigValueContainer::parseValueString(bool bStripped)
589    {
590        std::string output;
591        if (bStripped)
592            output = this->getStrippedLine(*this->configFileLine_);
593        else
594            output = *this->configFileLine_;
595
596        return output.substr(output.find("=") + 1);
597    }
598
599    /**
600        @returns a list, containing all entrys in the config-file.
601    */
602    std::list<std::string>& ConfigValueContainer::getConfigFileLines()
603    {
604        // This is done to avoid problems while executing this code before main()
605        static std::list<std::string> configFileLinesStaticReference = std::list<std::string>();
606        return configFileLinesStaticReference;
607    }
608
609    /**
610        @brief Returns true if the ConfigFile is read and stored into the ConfigFile-lines-list.
611        @param finished This is used to change the state
612        @return True if the ConfigFile is read and stored into the ConfigFile-lines-list
613    */
614    bool ConfigValueContainer::finishedReadingConfigFile(bool finished)
615    {
616        // This is done to avoid problems while executing this code before main()
617        static bool finishedReadingConfigFileStaticVariable = false;
618
619        if (finished)
620            finishedReadingConfigFileStaticVariable = true;
621
622        return finishedReadingConfigFileStaticVariable;
623    }
624
625    /**
626        @brief Reads the config-file and stores the lines in a list.
627        @param filename The name of the config-file
628    */
629    void ConfigValueContainer::readConfigFile(const std::string& filename)
630    {
631        ConfigValueContainer::finishedReadingConfigFile(true);
632
633        // This creates the file if it's not existing
634        std::ofstream createFile;
635        createFile.open(filename.c_str(), std::fstream::app);
636        createFile.close();
637
638        // Open the file
639        std::ifstream file;
640        file.open(filename.c_str(), std::fstream::in);
641
642        char line[1024];
643
644        // Iterate through the file and add the lines into the list
645        while (file.good() && !file.eof())
646        {
647            file.getline(line, 1024);
648            ConfigValueContainer::getConfigFileLines().push_back(line);
649//            std::cout << "### ->" << line << "<- : empty: " << isEmpty(line) << " comment: " << isComment(line) << std::endl;
650        }
651
652        // The last line is useless
653        ConfigValueContainer::getConfigFileLines().pop_back();
654
655        // Add an empty line to the end of the file if needed
656        // this is needed for the algorithm in the searchConfigFileLine-function
657        if ((ConfigValueContainer::getConfigFileLines().size() > 0) && !isEmpty(*ConfigValueContainer::getConfigFileLines().rbegin()))
658        {
659//            std::cout << "### newline added" << std::endl;
660            ConfigValueContainer::getConfigFileLines().push_back("");
661        }
662
663        file.close();
664    }
665
666    /**
667     *  @param Writes the content of the list, containing all lines of the config-file, into the config-file.
668     *  @param filename The name of the config-file
669     */
670    void ConfigValueContainer::writeConfigFile(const std::string& filename)
671    {
672        // Make sure we stored the config-file in the list
673        if (!ConfigValueContainer::finishedReadingConfigFile())
674            ConfigValueContainer::readConfigFile(filename);
675
676        // Open the file
677        std::ofstream file;
678        file.open(filename.c_str(), std::fstream::out);
679
680        // Iterate through the list an write the lines into the file
681        std::list<std::string>::iterator it;
682        for(it = ConfigValueContainer::getConfigFileLines().begin(); it != ConfigValueContainer::getConfigFileLines().end(); ++it)
683        {
684            file << (*it) << std::endl;
685        }
686
687        file.close();
688    }
689}
Note: See TracBrowser for help on using the repository browser.