Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core/src/util/Convert.h @ 854

Last change on this file since 854 was 854, checked in by landauf, 16 years ago

hopefully fixed the bug in XMLPort and Converter

File size: 16.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Benjamin Grauer
23 *   Co-authors:
24 *      Fabian 'x3n' Landau
25 */
26
27/*!
28    @file Convert.h
29    @brief Definition and Implementation of the Convert class.
30*/
31
32#ifndef _Convert_H__
33#define _Convert_H__
34
35#include <string>
36#include <sstream>
37
38#include "UtilPrereqs.h"
39#include "Math.h"
40#include "SubString.h"
41#include "MultiTypeMath.h"
42
43
44// DEFAULT CLASS
45template <typename FromType, typename ToType>
46class Converter
47{
48  public:
49    bool operator()(ToType* output, const FromType& input) const
50    {
51      return false;
52    }
53};
54
55// PARTIAL SPECIALIZATION TO CONVERT TO STRINGS
56template<typename FromType>
57class Converter<FromType, std::string>
58{
59  public:
60    bool operator()(std::string* output, const FromType& input) const
61    {
62      std::ostringstream oss;
63      if (oss << input)
64      {
65        (*output) = oss.str();
66        return true;
67      }
68      else
69        return false;
70    }
71};
72
73// PARTIAL SPECIALIZATION TO CONVERT FROM STRING
74template<typename ToType>
75class Converter<std::string, ToType>
76{
77  public:
78    bool operator()(ToType* output, const std::string& input) const
79    {
80      std::istringstream iss(input);
81      if (iss >> (*output))
82        return true;
83      else
84        return false;
85    }
86};
87
88// FUNCTION SO WE DO NOT HAVE TO TELL THE COMPILER ABOUT THE TYPE
89template<typename FromType, typename ToType>
90static bool ConvertValue(ToType* output, const FromType& input)
91{
92  Converter<FromType, ToType> converter;
93  return converter(output, input);
94}
95
96// THE SAME, BUT WITH DEFAULT VALUE
97template<typename FromType, typename ToType>
98static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)
99{
100  Converter<FromType, ToType> converter;
101  if (converter(output, input))
102    return true;
103
104  (*output) = fallback;
105  return false;
106}
107
108// THE SAME LIKE BEFORE, BUT NEEDS NO POINTER TO THE OUTPUT
109template<typename FromType, typename ToType>
110static ToType ConvertValueAndReturn(const FromType& input)
111{
112  ToType output;
113  ConvertValue(&output, input);
114  return output;
115}
116
117// THE SAME, BUT WITH DEFAULT VALUE
118template<typename FromType, typename ToType>
119static ToType ConvertValueAndReturn(const FromType& input, const FromType& fallback)
120{
121  ToType output;
122  ConvertValue(&output, input, fallback);
123  return output;
124}
125
126//////////////////////////
127// MORE SPECIALISATIONS //
128//////////////////////////
129
130// STRING TO STRING
131template<>
132class Converter<std::string, std::string>
133{
134  public:
135    bool operator()(std::string* output, const std::string& input) const
136    {
137        (*output) = std::string(input);
138        return true;
139    }
140};
141
142////////////////
143// MULTITYPES //
144////////////////
145
146// PARTIAL SPECIALIZATION TO CONVERT FROM MULTITYPEPRIMITIVE
147template<typename ToType>
148class Converter<MultiTypePrimitive, ToType>
149{
150  public:
151    bool operator()(ToType* output, const MultiTypePrimitive& input) const
152    {
153      if (input.getType() == MT_int)
154        return ConvertValue(output, input.getInt());
155      else if (input.getType() == MT_uint)
156        return ConvertValue(output, input.getUnsignedInt());
157      else if (input.getType() == MT_char)
158        return ConvertValue(output, input.getChar());
159      else if (input.getType() == MT_uchar)
160        return ConvertValue(output, input.getUnsignedChar());
161      else if (input.getType() == MT_short)
162        return ConvertValue(output, input.getShort());
163      else if (input.getType() == MT_ushort)
164        return ConvertValue(output, input.getUnsignedShort());
165      else if (input.getType() == MT_long)
166        return ConvertValue(output, input.getLong());
167      else if (input.getType() == MT_ulong)
168        return ConvertValue(output, input.getUnsignedLong());
169      else if (input.getType() == MT_float)
170        return ConvertValue(output, input.getFloat());
171      else if (input.getType() == MT_double)
172        return ConvertValue(output, input.getDouble());
173      else if (input.getType() == MT_longdouble)
174        return ConvertValue(output, input.getLongDouble());
175      else if (input.getType() == MT_bool)
176        return ConvertValue(output, input.getBool());
177      else
178        return false;
179    }
180};
181template<>
182class Converter<MultiTypePrimitive, std::string>
183{
184  public:
185    bool operator()(std::string* output, const MultiTypePrimitive& input) const
186    {
187      if (input.getType() == MT_int)
188        return ConvertValue(output, input.getInt());
189      else if (input.getType() == MT_uint)
190        return ConvertValue(output, input.getUnsignedInt());
191      else if (input.getType() == MT_char)
192        return ConvertValue(output, input.getChar());
193      else if (input.getType() == MT_uchar)
194        return ConvertValue(output, input.getUnsignedChar());
195      else if (input.getType() == MT_short)
196        return ConvertValue(output, input.getShort());
197      else if (input.getType() == MT_ushort)
198        return ConvertValue(output, input.getUnsignedShort());
199      else if (input.getType() == MT_long)
200        return ConvertValue(output, input.getLong());
201      else if (input.getType() == MT_ulong)
202        return ConvertValue(output, input.getUnsignedLong());
203      else if (input.getType() == MT_float)
204        return ConvertValue(output, input.getFloat());
205      else if (input.getType() == MT_double)
206        return ConvertValue(output, input.getDouble());
207      else if (input.getType() == MT_longdouble)
208        return ConvertValue(output, input.getLongDouble());
209      else if (input.getType() == MT_bool)
210        return ConvertValue(output, input.getBool());
211      else
212        return false;
213    }
214};
215
216// PARTIAL SPECIALIZATION TO CONVERT FROM MULTITYPESTRING
217template<typename ToType>
218class Converter<MultiTypeString, ToType>
219{
220  public:
221    bool operator()(ToType* output, const MultiTypeString& input) const
222    {
223      if (input.getType() == MT_constchar)
224        return ConvertValue(output, input.getConstChar());
225      else if (input.getType() == MT_string)
226        return ConvertValue(output, input.getString());
227      else
228        return ConvertValue(output, (MultiTypePrimitive)input);
229    }
230};
231template<>
232class Converter<MultiTypeString, std::string>
233{
234  public:
235    bool operator()(std::string* output, const MultiTypeString& input) const
236    {
237      if (input.getType() == MT_constchar)
238        return ConvertValue(output, input.getConstChar());
239      else if (input.getType() == MT_string)
240        return ConvertValue(output, input.getString());
241      else
242        return ConvertValue(output, (MultiTypePrimitive)input);
243    }
244};
245
246// PARTIAL SPECIALIZATION TO CONVERT FROM MULTITYPEMATH
247template<typename ToType>
248class Converter<MultiTypeMath, ToType>
249{
250  public:
251    bool operator()(ToType* output, const MultiTypeMath& input) const
252    {
253      if (input.getType() == MT_vector2)
254        return ConvertValue(output, input.getVector2());
255      else if (input.getType() == MT_vector3)
256        return ConvertValue(output, input.getVector3());
257      else if (input.getType() == MT_quaternion)
258        return ConvertValue(output, input.getQuaternion());
259      else if (input.getType() == MT_colourvalue)
260        return ConvertValue(output, input.getColourValue());
261      else if (input.getType() == MT_radian)
262        return ConvertValue(output, input.getRadian());
263      else if (input.getType() == MT_degree)
264        return ConvertValue(output, input.getDegree());
265      else
266        return ConvertValue(output, (MultiTypeString)input);
267    }
268};
269template<>
270class Converter<MultiTypeMath, std::string>
271{
272  public:
273    bool operator()(std::string* output, const MultiTypeMath& input) const
274    {
275      if (input.getType() == MT_vector2)
276        return ConvertValue(output, input.getVector2());
277      else if (input.getType() == MT_vector3)
278        return ConvertValue(output, input.getVector3());
279      else if (input.getType() == MT_quaternion)
280        return ConvertValue(output, input.getQuaternion());
281      else if (input.getType() == MT_colourvalue)
282        return ConvertValue(output, input.getColourValue());
283      else if (input.getType() == MT_radian)
284        return ConvertValue(output, input.getRadian());
285      else if (input.getType() == MT_degree)
286        return ConvertValue(output, input.getDegree());
287      else
288        return ConvertValue(output, (MultiTypeString)input);
289    }
290};
291
292
293////////////////////
294// MATH TO STRING //
295////////////////////
296
297// Vector2 to std::string
298template <>
299class Converter<orxonox::Vector2, std::string>
300{
301  public:
302    bool operator()(std::string* output, const orxonox::Vector2& input) const
303    {
304      std::ostringstream ostream;
305      if (ostream << input.x << "," << input.y)
306      {
307        (*output) = ostream.str();
308        return true;
309      }
310
311      return false;
312    }
313};
314
315// Vector3 to std::string
316template <>
317class Converter<orxonox::Vector3, std::string>
318{
319  public:
320    bool operator()(std::string* output, const orxonox::Vector3& input) const
321    {
322      std::ostringstream ostream;
323      if (ostream << input.x << "," << input.y << "," << input.z)
324      {
325        (*output) = ostream.str();
326        return true;
327      }
328
329      return false;
330    }
331};
332
333// Vector4 to std::string
334template <>
335class Converter<orxonox::Vector4, std::string>
336{
337  public:
338    bool operator()(std::string* output, const orxonox::Vector4& input) const
339    {
340      std::ostringstream ostream;
341      if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w)
342      {
343        (*output) = ostream.str();
344        return true;
345      }
346
347      return false;
348    }
349};
350
351// Quaternion to std::string
352template <>
353class Converter<orxonox::Quaternion, std::string>
354{
355  public:
356    bool operator()(std::string* output, const orxonox::Quaternion& input) const
357    {
358      std::ostringstream ostream;
359      if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z)
360      {
361        (*output) = ostream.str();
362        return true;
363      }
364
365      return false;
366    }
367};
368
369// ColourValue to std::string
370template <>
371class Converter<orxonox::ColourValue, std::string>
372{
373  public:
374    bool operator()(std::string* output, const orxonox::ColourValue& input) const
375    {
376      std::ostringstream ostream;
377      if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a)
378      {
379        (*output) = ostream.str();
380        return true;
381      }
382
383      return false;
384    }
385};
386
387
388////////////////////
389// STRING TO MATH //
390////////////////////
391
392// std::string to Vector2
393template <>
394class Converter<std::string, orxonox::Vector2>
395{
396  public:
397    bool operator()(orxonox::Vector2* output, const std::string& input) const
398    {
399      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
400      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
401
402      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', '"', '\0', '\0', '\0');
403
404      if (tokens.size() >= 2)
405      {
406        if (!ConvertValue(&(output->x), tokens[0]))
407          return false;
408        if (!ConvertValue(&(output->y), tokens[1]))
409          return false;
410
411        return true;
412      }
413
414      return false;
415    }
416};
417
418// std::string to Vector3
419template <>
420class Converter<std::string, orxonox::Vector3>
421{
422  public:
423    bool operator()(orxonox::Vector3* output, const std::string& input) const
424    {
425      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
426      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
427
428      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', '"', '\0', '\0', '\0');
429
430      if (tokens.size() >= 3)
431      {
432        if (!ConvertValue(&(output->x), tokens[0]))
433          return false;
434        if (!ConvertValue(&(output->y), tokens[1]))
435          return false;
436        if (!ConvertValue(&(output->z), tokens[2]))
437          return false;
438
439        return true;
440      }
441
442      return false;
443    }
444};
445
446// std::string to Vector4
447template <>
448class Converter<std::string, orxonox::Vector4>
449{
450  public:
451    bool operator()(orxonox::Vector4* output, const std::string& input) const
452    {
453      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
454      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
455
456      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', '"', '\0', '\0', '\0');
457
458      if (tokens.size() >= 4)
459      {
460        if (!ConvertValue(&(output->x), tokens[0]))
461          return false;
462        if (!ConvertValue(&(output->y), tokens[1]))
463          return false;
464        if (!ConvertValue(&(output->z), tokens[2]))
465          return false;
466        if (!ConvertValue(&(output->w), tokens[3]))
467          return false;
468
469        return true;
470      }
471
472      return false;
473    }
474};
475
476// std::string to Quaternion
477template <>
478class Converter<std::string, orxonox::Quaternion>
479{
480  public:
481    bool operator()(orxonox::Quaternion* output, const std::string& input) const
482    {
483      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
484      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
485
486      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', '"', '\0', '\0', '\0');
487
488      if (tokens.size() >= 4)
489      {
490        if (!ConvertValue(&(output->w), tokens[0]))
491          return false;
492        if (!ConvertValue(&(output->x), tokens[1]))
493          return false;
494        if (!ConvertValue(&(output->y), tokens[2]))
495          return false;
496        if (!ConvertValue(&(output->z), tokens[3]))
497          return false;
498
499        return true;
500      }
501
502      return false;
503    }
504};
505
506// std::string to ColourValue
507template <>
508class Converter<std::string, orxonox::ColourValue>
509{
510  public:
511    bool operator()(orxonox::ColourValue* output, const std::string& input) const
512    {
513      unsigned int opening_parenthesis, closing_parenthesis = input.find(')');
514      if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
515
516      SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', '"', '\0', '\0', '\0');
517
518      if (tokens.size() >= 4)
519      {
520        if (!ConvertValue(&(output->r), tokens[0]))
521          return false;
522        if (!ConvertValue(&(output->g), tokens[1]))
523          return false;
524        if (!ConvertValue(&(output->b), tokens[2]))
525          return false;
526        if (!ConvertValue(&(output->a), tokens[3]))
527          return false;
528
529        return true;
530      }
531
532      return false;
533    }
534};
535
536#endif /* _Convert_H__ */
Note: See TracBrowser for help on using the repository browser.