Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: MultiType rework (now uses std::string) this is more compliant, and better to handle

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