Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/util/multi_type.cc @ 9312

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

minor lib cleanup

File size: 10.8 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:
[7221]35      this->value.Float = 0.0f;
36      break;
[8035]37    case MT_BOOL:
[7200]38      this->value.Bool = false;
39      break;
[8035]40    case MT_INT:
[7200]41      this->value.Int = 0;
42      break;
[8035]43    case MT_FLOAT:
[7200]44      this->value.Float = 0.0f;
45      break;
[8035]46    case MT_CHAR:
[7200]47      this->value.Char = '\0';
48      break;
[8035]49    case MT_STRING:
[7201]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:
[6643]144      return true;
[8035]145    case MT_BOOL:
[6643]146      return (this->value.Bool == mt.value.Bool);
[8035]147    case MT_INT:
[6643]148      return (this->value.Int == mt.value.Int);
[8035]149    case MT_CHAR:
[6643]150      return (this->value.Char == mt.value.Char);
[8035]151    case MT_FLOAT:
[6643]152      return (this->value.Float == mt.value.Float);
[8035]153    case MT_STRING:
[7199]154      return (this->storedString == mt.storedString);
[8316]155    default:
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:
[7199]173      this->setBool(this->getBool());
174      break;
[8035]175    case MT_INT:
[7199]176      this->setInt(this->getInt());
177      break;
[8035]178    case MT_FLOAT:
[7199]179      this->setFloat(this->getFloat());
180      break;
[8035]181    case MT_CHAR:
[7199]182      this->setChar(this->getChar());
183      break;
[8035]184    case MT_STRING:
[7199]185      this->setString(this->getString());
186      break;
[8316]187    default:
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 *
198 * @TODO speedup
199 */
200void MultiType::setValueOf(const MultiType& mt)
201{
202  MT_Type prevType = this->type;
203
204  *this = mt;
205  this->setType(prevType);
206}
207
208
209/**
210 * @brief sets a new Value to the MultiType
[5545]211 * @param value the new Value as a bool
212 */
[5540]213void MultiType::setBool(bool value)
214{
215  this->type = MT_BOOL;
216  this->value.Bool = value;
217}
218
[5545]219/**
[7199]220 * @brief sets a new Value to the MultiType
[5545]221 * @param value the new Value as an int
222 */
[5540]223void MultiType::setInt(int value)
224{
225  this->type = MT_INT;
226  this->value.Int = value;
227}
228
[5545]229/**
[7199]230 * @brief sets a new Value to the MultiType
[5545]231 * @param value the new Value as a float
232 */
[5540]233void MultiType::setFloat(float value)
234{
235  this->type = MT_FLOAT;
236  this->value.Float = value;
237}
238
[5545]239/**
[7199]240 * @brief sets a new Value to the MultiType
[5545]241 * @param value the new Value as a char
242 */
[5540]243void MultiType::setChar(char value)
244{
245  this->type = MT_CHAR;
246  this->value.Char = value;
247}
248
[5545]249/**
[7199]250 * @brief sets a new Value to the MultiType
[5545]251 * @param value the new Value as a String
252 */
[7199]253void MultiType::setString(const std::string& value)
[5540]254{
255  this->type = MT_STRING;
[7199]256  this->storedString = value;
[5540]257}
258
259
[7199]260/**************************
261*** RETRIEVAL FUNCTIONS ***
262**************************/
[5545]263/**
264 * @returns the Value of this MultiType as a int
265 */
[5544]266bool MultiType::getBool() const
[5537]267{
268  // default case:
269  if (this->type & MT_BOOL)
270    return this->value.Bool;
271  // Special Cases:
272  else if (this->type & MT_INT) return (this->value.Int == 0)? false : true;
273  else if (this->type & MT_FLOAT) return (this->value.Float == 0.0f)? false : true;
274  else if (this->type & MT_CHAR) return (this->value.Char == '\0')? false : true;
[7199]275  else if (this->type & MT_STRING) return (this->storedString == "true" ||
276                                            this->storedString == "TRUE" ||
277                                            this->storedString != "0"); //! @TODO make this better...
[5538]278
279  return false;
[5537]280}
281
[5545]282/**
283 * @returns the Value of this MultiType as a int
284 */
[5544]285int MultiType::getInt() const
[5537]286{
287  // default case:
288  if (this->type & MT_INT)
289    return this->value.Int;
290  if (this->type & MT_BOOL) return (this->value.Bool)? 1 : 0;
291  else if (this->type & MT_FLOAT) return (int) this->value.Float;
292  else if (this->type & MT_CHAR) return (int) this->value.Char;
[7199]293  else if (this->type & MT_STRING)
294  {
[7284]295    std::stringstream ssStream(this->storedString);
296    int iReturn;
297    ssStream >> iReturn;
298    return iReturn;
[5538]299  }
300  return 0;
[5537]301}
302
[7199]303
[5545]304/**
305 * @returns the Value of this MultiType as a float
306 */
[5544]307float MultiType::getFloat() const
[5537]308{
[7199]309  // default case:
[5539]310  if (this->type & MT_FLOAT)
311    return this->value.Float;
312  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
[5537]313  else if (this->type & MT_INT) return (float) this->value.Int;
314  else if (this->type & MT_CHAR) return (float) this->value.Char;
[7199]315  else if (this->type & MT_STRING)
316  {
[5538]317    char* endPtr = NULL;
[7199]318    double result = strtod(this->storedString.c_str(), &endPtr);
[7284]319    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + this->storedString.size())
[5538]320      return 0.0f;
321    else
322      return result;
323  }
324  return 0.0f;
[5537]325}
326
327
[5545]328/**
329 * @returns the Value of this MultiType as a char
330 */
[5544]331char MultiType::getChar() const
[5537]332{
[7199]333  // default case:
[5537]334  if (this->type & MT_INT)
335    return this->value.Int;
336  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
337  else if (this->type & MT_INT) return (int) this->value.Int;
338  else if (this->type & MT_FLOAT) return (char) this->value.Float;
[7199]339  else if (this->type & MT_STRING) return this->storedString[0];
[5538]340
341  return '\0';
[5537]342}
343
[7199]344
[5545]345/**
346 * @returns the Value of this MultiType as a String
347 */
[7199]348std::string MultiType::getString() const
[5537]349{
[7199]350  // default case:
[5537]351  if (this->type & MT_STRING)
[7199]352    return this->storedString;
[5538]353  else
354  {
355    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
[7199]356
[5641]357    else if (this->type & MT_INT)
358    {
[7199]359      char tmpString[32];
[5538]360      sprintf(tmpString, "%d", this->value.Int);
[7199]361      return tmpString;
[5538]362    }
[7199]363    else if (this->type & MT_FLOAT)
[5538]364    {
[7199]365      char tmpString[64];
[5538]366      sprintf(tmpString, "%f", this->value.Float);
[7199]367      return tmpString;
[5538]368    }
[7200]369    else if (this->type & MT_CHAR)
370    {
371      char tmpString[2];
372      tmpString[0] = this->value.Char;
373      tmpString[1] = '\0';
374      return tmpString;
375    }
[5538]376  }
377  return "";
[5537]378}
379
[5545]380/**
[8035]381 * @brief returns a Constant string (actually this is slower than getString()
382 * @returns a constant string of the stored version's one.
383 * @note this  could lead to a inconsistency of data
384 */
385const std::string& MultiType::getConstString() const
386{
387
388  MultiType::constString = this->getString();
389  return MultiType::constString;
390}
391
392
393/**
[7199]394 * @returns a formated c-string of the held value
[5545]395 */
[7199]396const char* MultiType::getCString()
[5544]397{
[7199]398  if (this->type & MT_STRING) return this->storedString.c_str();
399  else
400  {
401    this->storedString = this->getString();
402    return this->storedString.c_str();
403  }
404}
405
406/**
407 * @brief prints out some nice debug output
408 */
409void MultiType::debug() const
410{
[5659]411#ifdef DEBUG
412  PRINT(0)
413#else
414  printf
415#endif
[7199]416  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
[7401]417   MultiType::MultiTypeToString(this->type).c_str(),
[7199]418   this->getBool(),
419   this->getInt(),
420   this->getFloat(),
421   this->getChar(),
422   this->getString().c_str()
423  );
424}
[5544]425
426
[5545]427/**
[7199]428 * @brief Resets the MultiType to default values.
[5643]429 */
430void MultiType::reset()
431{
[5659]432  switch ( this->type )
[5643]433  {
[8035]434    case MT_BOOL:
[5643]435      this->setBool(false);
[7200]436      break;
[8035]437    case MT_INT:
[5643]438      this->setInt(0);
439      break;
[8035]440    case MT_FLOAT:
[5643]441      this->setFloat(0.0f);
442      break;
[8035]443    case MT_CHAR:
[5643]444      this->setChar('\0');
445      break;
[8035]446    case MT_STRING:
[5643]447      this->setString("");
448      break;
[8035]449    default:
[5659]450#ifdef DEBUG
451      PRINTF(2)("Unknown Type not reseting\n");
452#endif
453      break;
[5643]454  }
455}
456
457/**
[7199]458 * @brief converts a MT_Type into a String
[5545]459 * @param type: the MT_Type
460 * @returns: the Type as a constant String (do not delete)
461 */
[7401]462const std::string& MultiType::MultiTypeToString(MT_Type type)
[5544]463{
[5659]464  switch ( type )
[5544]465  {
[8035]466    case MT_BOOL:
[7401]467      return MultiType::typeNames[1];
[8035]468    case MT_INT:
[7401]469      return MultiType::typeNames[2];
[8035]470    case MT_FLOAT:
[7401]471      return MultiType::typeNames[3];
[8035]472    case MT_CHAR:
[7401]473      return MultiType::typeNames[4];
[8035]474    case MT_STRING:
[7401]475      return MultiType::typeNames[5];
[8316]476    default:
477      return MultiType::typeNames[0];
[5544]478  }
479}
480
[5545]481/**
[7199]482 * @brief converts a String into a MT_Type
[5545]483 * @param type: the Type as a String
484 * @returns: the Type as MT_Type
485 */
[7221]486MT_Type MultiType::StringToMultiType(const std::string& type)
[5544]487{
[7401]488  if (type == MultiType::typeNames[1])
[5544]489    return MT_BOOL;
[7401]490  if (type == MultiType::typeNames[2])
[5544]491    return MT_INT;
[7401]492  if (type == MultiType::typeNames[3])
[5544]493    return MT_FLOAT;
[7401]494  if (type == MultiType::typeNames[4])
[5544]495    return MT_CHAR;
[7401]496  if (type == MultiType::typeNames[5])
[5544]497    return MT_STRING;
[7200]498
499  return MT_NULL;
[5544]500}
[7401]501
502
[8035]503std::string MultiType::constString = "";
[7401]504const std::string MultiType::typeNames[] =
505  {
506    "NONE",      //0
507    "bool",      //1
508    "int",       //2
509    "float",     //3
510    "char",      //4
511    "string"     //5
512  };
Note: See TracBrowser for help on using the repository browser.