Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/std/src/lib/util/multi_type.cc @ 7219

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

orxonox/std: less char*

File size: 10.3 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  {
[7211]41    default:
42      this->value.Float = 0.0f;
43      break;
[7200]44    case MT_BOOL:
45      this->value.Bool = false;
46      break;
47    case MT_INT:
48      this->value.Int = 0;
49      break;
50    case MT_FLOAT:
51      this->value.Float = 0.0f;
52      break;
53    case MT_CHAR:
54      this->value.Char = '\0';
55      break;
[7201]56    case MT_STRING:
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  {
150    case MT_NULL:
151      return true;
152    case MT_BOOL:
153      return (this->value.Bool == mt.value.Bool);
154    case MT_INT:
155      return (this->value.Int == mt.value.Int);
156    case MT_CHAR:
157      return (this->value.Char == mt.value.Char);
158    case MT_FLOAT:
159      return (this->value.Float == mt.value.Float);
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  {
177    case MT_BOOL:
178      this->setBool(this->getBool());
179      break;
180    case MT_INT:
181      this->setInt(this->getInt());
182      break;
183    case MT_FLOAT:
184      this->setFloat(this->getFloat());
185      break;
186    case MT_CHAR:
187      this->setChar(this->getChar());
188      break;
189    case MT_STRING:
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  {
[7201]298    if (this->storedString == "") return 0;
[5538]299    char* endPtr = NULL;
[7199]300    int result = strtol(this->storedString.c_str(), &endPtr, 10);
301    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + strlen(this->storedString.c_str()))
[5538]302      return 0;
303    else
304      return result;
305  }
306  return 0;
[5537]307}
308
[7199]309
[5545]310/**
311 * @returns the Value of this MultiType as a float
312 */
[5544]313float MultiType::getFloat() const
[5537]314{
[7199]315  // default case:
[5539]316  if (this->type & MT_FLOAT)
317    return this->value.Float;
318  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
[5537]319  else if (this->type & MT_INT) return (float) this->value.Int;
320  else if (this->type & MT_CHAR) return (float) this->value.Char;
[7199]321  else if (this->type & MT_STRING)
322  {
[5538]323    char* endPtr = NULL;
[7199]324    double result = strtod(this->storedString.c_str(), &endPtr);
325    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + strlen(this->storedString.c_str()))
[5538]326      return 0.0f;
327    else
328      return result;
329  }
330  return 0.0f;
[5537]331}
332
333
[5545]334/**
335 * @returns the Value of this MultiType as a char
336 */
[5544]337char MultiType::getChar() const
[5537]338{
[7199]339  // default case:
[5537]340  if (this->type & MT_INT)
341    return this->value.Int;
342  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
343  else if (this->type & MT_INT) return (int) this->value.Int;
344  else if (this->type & MT_FLOAT) return (char) this->value.Float;
[7199]345  else if (this->type & MT_STRING) return this->storedString[0];
[5538]346
347  return '\0';
[5537]348}
349
[7199]350
[5545]351/**
352 * @returns the Value of this MultiType as a String
353 */
[7199]354std::string MultiType::getString() const
[5537]355{
[7199]356  // default case:
[5537]357  if (this->type & MT_STRING)
[7199]358    return this->storedString;
[5538]359  else
360  {
361    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
[7199]362
[5641]363    else if (this->type & MT_INT)
364    {
[7199]365      char tmpString[32];
[5538]366      sprintf(tmpString, "%d", this->value.Int);
[7199]367      return tmpString;
[5538]368    }
[7199]369    else if (this->type & MT_FLOAT)
[5538]370    {
[7199]371      char tmpString[64];
[5538]372      sprintf(tmpString, "%f", this->value.Float);
[7199]373      return tmpString;
[5538]374    }
[7200]375    else if (this->type & MT_CHAR)
376    {
377      char tmpString[2];
378      tmpString[0] = this->value.Char;
379      tmpString[1] = '\0';
380      return tmpString;
381    }
[5538]382  }
383  return "";
[5537]384}
385
[5545]386/**
[7199]387 * @returns a formated c-string of the held value
[5545]388 */
[7199]389const char* MultiType::getCString()
[5544]390{
[7199]391  if (this->type & MT_STRING) return this->storedString.c_str();
392  else
393  {
394    this->storedString = this->getString();
395    return this->storedString.c_str();
396  }
397}
398
399/**
400 * @brief prints out some nice debug output
401 */
402void MultiType::debug() const
403{
[5659]404#ifdef DEBUG
405  PRINT(0)
406#else
407  printf
408#endif
[7199]409  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
410   MultiType::MultiTypeToString(this->type),
411   this->getBool(),
412   this->getInt(),
413   this->getFloat(),
414   this->getChar(),
415   this->getString().c_str()
416  );
417}
[5544]418
419
[5545]420/**
[7199]421 * @brief Resets the MultiType to default values.
[5643]422 */
423void MultiType::reset()
424{
[5659]425  switch ( this->type )
[5643]426  {
427    case MT_BOOL:
428      this->setBool(false);
[7200]429      break;
[5643]430    case MT_INT:
431      this->setInt(0);
432      break;
433    case MT_FLOAT:
434      this->setFloat(0.0f);
435      break;
436    case MT_CHAR:
437      this->setChar('\0');
438      break;
439    case MT_STRING:
440      this->setString("");
441      break;
[5659]442    default:
443#ifdef DEBUG
444      PRINTF(2)("Unknown Type not reseting\n");
445#endif
446      break;
[5643]447  }
448}
449
450/**
[7199]451 * @brief converts a MT_Type into a String
[5545]452 * @param type: the MT_Type
453 * @returns: the Type as a constant String (do not delete)
454 */
[5544]455const char* MultiType::MultiTypeToString(MT_Type type)
456{
[5659]457  switch ( type )
[5544]458  {
[7199]459    case MT_BOOL:
460      return "bool";
461    case MT_INT:
462      return "int";
463    case MT_FLOAT:
464      return "float";
465    case MT_CHAR:
466      return "char";
467    case MT_STRING:
468      return "string";
[5544]469  }
[7200]470  return "NONE";
[5544]471}
472
[5545]473/**
[7199]474 * @brief converts a String into a MT_Type
[5545]475 * @param type: the Type as a String
476 * @returns: the Type as MT_Type
477 */
[7219]478MT_Type MultiType::StringToMultiType(const std::string& type)
[5544]479{
[7219]480  if (type == "bool")
[5544]481    return MT_BOOL;
[7219]482  if (type == "int")
[5544]483    return MT_INT;
[7219]484  if (type, "float")
[5544]485    return MT_FLOAT;
[7219]486  if (type == "char")
[5544]487    return MT_CHAR;
[7219]488  if (type == "string")
[5544]489    return MT_STRING;
[7200]490
491  return MT_NULL;
[5544]492}
Note: See TracBrowser for help on using the repository browser.