Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/gui/src/lib/util/multi_type.cc @ 7994

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

gui: doxytags, and returning reference to temporary resolved

File size: 10.7 KB
Line 
1/*
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.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "multi_type.h"
19
20//#include "stdincl.h"
21#include <stddef.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
25#include <sstream>
26
27#ifdef DEBUG
28#include "debug.h"
29#endif
30
31using namespace std;
32
33/**
34 * @brief creates a multiType without any stored value at all.
35 */
36MultiType::MultiType(MT_Type type)
37{
38  this->type = type;
39  switch (this->type)
40  {
41      default:
42      this->value.Float = 0.0f;
43      break;
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;
56      case MT_STRING:
57      this->storedString = "";
58      break;
59  }
60}
61/**
62 * @brief creates a multiType out of a boolean
63 * @param value the Value of this MulitType
64 */
65MultiType::MultiType(bool value)
66{
67  this->setBool(value);
68}
69
70/**
71 * @brief creates a multiType out of an integer
72 * @param value the Value of this MulitType
73 */
74MultiType::MultiType(int value)
75{
76  this->setInt(value);
77}
78
79/**
80 * @brief creates a multiType out of a float (double)
81 * @param value the Value of this MulitType
82 */
83MultiType::MultiType(double value)
84{
85  this->setFloat(value);
86}
87
88/**
89 * @brief creates a multiType out of a char
90 * @param value the Value of this MulitType
91 */
92MultiType::MultiType(char value)
93{
94  this->setChar(value);
95}
96
97/**
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 */
109MultiType::MultiType(const MultiType& multiType)
110{
111  *this = multiType;
112}
113
114/**
115 * @brief standard deconstructor
116*/
117MultiType::~MultiType ()
118{ }
119
120/**
121 * @brief copy operator
122 * @param mt: the entity to copy
123 * @returns A Copy of itself. (strings inside are copied as well)
124 */
125MultiType& MultiType::operator= (const MultiType& mt)
126{
127  this->type = mt.type;
128  this->value = mt.value;
129  this->storedString = mt.storedString;
130
131  return *this;
132}
133
134/**
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:
161      return (this->storedString == mt.storedString);
162  }
163}
164
165
166/**
167 * @brief sets the type of this MultiType and resets to the default value
168 * @param type the new Type
169 */
170void MultiType::setType(MT_Type type)
171{
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  }
193}
194
195/**
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
214 * @param value the new Value as a bool
215 */
216void MultiType::setBool(bool value)
217{
218  this->type = MT_BOOL;
219  this->value.Bool = value;
220}
221
222/**
223 * @brief sets a new Value to the MultiType
224 * @param value the new Value as an int
225 */
226void MultiType::setInt(int value)
227{
228  this->type = MT_INT;
229  this->value.Int = value;
230}
231
232/**
233 * @brief sets a new Value to the MultiType
234 * @param value the new Value as a float
235 */
236void MultiType::setFloat(float value)
237{
238  this->type = MT_FLOAT;
239  this->value.Float = value;
240}
241
242/**
243 * @brief sets a new Value to the MultiType
244 * @param value the new Value as a char
245 */
246void MultiType::setChar(char value)
247{
248  this->type = MT_CHAR;
249  this->value.Char = value;
250}
251
252/**
253 * @brief sets a new Value to the MultiType
254 * @param value the new Value as a String
255 */
256void MultiType::setString(const std::string& value)
257{
258  this->type = MT_STRING;
259  this->storedString = value;
260}
261
262
263/**************************
264*** RETRIEVAL FUNCTIONS ***
265**************************/
266/**
267 * @returns the Value of this MultiType as a int
268 */
269bool MultiType::getBool() const
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;
278  else if (this->type & MT_STRING) return (this->storedString == "true" ||
279                                            this->storedString == "TRUE" ||
280                                            this->storedString != "0"); //! @TODO make this better...
281
282  return false;
283}
284
285/**
286 * @returns the Value of this MultiType as a int
287 */
288int MultiType::getInt() const
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;
296  else if (this->type & MT_STRING)
297  {
298    std::stringstream ssStream(this->storedString);
299    int iReturn;
300    ssStream >> iReturn;
301    return iReturn;
302  }
303  return 0;
304}
305
306
307/**
308 * @returns the Value of this MultiType as a float
309 */
310float MultiType::getFloat() const
311{
312  // default case:
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;
316  else if (this->type & MT_INT) return (float) this->value.Int;
317  else if (this->type & MT_CHAR) return (float) this->value.Char;
318  else if (this->type & MT_STRING)
319  {
320    char* endPtr = NULL;
321    double result = strtod(this->storedString.c_str(), &endPtr);
322    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + this->storedString.size())
323      return 0.0f;
324    else
325      return result;
326  }
327  return 0.0f;
328}
329
330
331/**
332 * @returns the Value of this MultiType as a char
333 */
334char MultiType::getChar() const
335{
336  // default case:
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;
342  else if (this->type & MT_STRING) return this->storedString[0];
343
344  return '\0';
345}
346
347
348/**
349 * @returns the Value of this MultiType as a String
350 */
351std::string MultiType::getString() const
352{
353  // default case:
354  if (this->type & MT_STRING)
355    return this->storedString;
356  else
357  {
358    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
359
360    else if (this->type & MT_INT)
361    {
362      char tmpString[32];
363      sprintf(tmpString, "%d", this->value.Int);
364      return tmpString;
365    }
366    else if (this->type & MT_FLOAT)
367    {
368      char tmpString[64];
369      sprintf(tmpString, "%f", this->value.Float);
370      return tmpString;
371    }
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    }
379  }
380  return "";
381}
382
383const std::string& MultiType::getConstString() const
384{
385  MultiType::constString = this->getString();
386  return MultiType::constString;
387}
388
389
390/**
391 * @returns a formated c-string of the held value
392 */
393const char* MultiType::getCString()
394{
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{
408#ifdef DEBUG
409  PRINT(0)
410#else
411  printf
412#endif
413  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
414   MultiType::MultiTypeToString(this->type).c_str(),
415   this->getBool(),
416   this->getInt(),
417   this->getFloat(),
418   this->getChar(),
419   this->getString().c_str()
420  );
421}
422
423
424/**
425 * @brief Resets the MultiType to default values.
426 */
427void MultiType::reset()
428{
429  switch ( this->type )
430  {
431      case MT_BOOL:
432      this->setBool(false);
433      break;
434      case MT_INT:
435      this->setInt(0);
436      break;
437      case MT_FLOAT:
438      this->setFloat(0.0f);
439      break;
440      case MT_CHAR:
441      this->setChar('\0');
442      break;
443      case MT_STRING:
444      this->setString("");
445      break;
446      default:
447#ifdef DEBUG
448      PRINTF(2)("Unknown Type not reseting\n");
449#endif
450      break;
451  }
452}
453
454/**
455 * @brief converts a MT_Type into a String
456 * @param type: the MT_Type
457 * @returns: the Type as a constant String (do not delete)
458 */
459const std::string& MultiType::MultiTypeToString(MT_Type type)
460{
461  switch ( type )
462  {
463      case MT_BOOL:
464      return MultiType::typeNames[1];
465      case MT_INT:
466      return MultiType::typeNames[2];
467      case MT_FLOAT:
468      return MultiType::typeNames[3];
469      case MT_CHAR:
470      return MultiType::typeNames[4];
471      case MT_STRING:
472      return MultiType::typeNames[5];
473  }
474  return MultiType::typeNames[0];
475}
476
477/**
478 * @brief converts a String into a MT_Type
479 * @param type: the Type as a String
480 * @returns: the Type as MT_Type
481 */
482MT_Type MultiType::StringToMultiType(const std::string& type)
483{
484  if (type == MultiType::typeNames[1])
485    return MT_BOOL;
486  if (type == MultiType::typeNames[2])
487    return MT_INT;
488  if (type == MultiType::typeNames[3])
489    return MT_FLOAT;
490  if (type == MultiType::typeNames[4])
491    return MT_CHAR;
492  if (type == MultiType::typeNames[5])
493    return MT_STRING;
494
495  return MT_NULL;
496}
497
498
499std::string MultiType::constString = "";
500const std::string MultiType::typeNames[] =
501  {
502    "NONE",      //0
503    "bool",      //1
504    "int",       //2
505    "float",     //3
506    "char",      //4
507    "string"     //5
508  };
Note: See TracBrowser for help on using the repository browser.