Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

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