Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/util/multi_type.cc @ 9869

Last change on this file since 9869 was 9869, checked in by bensch, 18 years ago

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 11.6 KB
RevLine 
[4744]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
[5643]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[5536]18#include "multi_type.h"
[1853]19
[7199]20#include <sstream>
[5659]21
22#ifdef DEBUG
23#include "debug.h"
24#endif
25
[5545]26/**
[7199]27 * @brief creates a multiType without any stored value at all.
[5545]28 */
[7197]29MultiType::MultiType(MT_Type type)
[5540]30{
[7197]31  this->type = type;
[7200]32  switch (this->type)
33  {
[8035]34    default:
[9869]35    this->value.Float = 0.0f;
36    break;
[8035]37    case MT_BOOL:
[9869]38    this->value.Bool = false;
39    break;
[8035]40    case MT_INT:
[9869]41    this->value.Int = 0;
42    break;
[8035]43    case MT_FLOAT:
[9869]44    this->value.Float = 0.0f;
45    break;
[8035]46    case MT_CHAR:
[9869]47    this->value.Char = '\0';
48    break;
[8035]49    case MT_STRING:
[9869]50    this->storedString = "";
51    break;
[7200]52  }
[5540]53}
[5545]54/**
[7199]55 * @brief creates a multiType out of a boolean
[5545]56 * @param value the Value of this MulitType
57 */
[5537]58MultiType::MultiType(bool value)
59{
[5540]60  this->setBool(value);
[5537]61}
62
[5545]63/**
[7199]64 * @brief creates a multiType out of an integer
[5545]65 * @param value the Value of this MulitType
66 */
[5536]67MultiType::MultiType(int value)
68{
[5540]69  this->setInt(value);
[5536]70}
[1856]71
[5545]72/**
[7199]73 * @brief creates a multiType out of a float (double)
[5545]74 * @param value the Value of this MulitType
75 */
[5539]76MultiType::MultiType(double value)
[3365]77{
[5540]78  this->setFloat(value);
[5536]79}
[4320]80
[5545]81/**
[7199]82 * @brief creates a multiType out of a char
[5545]83 * @param value the Value of this MulitType
84 */
[5536]85MultiType::MultiType(char value)
86{
[5540]87  this->setChar(value);
[3365]88}
[1853]89
[5545]90/**
[7199]91 * @brief creates a multiType out of a String
92 * @param value the Value of this MulitType
93 */
94MultiType::MultiType(const std::string& value)
95{
96  this->setString(value);
97}
98
99/**
100 * @brief constructs a new MultiType from another one (copy)
101 */
[5659]102MultiType::MultiType(const MultiType& multiType)
103{
104  *this = multiType;
105}
106
[3245]107/**
[7199]108 * @brief standard deconstructor
[3245]109*/
[5536]110MultiType::~MultiType ()
[7199]111{ }
[5537]112
[5540]113/**
[7199]114 * @brief copy operator
[5540]115 * @param mt: the entity to copy
[7199]116 * @returns A Copy of itself. (strings inside are copied as well)
[5540]117 */
[5659]118MultiType& MultiType::operator= (const MultiType& mt)
119{
120  this->type = mt.type;
121  this->value = mt.value;
[7199]122  this->storedString = mt.storedString;
123
[5659]124  return *this;
125}
126
[5545]127/**
[6643]128 * @brief checks if the two Multitypes match
129 * @param mt MultiType to check against this one
130 * @returns true on match. false otherwise
131 *
132 * Two MultiType match if and only if
133 *  1. the internal Type is the same
134 *  2. the stored values match
135 */
136bool MultiType::operator==(const MultiType& mt) const
137{
138  if (this->type != mt.type)
139    return false;
140
141  switch (this->type)
142  {
[8035]143    case MT_NULL:
[9869]144    return true;
[8035]145    case MT_BOOL:
[9869]146    return (this->value.Bool == mt.value.Bool);
[8035]147    case MT_INT:
[9869]148    return (this->value.Int == mt.value.Int);
[8035]149    case MT_CHAR:
[9869]150    return (this->value.Char == mt.value.Char);
[8035]151    case MT_FLOAT:
[9869]152    return (this->value.Float == mt.value.Float);
[8035]153    case MT_STRING:
[9869]154    return (this->storedString == mt.storedString);
[8316]155    default:
[9869]156    return false;
[6643]157  }
158}
159
160
161/**
[7199]162 * @brief sets the type of this MultiType and resets to the default value
[5643]163 * @param type the new Type
164 */
[6645]165void MultiType::setType(MT_Type type)
[5540]166{
[7199]167  if (this->type == type)
168    return;
169
170  switch (type)
171  {
[8035]172    case MT_BOOL:
[9869]173    this->setBool(this->getBool());
174    break;
[8035]175    case MT_INT:
[9869]176    this->setInt(this->getInt());
177    break;
[8035]178    case MT_FLOAT:
[9869]179    this->setFloat(this->getFloat());
180    break;
[8035]181    case MT_CHAR:
[9869]182    this->setChar(this->getChar());
183    break;
[8035]184    case MT_STRING:
[9869]185    this->setString(this->getString());
186    break;
[8316]187    default:
[9869]188    this->type = type;
[7199]189  }
[5540]190}
191
[5545]192/**
[7199]193 * @brief sets the Value of mt without changing the type of this MultiType
194 * @param mt: the MultiType to get the value from
195 *
196 * This is a pure Value copy. The current type will be preserved.
197 */
198void MultiType::setValueOf(const MultiType& mt)
199{
200  MT_Type prevType = this->type;
201
202  *this = mt;
203  this->setType(prevType);
204}
205
206
207/**
208 * @brief sets a new Value to the MultiType
[5545]209 * @param value the new Value as a bool
210 */
[5540]211void MultiType::setBool(bool value)
212{
213  this->type = MT_BOOL;
214  this->value.Bool = value;
215}
216
[5545]217/**
[7199]218 * @brief sets a new Value to the MultiType
[5545]219 * @param value the new Value as an int
220 */
[5540]221void MultiType::setInt(int value)
222{
223  this->type = MT_INT;
224  this->value.Int = value;
225}
226
[5545]227/**
[7199]228 * @brief sets a new Value to the MultiType
[5545]229 * @param value the new Value as a float
230 */
[5540]231void MultiType::setFloat(float value)
232{
233  this->type = MT_FLOAT;
234  this->value.Float = value;
235}
236
[5545]237/**
[7199]238 * @brief sets a new Value to the MultiType
[5545]239 * @param value the new Value as a char
240 */
[5540]241void MultiType::setChar(char value)
242{
243  this->type = MT_CHAR;
244  this->value.Char = value;
245}
246
[5545]247/**
[7199]248 * @brief sets a new Value to the MultiType
[5545]249 * @param value the new Value as a String
250 */
[7199]251void MultiType::setString(const std::string& value)
[5540]252{
253  this->type = MT_STRING;
[7199]254  this->storedString = value;
[5540]255}
256
[9869]257/**
258 * @brief stores any value to the string.
259 * @note this Value can be grabbed by using the getStoredString function.
260 */
261void MultiType::storeString()
262{
263  if (!(this->type & MT_STRING))
264    this->storedString = this->getString();
265}
[5540]266
[7199]267/**************************
268*** RETRIEVAL FUNCTIONS ***
269**************************/
[5545]270/**
271 * @returns the Value of this MultiType as a int
272 */
[5544]273bool MultiType::getBool() const
[5537]274{
275  // default case:
276  if (this->type & MT_BOOL)
277    return this->value.Bool;
278  // Special Cases:
279  else if (this->type & MT_INT) return (this->value.Int == 0)? false : true;
280  else if (this->type & MT_FLOAT) return (this->value.Float == 0.0f)? false : true;
281  else if (this->type & MT_CHAR) return (this->value.Char == '\0')? false : true;
[7199]282  else if (this->type & MT_STRING) return (this->storedString == "true" ||
283                                            this->storedString == "TRUE" ||
[9869]284                                            this->storedString != "0"); // TODO make this better...
[5538]285
286  return false;
[5537]287}
288
[5545]289/**
290 * @returns the Value of this MultiType as a int
291 */
[5544]292int MultiType::getInt() const
[5537]293{
294  // default case:
295  if (this->type & MT_INT)
296    return this->value.Int;
297  if (this->type & MT_BOOL) return (this->value.Bool)? 1 : 0;
298  else if (this->type & MT_FLOAT) return (int) this->value.Float;
299  else if (this->type & MT_CHAR) return (int) this->value.Char;
[7199]300  else if (this->type & MT_STRING)
301  {
[7284]302    std::stringstream ssStream(this->storedString);
303    int iReturn;
304    ssStream >> iReturn;
305    return iReturn;
[5538]306  }
307  return 0;
[5537]308}
309
[7199]310
[5545]311/**
312 * @returns the Value of this MultiType as a float
313 */
[5544]314float MultiType::getFloat() const
[5537]315{
[7199]316  // default case:
[5539]317  if (this->type & MT_FLOAT)
318    return this->value.Float;
319  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
[5537]320  else if (this->type & MT_INT) return (float) this->value.Int;
321  else if (this->type & MT_CHAR) return (float) this->value.Char;
[7199]322  else if (this->type & MT_STRING)
323  {
[5538]324    char* endPtr = NULL;
[7199]325    double result = strtod(this->storedString.c_str(), &endPtr);
[7284]326    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + this->storedString.size())
[5538]327      return 0.0f;
328    else
329      return result;
330  }
331  return 0.0f;
[5537]332}
333
334
[5545]335/**
336 * @returns the Value of this MultiType as a char
337 */
[5544]338char MultiType::getChar() const
[5537]339{
[7199]340  // default case:
[5537]341  if (this->type & MT_INT)
342    return this->value.Int;
343  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
344  else if (this->type & MT_INT) return (int) this->value.Int;
345  else if (this->type & MT_FLOAT) return (char) this->value.Float;
[7199]346  else if (this->type & MT_STRING) return this->storedString[0];
[5538]347
348  return '\0';
[5537]349}
350
[7199]351
[5545]352/**
353 * @returns the Value of this MultiType as a String
354 */
[7199]355std::string MultiType::getString() const
[5537]356{
[7199]357  // default case:
[5537]358  if (this->type & MT_STRING)
[7199]359    return this->storedString;
[5538]360  else
361  {
362    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
[7199]363
[5641]364    else if (this->type & MT_INT)
365    {
[7199]366      char tmpString[32];
[5538]367      sprintf(tmpString, "%d", this->value.Int);
[7199]368      return tmpString;
[5538]369    }
[7199]370    else if (this->type & MT_FLOAT)
[5538]371    {
[7199]372      char tmpString[64];
[5538]373      sprintf(tmpString, "%f", this->value.Float);
[7199]374      return tmpString;
[5538]375    }
[7200]376    else if (this->type & MT_CHAR)
377    {
378      char tmpString[2];
379      tmpString[0] = this->value.Char;
380      tmpString[1] = '\0';
381      return tmpString;
382    }
[5538]383  }
384  return "";
[5537]385}
386
[5545]387/**
[8035]388 * @brief returns a Constant string (actually this is slower than getString()
389 * @returns a constant string of the stored version's one.
[9869]390 * @note this  could lead to a inconsistency of data AND IS HIGHLY NON_THREAD_SAFE!
391 * PLEASE THINK ABOUT USING THE getStoredString function in conjunction with storeString().
[8035]392 */
393const std::string& MultiType::getConstString() const
394{
[9869]395  MultiType::constString = this->getString();
396  return MultiType::constString;
397}
[8035]398
[9869]399/**
400 * @brief returns the currently stored string.
401 * @returns the Stored string.
402 * @note Storing a string works as follows: \\
403 * MultiType a(3);  // Creates a MultiType of Type int with value 3 \\
404 * a.storeString(); // Stores the String in the internal structure. \\
405 * std::string name = a.getStoredString();
406 *
407 * This would be the same as
408 * name = a.getString();
409 * but with much more const'ness.
410 */
411const std::string& MultiType::getStoredString() const
412{
[8035]413  MultiType::constString = this->getString();
414  return MultiType::constString;
415}
416
417/**
[7199]418 * @returns a formated c-string of the held value
[5545]419 */
[7199]420const char* MultiType::getCString()
[5544]421{
[7199]422  if (this->type & MT_STRING) return this->storedString.c_str();
423  else
424  {
425    this->storedString = this->getString();
426    return this->storedString.c_str();
427  }
428}
429
430/**
431 * @brief prints out some nice debug output
432 */
433void MultiType::debug() const
434{
[5659]435#ifdef DEBUG
436  PRINT(0)
437#else
438  printf
439#endif
[7199]440  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
[7401]441   MultiType::MultiTypeToString(this->type).c_str(),
[7199]442   this->getBool(),
443   this->getInt(),
444   this->getFloat(),
445   this->getChar(),
446   this->getString().c_str()
447  );
448}
[5544]449
450
[5545]451/**
[7199]452 * @brief Resets the MultiType to default values.
[5643]453 */
454void MultiType::reset()
455{
[5659]456  switch ( this->type )
[5643]457  {
[8035]458    case MT_BOOL:
[9869]459    this->setBool(false);
460    break;
[8035]461    case MT_INT:
[9869]462    this->setInt(0);
463    break;
[8035]464    case MT_FLOAT:
[9869]465    this->setFloat(0.0f);
466    break;
[8035]467    case MT_CHAR:
[9869]468    this->setChar('\0');
469    break;
[8035]470    case MT_STRING:
[9869]471    this->setString("");
472    break;
[8035]473    default:
[5659]474#ifdef DEBUG
[9869]475    PRINTF(2)("Unknown Type not reseting\n");
[5659]476#endif
[9869]477    break;
[5643]478  }
479}
480
481/**
[7199]482 * @brief converts a MT_Type into a String
[5545]483 * @param type: the MT_Type
484 * @returns: the Type as a constant String (do not delete)
485 */
[7401]486const std::string& MultiType::MultiTypeToString(MT_Type type)
[5544]487{
[5659]488  switch ( type )
[5544]489  {
[8035]490    case MT_BOOL:
[9869]491    return MultiType::typeNames[1];
[8035]492    case MT_INT:
[9869]493    return MultiType::typeNames[2];
[8035]494    case MT_FLOAT:
[9869]495    return MultiType::typeNames[3];
[8035]496    case MT_CHAR:
[9869]497    return MultiType::typeNames[4];
[8035]498    case MT_STRING:
[9869]499    return MultiType::typeNames[5];
[8316]500    default:
[9869]501    return MultiType::typeNames[0];
[5544]502  }
503}
504
[5545]505/**
[7199]506 * @brief converts a String into a MT_Type
[5545]507 * @param type: the Type as a String
508 * @returns: the Type as MT_Type
509 */
[7221]510MT_Type MultiType::StringToMultiType(const std::string& type)
[5544]511{
[7401]512  if (type == MultiType::typeNames[1])
[5544]513    return MT_BOOL;
[7401]514  if (type == MultiType::typeNames[2])
[5544]515    return MT_INT;
[7401]516  if (type == MultiType::typeNames[3])
[5544]517    return MT_FLOAT;
[7401]518  if (type == MultiType::typeNames[4])
[5544]519    return MT_CHAR;
[7401]520  if (type == MultiType::typeNames[5])
[5544]521    return MT_STRING;
[7200]522
523  return MT_NULL;
[5544]524}
[7401]525
526
[8035]527std::string MultiType::constString = "";
[7401]528const std::string MultiType::typeNames[] =
529  {
530    "NONE",      //0
531    "bool",      //1
532    "int",       //2
533    "float",     //3
534    "char",      //4
535    "string"     //5
536  };
Note: See TracBrowser for help on using the repository browser.