Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: small fixes

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