Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/truink: minor cleanup

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