Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: no more segfaults

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