Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 588 was 513, checked in by nicolasc, 17 years ago

added copyright notice
network still need to be done

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