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
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->init();
39  this->type = type;
40}
41/**
42 * @brief creates a multiType out of a boolean
43 * @param value the Value of this MulitType
44 */
45MultiType::MultiType(bool value)
46{
47  this->init();
48  this->setBool(value);
49}
50
51/**
52 * @brief creates a multiType out of an integer
53 * @param value the Value of this MulitType
54 */
55MultiType::MultiType(int value)
56{
57  this->init();
58  this->setInt(value);
59}
60
61/**
62 * @brief creates a multiType out of a float (double)
63 * @param value the Value of this MulitType
64 */
65MultiType::MultiType(double value)
66{
67  this->init();
68  this->setFloat(value);
69}
70
71/**
72 * @brief creates a multiType out of a char
73 * @param value the Value of this MulitType
74 */
75MultiType::MultiType(char value)
76{
77  this->init();
78  this->setChar(value);
79}
80
81/**
82 * @brief creates a multiType out of a C-String
83 * @param value the Value of this MulitType
84 */
85MultiType::MultiType(const char* value)
86{
87  this->init();
88  this->setString(value);
89}
90
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 */
104MultiType::MultiType(const MultiType& multiType)
105{
106  *this = multiType;
107}
108
109/**
110 * @brief standard deconstructor
111*/
112MultiType::~MultiType ()
113{ }
114
115/**
116 * @brief copy operator
117 * @param mt: the entity to copy
118 * @returns A Copy of itself. (strings inside are copied as well)
119 */
120MultiType& MultiType::operator= (const MultiType& mt)
121{
122  this->type = mt.type;
123  this->value = mt.value;
124  this->storedString = mt.storedString;
125
126  return *this;
127}
128
129/**
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:
156      return (this->storedString == mt.storedString);
157  }
158}
159
160
161/**
162 * @brief initializes the MultiType
163 */
164void MultiType::init()
165{
166  this->type = MT_NULL;
167  this->value.Float = 0.0f;
168}
169
170
171/**
172 * @brief sets the type of this MultiType and resets to the default value
173 * @param type the new Type
174 */
175void MultiType::setType(MT_Type type)
176{
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  }
198}
199
200/**
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
219 * @param value the new Value as a bool
220 */
221void MultiType::setBool(bool value)
222{
223  this->type = MT_BOOL;
224  this->value.Bool = value;
225}
226
227/**
228 * @brief sets a new Value to the MultiType
229 * @param value the new Value as an int
230 */
231void MultiType::setInt(int value)
232{
233  this->type = MT_INT;
234  this->value.Int = value;
235}
236
237/**
238 * @brief sets a new Value to the MultiType
239 * @param value the new Value as a float
240 */
241void MultiType::setFloat(float value)
242{
243  this->type = MT_FLOAT;
244  this->value.Float = value;
245}
246
247/**
248 * @brief sets a new Value to the MultiType
249 * @param value the new Value as a char
250 */
251void MultiType::setChar(char value)
252{
253  this->type = MT_CHAR;
254  this->value.Char = value;
255}
256
257/**
258 * @brief sets a new Value to the MultiType
259 * @param value the new Value as a String
260 */
261void MultiType::setString(const std::string& value)
262{
263  this->type = MT_STRING;
264  this->storedString = value;
265}
266
267
268/**************************
269*** RETRIEVAL FUNCTIONS ***
270**************************/
271/**
272 * @returns the Value of this MultiType as a int
273 */
274bool MultiType::getBool() const
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;
283  else if (this->type & MT_STRING) return (this->storedString == "true" ||
284                                            this->storedString == "TRUE" ||
285                                            this->storedString != "0"); //! @TODO make this better...
286
287  return false;
288}
289
290/**
291 * @returns the Value of this MultiType as a int
292 */
293int MultiType::getInt() const
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;
301  else if (this->type & MT_STRING)
302  {
303    char* endPtr = NULL;
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()))
306      return 0;
307    else
308      return result;
309  }
310  return 0;
311}
312
313
314/**
315 * @returns the Value of this MultiType as a float
316 */
317float MultiType::getFloat() const
318{
319  // default case:
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;
323  else if (this->type & MT_INT) return (float) this->value.Int;
324  else if (this->type & MT_CHAR) return (float) this->value.Char;
325  else if (this->type & MT_STRING)
326  {
327    char* endPtr = NULL;
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()))
330      return 0.0f;
331    else
332      return result;
333  }
334  return 0.0f;
335}
336
337
338/**
339 * @returns the Value of this MultiType as a char
340 */
341char MultiType::getChar() const
342{
343  // default case:
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;
349  else if (this->type & MT_STRING) return this->storedString[0];
350
351  return '\0';
352}
353
354
355/**
356 * @returns the Value of this MultiType as a String
357 */
358std::string MultiType::getString() const
359{
360  // default case:
361  if (this->type & MT_STRING)
362    return this->storedString;
363  else
364  {
365    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
366
367    if (this->type & MT_CHAR)
368    {
369      char tmpString[2];
370      tmpString[0] = this->value.Char;
371      tmpString[1] = '\0';
372      return tmpString;
373    }
374    else if (this->type & MT_INT)
375    {
376      char tmpString[32];
377      sprintf(tmpString, "%d", this->value.Int);
378      return tmpString;
379    }
380    else if (this->type & MT_FLOAT)
381    {
382      char tmpString[64];
383      sprintf(tmpString, "%f", this->value.Float);
384      return tmpString;
385    }
386  }
387  return "";
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),
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    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;
445    default:
446#ifdef DEBUG
447      PRINTF(2)("Unknown Type not reseting\n");
448#endif
449      break;
450  }
451}
452
453/**
454 * @brief converts a MT_Type into a String
455 * @param type: the MT_Type
456 * @returns: the Type as a constant String (do not delete)
457 */
458const char* MultiType::MultiTypeToString(MT_Type type)
459{
460  switch ( type )
461  {
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";
474  }
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 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.