Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: error-correction

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