Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: now the branche works again, as it did before

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