Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 708 was 708, checked in by rgrieder, 16 years ago
  • added Vector2, Vector3, Matrix3, ColourValue, Quaternion and String to the misc folder as header files (each of them contains #include <string> … typedef std::string String , etc.)
  • please use String from now on by including <misc/String.h"
  • removed #include <OgreVector3.h", etc. from "CoreIncludes.h" (adjusted all source files)
  • adjusted all the source files (except network, that keeps <string> for the moment) (what a mess..)
  • moved usleep hack to misc/Sleep.h
  • relative include paths for files from other root directories (like misc, network, etc.) (but it stills writes "../Orxonox.h" when in folder orxonox/objects)
  • "OgreSceneManager.h" —> <OgreSceneManager.h>
  • included OrxonoxPrereqs in every file in folder orxonox
  • moved HUD and ParticleInterface to namespace orxonox
  • removed some using namespace Ogre/std when appropriate
  • I hope I haven't forgotten important points..
File size: 43.5 KB
RevLine 
[513]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:
[670]22 *      Fabian 'x3n' Landau
[513]23 *   Co-authors:
24 *      ...
25 *
26 */
27
[497]28#include <fstream>
[682]29
[708]30#include "misc/Tokenizer.h"
31#include "misc/String2Number.h"
[682]32#include "ConfigValueContainer.h"
[497]33
34#define CONFIGFILEPATH "orxonox.ini"
35
36namespace orxonox
37{
38    /**
[667]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.
[497]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    */
[708]45    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, int defvalue)
[497]46    {
[705]47        this->bAddedDescription_ = false;
[667]48        this->classname_ = classname;
49        this->varname_ = varname;
50        this->type_ = Int;
[497]51
[703]52        this->defvalueString_ = number2String(defvalue, "0");                       // Try to convert the default-value to a string
53        this->searchConfigFileLine();                                               // Search the entry in the config-file
[497]54
[708]55        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]56        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
57            this->resetConfigFileEntry();                                           // The conversion failed
[497]58    }
59
60    /**
[667]61        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
62        @param value This is only needed to determine the right type.
[497]63        @param classname The name of the class the variable belongs to
64        @param varname The name of the variable
65        @param defvalue The default-value
66    */
[708]67    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, unsigned int defvalue)
[667]68    {
[705]69        this->bAddedDescription_ = false;
[667]70        this->classname_ = classname;
71        this->varname_ = varname;
72        this->type_ = uInt;
73
[703]74        this->defvalueString_ = number2String(defvalue, "0");                       // Try to convert the default-value to a string
75        this->searchConfigFileLine();                                               // Search the entry in the config-file
[667]76
[708]77        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]78        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
79            this->resetConfigFileEntry();                                           // The conversion failed
[667]80    }
81
82    /**
83        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
84        @param value This is only needed to determine the right type.
85        @param classname The name of the class the variable belongs to
86        @param varname The name of the variable
87        @param defvalue The default-value
88    */
[708]89    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, char defvalue)
[667]90    {
[705]91        this->bAddedDescription_ = false;
[667]92        this->classname_ = classname;
93        this->varname_ = varname;
94        this->type_ = Char;
95
[703]96        this->defvalueString_ = number2String((int)defvalue, "0");                  // Try to convert the default-value to a string
97        this->searchConfigFileLine();                                               // Search the entry in the config-file
[667]98
[708]99        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]100        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
101            this->resetConfigFileEntry();                                           // The conversion failed
[667]102    }
103
104    /**
105        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
106        @param value This is only needed to determine the right type.
107        @param classname The name of the class the variable belongs to
108        @param varname The name of the variable
109        @param defvalue The default-value
110    */
[708]111    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, unsigned char defvalue)
[667]112    {
[705]113        this->bAddedDescription_ = false;
[667]114        this->classname_ = classname;
115        this->varname_ = varname;
116        this->type_ = uChar;
117
[703]118        this->defvalueString_ = number2String((unsigned int)defvalue, "0");         // Try to convert the default-value to a string
119        this->searchConfigFileLine();                                               // Search the entry in the config-file
[667]120
[708]121        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]122        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
123            this->resetConfigFileEntry();                                           // The conversion failed
[667]124    }
125
126    /**
127        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
128        @param value This is only needed to determine the right type.
129        @param classname The name of the class the variable belongs to
130        @param varname The name of the variable
131        @param defvalue The default-value
132    */
[708]133    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, float defvalue)
[667]134    {
[705]135        this->bAddedDescription_ = false;
[667]136        this->classname_ = classname;
137        this->varname_ = varname;
138        this->type_ = Float;
139
[703]140        this->defvalueString_ = number2String(defvalue, "0.000000");                // Try to convert the default-value to a string
141        this->searchConfigFileLine();                                               // Search the entry in the config-file
[667]142
[708]143        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]144        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
145            this->resetConfigFileEntry();                                           // The conversion failed
[667]146    }
147
148    /**
149        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
150        @param value This is only needed to determine the right type.
151        @param classname The name of the class the variable belongs to
152        @param varname The name of the variable
153        @param defvalue The default-value
154    */
[708]155    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, double defvalue)
[497]156    {
[705]157        this->bAddedDescription_ = false;
[667]158        this->classname_ = classname;
159        this->varname_ = varname;
160        this->type_ = Double;
[497]161
[703]162        this->defvalueString_ = number2String(defvalue, "0.000000");                // Try to convert the default-value to a string
163        this->searchConfigFileLine();                                               // Search the entry in the config-file
[497]164
[708]165        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]166        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
167            this->resetConfigFileEntry();                                           // The conversion failed
[497]168    }
169
170    /**
[667]171        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
172        @param value This is only needed to determine the right type.
[497]173        @param classname The name of the class the variable belongs to
174        @param varname The name of the variable
175        @param defvalue The default-value
176    */
[708]177    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, long double defvalue)
[703]178    {
[705]179        this->bAddedDescription_ = false;
[703]180        this->classname_ = classname;
181        this->varname_ = varname;
182        this->type_ = LongDouble;
183
184        this->defvalueString_ = number2String(defvalue, "0.000000");                // Try to convert the default-value to a string
185        this->searchConfigFileLine();                                               // Search the entry in the config-file
186
[708]187        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]188        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
189            this->resetConfigFileEntry();                                           // The conversion failed
190    }
191
192    /**
193        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
194        @param value This is only needed to determine the right type.
195        @param classname The name of the class the variable belongs to
196        @param varname The name of the variable
197        @param defvalue The default-value
198    */
[708]199    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, bool defvalue)
[497]200    {
[705]201        this->bAddedDescription_ = false;
[667]202        this->classname_ = classname;
203        this->varname_ = varname;
204        this->type_ = Bool;
205
[497]206        // Convert the default-value from bool to string
207        if (defvalue)
[667]208            this->defvalueString_ = "true";
[497]209        else
[667]210            this->defvalueString_ = "false";
[497]211
[703]212        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]213        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]214        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
215            this->resetConfigFileEntry();                                           // The conversion failed
[497]216    }
217
218    /**
[667]219        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
220        @param value This is only needed to determine the right type.
[497]221        @param classname The name of the class the variable belongs to
222        @param varname The name of the variable
223        @param defvalue The default-value
224    */
[708]225    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, const String& defvalue)
[667]226    {
[705]227        this->bAddedDescription_ = false;
[667]228        this->classname_ = classname;
229        this->varname_ = varname;
[708]230        this->type_ = _String;
[667]231
[703]232        this->defvalueString_ = "\"" + defvalue + "\"";                             // Convert the string to a "config-file-string" with quotes
233        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]234        String valueString = this->parseValueString(false);                    // Parses the value string from the config-file-entry
[703]235        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
236            this->resetConfigFileEntry();                                           // The conversion failed
[667]237    }
238
239    /**
240        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
241        @param value This is only needed to determine the right type.
242        @param classname The name of the class the variable belongs to
243        @param varname The name of the variable
244        @param defvalue The default-value
245    */
[708]246    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, const char* defvalue)
[497]247    {
[705]248        this->bAddedDescription_ = false;
[667]249        this->classname_ = classname;
250        this->varname_ = varname;
251        this->type_ = ConstChar;
[497]252
[708]253        this->defvalueString_ = "\"" + String(defvalue) + "\"";                // Convert the string to a "config-file-string" with quotes
[703]254        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]255        String valueString = this->parseValueString(false);                    // Parses the value string from the config-file-entry
[703]256        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
257            this->resetConfigFileEntry();                                           // The conversion failed
[497]258    }
259
260    /**
[667]261        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
262        @param value This is only needed to determine the right type.
[497]263        @param classname The name of the class the variable belongs to
264        @param varname The name of the variable
265        @param defvalue The default-value
266    */
[708]267    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, Vector2 defvalue)
[497]268    {
[705]269        this->bAddedDescription_ = false;
[667]270        this->classname_ = classname;
271        this->varname_ = varname;
[708]272        this->type_ = _Vector2;
[667]273
[497]274        // Try to convert the default-value from Vector2 to string
275        std::ostringstream ostream;
276        if (ostream << "(" << defvalue.x << "," << defvalue.y << ")")
[667]277            this->defvalueString_ = ostream.str();
[497]278        else
[667]279            this->defvalueString_ = "(0,0)";
[497]280
[703]281        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]282        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]283        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
284            this->resetConfigFileEntry();                                           // The conversion failed
[497]285    }
286
287    /**
[667]288        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
289        @param value This is only needed to determine the right type.
[497]290        @param classname The name of the class the variable belongs to
291        @param varname The name of the variable
292        @param defvalue The default-value
293    */
[708]294    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, Vector3 defvalue)
[497]295    {
[705]296        this->bAddedDescription_ = false;
[667]297        this->classname_ = classname;
298        this->varname_ = varname;
[708]299        this->type_ = _Vector3;
[667]300
[497]301        // Try to convert the default-value from Vector3 to string
302        std::ostringstream ostream;
303        if (ostream << "(" << defvalue.x << "," << defvalue.y << "," << defvalue.z << ")")
[667]304            this->defvalueString_ = ostream.str();
[497]305        else
[667]306            this->defvalueString_ = "(0,0,0)";
[497]307
[703]308        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]309        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]310        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
311            this->resetConfigFileEntry();                                           // The conversion failed
[497]312    }
313
314    /**
[667]315        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
316        @param value This is only needed to determine the right type.
[497]317        @param classname The name of the class the variable belongs to
318        @param varname The name of the variable
319        @param defvalue The default-value
320    */
[708]321    ConfigValueContainer::ConfigValueContainer(const String& classname, const String& varname, ColourValue defvalue)
[497]322    {
[705]323        this->bAddedDescription_ = false;
[667]324        this->classname_ = classname;
325        this->varname_ = varname;
[708]326        this->type_ = _ColourValue;
[667]327
[497]328        // Try to convert the default-value from ColourValue to string
329        std::ostringstream ostream;
330        if (ostream << "(" << defvalue.r << "," << defvalue.g << "," << defvalue.b << "," << defvalue.a << ")")
[667]331            this->defvalueString_ = ostream.str();
[497]332        else
[667]333            this->defvalueString_ = "(0,0,0,0)";
[497]334
[703]335        this->searchConfigFileLine();                                               // Search the entry in the config-file
[708]336        String valueString = this->parseValueString();                         // Parses the value string from the config-file-entry
[703]337        if (!this->parseSting(valueString, defvalue))                               // Try to convert the string to a value
338            this->resetConfigFileEntry();                                           // The conversion failed
339    }
[497]340
[703]341    /**
[708]342        @brief Parses a given String into a value of the type of the associated variable and assigns it.
[703]343        @param input The string to convert
344        @return True if the string was successfully parsed
345    */
[708]346    bool ConfigValueContainer::parseSting(const String& input)
[703]347    {
348        if (this->type_ == ConfigValueContainer::Int)
349            return this->parseSting(input, this->value_.value_int_);
350        else if (this->type_ == ConfigValueContainer::uInt)
351            return this->parseSting(input, this->value_.value_uint_);
352        else if (this->type_ == ConfigValueContainer::Char)
353            return this->parseSting(input, this->value_.value_char_);
354        else if (this->type_ == ConfigValueContainer::uChar)
355            return this->parseSting(input, this->value_.value_uchar_);
356        else if (this->type_ == ConfigValueContainer::Float)
357            return this->parseSting(input, this->value_.value_float_);
358        else if (this->type_ == ConfigValueContainer::Double)
359            return this->parseSting(input, this->value_.value_double_);
360        else if (this->type_ == ConfigValueContainer::LongDouble)
361            return this->parseSting(input, this->value_.value_long_double_);
362        else if (this->type_ == ConfigValueContainer::Bool)
363            return this->parseSting(input, this->value_.value_bool_);
[708]364        else if (this->type_ == ConfigValueContainer::_String)
[703]365            return this->parseSting(input, this->value_string_);
366        else if (this->type_ == ConfigValueContainer::ConstChar)
367            return this->parseSting(input, this->value_string_);
[708]368        else if (this->type_ == ConfigValueContainer::_Vector2)
[703]369            return this->parseSting(input, this->value_vector2_);
[708]370        else if (this->type_ == ConfigValueContainer::_Vector3)
[703]371            return this->parseSting(input, this->value_vector3_);
[708]372        else if (this->type_ == ConfigValueContainer::_ColourValue)
[703]373            return this->parseSting(input, this->value_colourvalue_);
374
375        return false;
376    }
377
378    /**
[708]379        @brief Parses a given String into a value of the type int and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]380        @param input The string to convert
381        @param defvalue The default-value
382        @return True if the string was successfully parsed
383    */
[708]384    bool ConfigValueContainer::parseSting(const String& input, int defvalue)
[703]385    {
386        return string2Number(this->value_.value_int_, input, defvalue);
387    }
388
389    /**
[708]390        @brief Parses a given String into a value of the type unsigned int and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]391        @param input The string to convert
392        @param defvalue The default-value
393        @return True if the string was successfully parsed
394    */
[708]395    bool ConfigValueContainer::parseSting(const String& input, unsigned int defvalue)
[703]396    {
397        return string2Number(this->value_.value_uint_, input, defvalue);
398    }
399
400    /**
[708]401        @brief Parses a given String into a value of the type char and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]402        @param input The string to convert
403        @param defvalue The default-value
404        @return True if the string was successfully parsed
405    */
[708]406    bool ConfigValueContainer::parseSting(const String& input, char defvalue)
[703]407    {
408        // I used value_int_ instead of value_char_ to avoid number <-> char confusion in the config-file
409        return string2Number(this->value_.value_int_, input, (int)defvalue);
410    }
411
412    /**
[708]413        @brief Parses a given String into a value of the type unsigned char and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]414        @param input The string to convert
415        @param defvalue The default-value
416        @return True if the string was successfully parsed
417    */
[708]418    bool ConfigValueContainer::parseSting(const String& input, unsigned char defvalue)
[703]419    {
420        // I used value_uint_ instead of value_uchar_ to avoid number <-> char confusion in the config-file
421        return string2Number(this->value_.value_uint_, input, (unsigned int)defvalue);
422    }
423
424    /**
[708]425        @brief Parses a given String into a value of the type float and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]426        @param input The string to convert
427        @param defvalue The default-value
428        @return True if the string was successfully parsed
429    */
[708]430    bool ConfigValueContainer::parseSting(const String& input, float defvalue)
[703]431    {
432        return string2Number(this->value_.value_float_, input, defvalue);
433    }
434
435    /**
[708]436        @brief Parses a given String into a value of the type double and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]437        @param input The string to convert
438        @param defvalue The default-value
439        @return True if the string was successfully parsed
440    */
[708]441    bool ConfigValueContainer::parseSting(const String& input, double defvalue)
[703]442    {
443        return string2Number(this->value_.value_double_, input, defvalue);
444    }
445
446    /**
[708]447        @brief Parses a given String into a value of the type long double and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]448        @param input The string to convert
449        @param defvalue The default-value
450        @return True if the string was successfully parsed
451    */
[708]452    bool ConfigValueContainer::parseSting(const String& input, long double defvalue)
[703]453    {
454        return string2Number(this->value_.value_long_double_, input, defvalue);
455    }
456
457    /**
[708]458        @brief Parses a given String into a value of the type bool and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]459        @param input The string to convert
460        @param defvalue The default-value
461        @return True if the string was successfully parsed
462    */
[708]463    bool ConfigValueContainer::parseSting(const String& input, bool defvalue)
[703]464    {
465        // Try to parse the value-string - is it a word?
466        if (input.find("true") < input.size()
467         || input.find("True") < input.size()
468         || input.find("yes") < input.size()
469         || input.find("Yes") < input.size())
470            this->value_.value_bool_ = true;
471        else if (input.find("false") < input.size()
472              || input.find("False") < input.size()
473              || input.find("no") < input.size()
474              || input.find("No") < input.size())
475            this->value_.value_bool_ = false;
476        else
477        {
478            // Its not a known word - is it a number?
479            return string2Number(this->value_.value_bool_, input, defvalue);
480        }
481
482        return true;
483    }
484
485    /**
[708]486        @brief Parses a given String into a value of the type String and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]487        @param input The string to convert
488        @param defvalue The default-value
489        @return True if the string was successfully parsed
490    */
[708]491    bool ConfigValueContainer::parseSting(const String& input, const String& defvalue)
[703]492    {
493        // Strip the quotes
494        unsigned int pos1 = input.find("\"") + 1;
495        unsigned int pos2 = input.find("\"", pos1);
496
497        // Check if the entry was correctly quoted
498        if (pos1 < input.length() && pos2 < input.length() && !(input.find("\"", pos2 + 1) < input.length()))
499        {
500            // It was - get the string between the quotes
501            this->value_string_ = input.substr(pos1, pos2 - pos1);
502            return true;
503        }
504
505        // It wasn't - use the default-value and restore the entry in the config-file.
506        this->value_string_ = defvalue;
507        return false;
508    }
509
510    /**
[708]511        @brief Parses a given String into a value of the type const char* and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]512        @param input The string to convert
513        @param defvalue The default-value
514        @return True if the string was successfully parsed
515    */
[708]516    bool ConfigValueContainer::parseSting(const String& input, const char* defvalue)
[703]517    {
518        // Strip the quotes
519        unsigned int pos1 = input.find("\"") + 1;
520        unsigned int pos2 = input.find("\"", pos1);
521
522        // Check if the entry was correctly quoted
523        if (pos1 < input.length() && pos2 < input.length() && !(input.find("\"", pos2 + 1) < input.length()))
524        {
525            // It was - get the string between the quotes
526            this->value_string_ = input.substr(pos1, pos2 - pos1);
527            return true;
528        }
529
530        // It wasn't - use the default-value and restore the entry in the config-file.
531        this->value_string_ = defvalue;
532        return false;
533    }
534
535    /**
[708]536        @brief Parses a given String into a value of the type _Vector2 and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]537        @param input The string to convert
538        @param defvalue The default-value
539        @return True if the string was successfully parsed
540    */
[708]541    bool ConfigValueContainer::parseSting(const String& input, const Vector2& defvalue)
[703]542    {
[497]543        // Strip the value-string
[703]544        unsigned int pos1 = input.find("(") + 1;
545        unsigned int pos2 = input.find(")", pos1);
[497]546
[703]547        // Try to convert the stripped value-string to Vector2
548        if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2)
549        {
[708]550            std::vector<String> tokens = tokenize(input.substr(pos1, pos2 - pos1), ",");
[703]551            if (!string2Number(this->value_vector2_.x, tokens[0], defvalue.x))
552            {
553                this->value_vector2_ = defvalue;
554                return false;
555            }
556            if (!string2Number(this->value_vector2_.y, tokens[1], defvalue.y))
557            {
558                this->value_vector2_ = defvalue;
559                return false;
560            }
561
562            return true;
563        }
564
565        this->value_vector2_ = defvalue;
566        return false;
567    }
568
569    /**
[708]570        @brief Parses a given String into a value of the type Vector3 and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]571        @param input The string to convert
572        @param defvalue The default-value
573        @return True if the string was successfully parsed
574    */
[708]575    bool ConfigValueContainer::parseSting(const String& input, const Vector3& defvalue)
[703]576    {
577        // Strip the value-string
578        unsigned int pos1 = input.find("(") + 1;
579        unsigned int pos2 = input.find(")", pos1);
580
[497]581        // Try to convert the stripped value-string to Vector3
[703]582        if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2)
[497]583        {
[708]584            std::vector<String> tokens = tokenize(input.substr(pos1, pos2 - pos1), ",");
[703]585            if (!string2Number(this->value_vector3_.x, tokens[0], defvalue.x))
586            {
587                this->value_vector3_ = defvalue;
588                return false;
589            }
590            if (!string2Number(this->value_vector3_.y, tokens[1], defvalue.y))
591            {
592                this->value_vector3_ = defvalue;
593                return false;
594            }
595            if (!string2Number(this->value_vector3_.z, tokens[2], defvalue.z))
596            {
597                this->value_vector3_ = defvalue;
598                return false;
599            }
600
601            return true;
602        }
603
604        this->value_vector3_ = defvalue;
605        return false;
606    }
607
608    /**
[708]609        @brief Parses a given String into a value of the type ColourValue and assigns it to the right variable. If the conversion failed, the default-value gets assigned.
[703]610        @param input The string to convert
611        @param defvalue The default-value
612        @return True if the string was successfully parsed
613    */
[708]614    bool ConfigValueContainer::parseSting(const String& input, const ColourValue& defvalue)
[703]615    {
616        // Strip the value-string
617        unsigned int pos1 = input.find("(") + 1;
618        unsigned int pos2 = input.find(")", pos1);
619
620        // Try to convert the stripped value-string to Vector3
621        if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2)
622        {
[708]623            std::vector<String> tokens = tokenize(input.substr(pos1, pos2 - pos1), ",");
[667]624            if (!string2Number(this->value_colourvalue_.r, tokens[0], defvalue.r))
[703]625            {
626                this->value_colourvalue_ = defvalue;
627                return false;
628            }
[667]629            if (!string2Number(this->value_colourvalue_.g, tokens[1], defvalue.g))
[703]630            {
631                this->value_colourvalue_ = defvalue;
632                return false;
633            }
[667]634            if (!string2Number(this->value_colourvalue_.b, tokens[2], defvalue.b))
[703]635            {
636                this->value_colourvalue_ = defvalue;
637                return false;
638            }
[667]639            if (!string2Number(this->value_colourvalue_.a, tokens[3], defvalue.a))
[703]640            {
641                this->value_colourvalue_ = defvalue;
642                return false;
643            }
644
645            return true;
[497]646        }
[703]647
648        this->value_colourvalue_ = defvalue;
649        return false;
[497]650    }
651
652    /**
[703]653        @brief Sets the corresponding entry in the config-file back to the default value.
[497]654    */
[703]655    void ConfigValueContainer::resetConfigFileEntry()
[497]656    {
[667]657        (*this->configFileLine_) = this->varname_ + "=" + this->defvalueString_;
658        ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
659    }
[497]660
[703]661    /**
[704]662        @brief Sets the value of the variable back to the default value and resets the config-file entry.
[703]663    */
664    void ConfigValueContainer::resetConfigValue()
665    {
[704]666        this->parseSting(this->defvalueString_);
667        this->resetConfigFileEntry();
[703]668    }
[497]669
670    /**
671        @brief Searches the corresponding entry in the config-file and creates it, if there is no entry.
672    */
673    void ConfigValueContainer::searchConfigFileLine()
674    {
675        // Read the file if needed
[698]676        if (!ConfigValueContainer::finishedReadingConfigFile())
[497]677            ConfigValueContainer::readConfigFile(CONFIGFILEPATH);
678
679        // The string of the section we're searching
[708]680        String section = "";
[497]681        section.append("[");
682        section.append(this->classname_);
683        section.append("]");
684
685        // Iterate through all config-file-lines
686        bool success = false;
[708]687        std::list<String>::iterator it1;
[698]688        for(it1 = ConfigValueContainer::getConfigFileLines().begin(); it1 != ConfigValueContainer::getConfigFileLines().end(); ++it1)
[497]689        {
690            // Don't try to parse comments
691            if (this->isComment(*it1))
692                continue;
693
694            if ((*it1).find(section) < (*it1).length())
695            {
696                // We found the right section
697                bool bLineIsEmpty = false;
[708]698                std::list<String>::iterator positionToPutNewLineAt;
[497]699
700                // Iterate through all lines in the section
[708]701                std::list<String>::iterator it2;
[698]702                for(it2 = ++it1; it2 != ConfigValueContainer::getConfigFileLines().end(); ++it2)
[497]703                {
704                    // Don't try to parse comments
705                    if (this->isComment(*it2))
706                        continue;
707
708                    // This if-else block is used to write a new line right after the last line of the
709                    // section but in front of the following empty lines before the next section.
710                    // (So this helps to keep a nice formatting with empty-lines between sections in the config-file)
711                    if (this->isEmpty(*it2))
712                    {
713                        if (!bLineIsEmpty)
714                        {
715                            bLineIsEmpty = true;
716                            positionToPutNewLineAt = it2;
717                        }
718                    }
719                    else
720                    {
721                        if (!bLineIsEmpty)
722                            positionToPutNewLineAt = it2;
723
724                        bLineIsEmpty = false;
725                    }
726
727                    // Look out for the beginning of the next section
728                    unsigned int open = (*it2).find("[");
729                    unsigned int close = (*it2).find("]");
730                    if ((open < (*it2).length()) && (close < (*it2).length()) && (open < close))
731                    {
732                        // The next section startet, so our line isn't yet in the file - now we add it and safe the file
[698]733                        this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_);
[497]734                        ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
735                        success = true;
736                        break;
737                    }
738
739                    // Look out for the variable-name
740                    if ((*it2).find(this->varname_) < (*it2).length())
741                    {
742                        // We found the right line - safe it and return
743                        this->configFileLine_ = it2;
744                        success = true;
745                        break;
746                    }
747                }
748
749                // Check if we succeeded
750                if (!success)
751                {
752                    // Looks like we found the right section, but the file ended without containing our variable - so we add it and safe the file
[698]753                    this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_);
[497]754                    ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);
755                    success = true;
756                }
757                break;
758            }
759        }
760
761        // Check if we succeeded
762        if (!success)
763        {
764            // We obviously didn't found the right section, so we'll create it
[698]765            this->getConfigFileLines().push_back("[" + this->classname_ + "]");                   // Create the section
766            this->getConfigFileLines().push_back(this->varname_ + "=" + this->defvalueString_);   // Create the line
767            this->configFileLine_ = --this->getConfigFileLines().end();                           // Set the pointer to the last element
[497]768            success = true;
[698]769            this->getConfigFileLines().push_back("");                                             // Add an empty line - this is needed for the algorithm in the searchConfigFileLine-function
[667]770            ConfigValueContainer::writeConfigFile(CONFIGFILEPATH);                              // Save the changed config-file
[497]771        }
772    }
773
774    /**
775        @brief Determines if a line in the config-file is a comment.
776        @param line The line to check
777        @return True = it's a comment
778    */
[708]779    bool ConfigValueContainer::isComment(const String& line)
[497]780    {
781        // Strip the line, whitespaces are disturbing
[708]782        String teststring = getStrippedLine(line);
[497]783
784        // There are four possible comment-symbols:
785        //  1) #comment in script-language style
786        //  2) %comment in matlab style
787        //  3) ;comment in unreal tournament config-file style
788        //  4) //comment in code style
789        if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[0] == '/'))
790            return true;
791
792        return false;
793    }
794
795    /**
796        @brief Determines if a line in the config-file is empty (contains only whitespaces).
797        @param line The line to check
798        @return True = it's empty
799    */
[708]800    bool ConfigValueContainer::isEmpty(const String& line)
[497]801    {
802        return getStrippedLine(line) == "";
803    }
804
805    /**
806        @brief Removes all whitespaces from a line.
807        @param line The line to strip
808        @return The stripped line
809    */
[708]810    String ConfigValueContainer::getStrippedLine(const String& line)
[497]811    {
[708]812        String output = line;
[497]813        unsigned int pos;
814        while ((pos = output.find(" ")) < output.length())
815            output.erase(pos, 1);
816        while ((pos = output.find("\t")) < output.length())
817            output.erase(pos, 1);
818
819        return output;
820    }
821
822    /**
823        @brief Returns the part in the corresponding config-file-entry of the container that defines the value.
824        @param bStripped True = strip the value-string
825        @return The value-string
826    */
[708]827    String ConfigValueContainer::parseValueString(bool bStripped)
[497]828    {
[708]829        String output;
[497]830        if (bStripped)
831            output = this->getStrippedLine(*this->configFileLine_);
832        else
833            output = *this->configFileLine_;
834
835        return output.substr(output.find("=") + 1);
836    }
837
838    /**
[698]839        @returns a list, containing all entrys in the config-file.
840    */
[708]841    std::list<String>& ConfigValueContainer::getConfigFileLines()
[698]842    {
843        // This is done to avoid problems while executing this code before main()
[708]844        static std::list<String> configFileLinesStaticReference = std::list<String>();
[698]845        return configFileLinesStaticReference;
846    }
847
848    /**
849        @brief Returns true if the ConfigFile is read and stored into the ConfigFile-lines-list.
850        @param finished This is used to change the state
851        @return True if the ConfigFile is read and stored into the ConfigFile-lines-list
852    */
853    bool ConfigValueContainer::finishedReadingConfigFile(bool finished)
854    {
855        // This is done to avoid problems while executing this code before main()
856        static bool finishedReadingConfigFileStaticVariable = false;
857
858        if (finished)
859            finishedReadingConfigFileStaticVariable = true;
860
861        return finishedReadingConfigFileStaticVariable;
862    }
863
864    /**
[497]865        @brief Reads the config-file and stores the lines in a list.
866        @param filename The name of the config-file
867    */
[708]868    void ConfigValueContainer::readConfigFile(const String& filename)
[497]869    {
870        // This creates the file if it's not existing
871        std::ofstream createFile;
872        createFile.open(filename.c_str(), std::fstream::app);
873        createFile.close();
874
875        // Open the file
876        std::ifstream file;
877        file.open(filename.c_str(), std::fstream::in);
878
[704]879        if (!file.is_open())
880        {
881            COUT(1) << "Error: Couldn't open config-file " << filename << " to read the config values!" << std::endl;
882            return;
883        }
884
[497]885        char line[1024];
886
887        // Iterate through the file and add the lines into the list
888        while (file.good() && !file.eof())
889        {
890            file.getline(line, 1024);
[698]891            ConfigValueContainer::getConfigFileLines().push_back(line);
[497]892//            std::cout << "### ->" << line << "<- : empty: " << isEmpty(line) << " comment: " << isComment(line) << std::endl;
893        }
894
895        // The last line is useless
[698]896        ConfigValueContainer::getConfigFileLines().pop_back();
[497]897
898        // Add an empty line to the end of the file if needed
899        // this is needed for the algorithm in the searchConfigFileLine-function
[698]900        if ((ConfigValueContainer::getConfigFileLines().size() > 0) && !isEmpty(*ConfigValueContainer::getConfigFileLines().rbegin()))
[497]901        {
902//            std::cout << "### newline added" << std::endl;
[698]903            ConfigValueContainer::getConfigFileLines().push_back("");
[497]904        }
905
906        file.close();
[704]907
908        ConfigValueContainer::finishedReadingConfigFile(true);
[497]909    }
910
911    /**
[705]912        @brief Writes the content of the list, containing all lines of the config-file, into the config-file.
913        @param filename The name of the config-file
914    */
[708]915    void ConfigValueContainer::writeConfigFile(const String& filename)
[497]916    {
917        // Make sure we stored the config-file in the list
[698]918        if (!ConfigValueContainer::finishedReadingConfigFile())
[497]919            ConfigValueContainer::readConfigFile(filename);
920
921        // Open the file
922        std::ofstream file;
923        file.open(filename.c_str(), std::fstream::out);
924
[704]925        if (!file.is_open())
926        {
927            COUT(1) << "Error: Couldn't open config-file " << filename << " to write the config values!" << std::endl;
928            return;
929        }
930
[497]931        // Iterate through the list an write the lines into the file
[708]932        std::list<String>::iterator it;
[704]933        for (it = ConfigValueContainer::getConfigFileLines().begin(); it != ConfigValueContainer::getConfigFileLines().end(); ++it)
[497]934        {
935            file << (*it) << std::endl;
936        }
937
938        file.close();
939    }
[705]940
941    /**
942        @brief Adds a description to the config-value.
943        @param description The description
944    */
[708]945    void ConfigValueContainer::description(const String& description)
[705]946    {
947        if (!this->bAddedDescription_)
948        {
[708]949            this->description_ = String("ConfigValueDescription::" + this->classname_ + "::" + this->varname_);
[705]950            Language::getLanguage().addEntry(description_, description);
951            this->bAddedDescription_ = true;
952        }
953    }
[497]954}
Note: See TracBrowser for help on using the repository browser.