Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
xml_support.cpp
Go to the documentation of this file.
1 #include <string>
2 #include <sstream>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <assert.h>
6 #include <stdarg.h>
7 #include "xml_support.h"
8 
9 #include <boost/tokenizer.hpp>
10 #include <boost/lexical_cast.hpp>
11 
12 using std::string;
13 
14 string strtoupper( const string &foo )
15 {
16  string rval( foo );
17  for (string::iterator it = rval.begin(); it != rval.end(); ++it)
18  *it = toupper( *it );
19  return rval;
20 }
21 string strtolower( const string &foo )
22 {
23  string rval( foo );
24  for (string::iterator it = rval.begin(); it != rval.end(); ++it)
25  *it = tolower( *it );
26  return rval;
27 }
28 namespace XMLSupport
29 {
30 typedef boost::char_separator<std::string::value_type> Separator;
31 typedef boost::tokenizer<Separator> Tokenizer;
32 
33 static const char *SEPARATORS = " \t,";
34 
35 EnumMap::EnumMap( const Pair *data, unsigned int num )
36 {
37  for (unsigned int a = 0; a < num; a++) {
38  forward.Put( strtoupper( data[a].name ), &data[a].val );
39  reverse.Put( tostring( data[a].val ), &data[a].name );
40  }
41 }
42 
43 int EnumMap::lookup( const string &str ) const
44 {
45  const int *result = forward.Get( strtoupper( str ) );
46  if (!result) result = forward.Get( "UNKNOWN" );
47  return result ? *result : 0;
48 }
49 const string& EnumMap::lookup( int val ) const
50 {
51  const string *result = reverse.Get( tostring( val ) );
52  assert( 0 != result );
53  return *result;
54 }
55 
56 AttributeList::AttributeList( const XML_Char **atts )
57 {
58  for (; *atts != NULL; atts += 2)
59  push_back( Attribute( atts[0], atts[1] ) );
60 }
61 
62 string replace_space( const string &str )
63 {
64  string retval( str );
65  for (string::iterator i = retval.begin(); i != retval.end(); i++)
66  if (*i == ' ')
67  *i = '_';
68  return retval;
69 }
70 bool parse_bool( const string &str )
71 {
72  if ( ( !str.empty() )
73  && ( ( *str.begin() ) == 't' || ( *str.begin() ) == 'T' || ( *str.begin() ) == 'y' || ( *str.begin() ) == 'Y'
74  || ( *str.begin() ) == '1' ) )
75  return true;
76  else
77  return false;
78 }
79 double parse_float( const string &str )
80 {
81  double ret = 0.0f;
82  std::stringstream ss( str );
83  ss>>ret;
84  return ret;
85 }
86 
87 float parse_floatf( const string &str )
88 {
89  float ret = 0.0f;
90  std::stringstream ss( str );
91  ss>>ret;
92  return ret;
93 }
94 
95 void parse_floatv(const std::string& input, size_t maxTokens, ...)
96 {
97  va_list arguments;
98  va_start(arguments, maxTokens);
99  Separator separator(SEPARATORS);
100  Tokenizer tokens(input, separator);
101 
102  for (Tokenizer::iterator it = tokens.begin(); maxTokens > 0 && it != tokens.end(); ++it, --maxTokens) {
103  double *output = va_arg(arguments, double *);
104  *output = boost::lexical_cast<double>(*it);
105  }
106  va_end(arguments);
107 }
108 
109 void parse_floatfv( const string &input, int maxTokens, ... )
110 {
111  va_list arguments;
112  va_start(arguments, maxTokens);
113  Separator separator(SEPARATORS);
114  Tokenizer tokens(input, separator);
115 
116  for (Tokenizer::iterator it = tokens.begin(); maxTokens > 0 && it != tokens.end(); ++it, --maxTokens) {
117  float *output = va_arg(arguments, float *);
118  *output = boost::lexical_cast<float>(*it);
119  }
120  va_end(arguments);
121 }
122 
123 
124 int parse_int( const string &str )
125 {
126  int ret = 0;
127  std::stringstream ss( str );
128  ss>>ret;
129  return ret;
130 }
131 string::size_type parse_option_find( const string &str, const string &opt, const string &sep, const string &vsep )
132 {
133  bool ini = true;
134  string::size_type pos = 0;
135  string::size_type optlen = opt.length();
136  string::size_type strlen = str.length();
137  string allsep = sep+vsep;
138  if ( (optlen == 0) || (strlen == 0) )
139  return string::npos;
140  bool found = false;
141  while ( !found && (pos != string::npos) && ( ( pos = str.find( opt, pos+(ini ? 0 : 1) ) ) != string::npos ) ) {
142  ini = false;
143  found = ( ( (pos == 0) || (sep.find( str[pos-1] ) != string::npos) )
144  && ( (pos+optlen >= strlen) || (allsep.find( str[pos+optlen] ) != string::npos) ) );
145  if (!found) pos = str.find_first_of( sep, pos+optlen ); //quick advancement
146  }
147  return found ? pos : string::npos;
148 }
149 bool parse_option_ispresent( const string &str, const string &opt, const string &sep, const string &vsep )
150 {
151  return parse_option_find( str, opt, sep, vsep ) != string::npos;
152 }
153 string parse_option_value( const string &str, const string &opt, const string &defvalue, const string &sep, const string &vsep )
154 {
155  string::size_type pos = parse_option_find( str, opt, sep, vsep );
156  string::size_type vpos = str.find_first_of( vsep, pos+opt.length() );
157  string value;
158  if (pos != string::npos && vpos != string::npos) {
159  string::size_type vend = str.find_first_of( sep, vpos+1 );
160  value = str.substr( vpos+1, ( (vend != string::npos) ? vend-vpos-1 : string::npos ) );
161  } else if (pos != string::npos) {
162  value = "true";
163  } else {
164  value = defvalue;
165  }
166  return value;
167 }
168 
169 string escaped_string( const string &str )
170 {
171 #define ESCAPE_CASE( e, c, skip ) \
172 case e: \
173  if (rp && str[rp-1] == '\\') rv[ip++] = c; \
174  else if (!skip) \
175  rv[ip++] = e; \
176  break
177  string::size_type rp, ip, n = str.length();
178  string rv;
179  rv.resize( n );
180  for (rp = ip = 0; rp < n; ++rp) {
181  switch (str[rp])
182  {
183  ESCAPE_CASE( '\\', '\\', true );
184  ESCAPE_CASE( 'n', '\n', false );
185  ESCAPE_CASE( 'r', '\r', false );
186  ESCAPE_CASE( 't', '\t', false );
187  default:
188  rv[ip++] = str[rp];
189  }
190  }
191 #undef ESCAPE_CASE
192  rv.resize( ip );
193  return rv;
194 }
195 } //namespace XMLSupport
196