Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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