Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Executor now uses MultiType instead of va_arg

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