Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
field.cpp
1 
2 /***************************************************************************
3  * field.cpp - Interface generator field representation
4  *
5  * Generated: Wed Oct 11 18:16:15 2006
6  * Copyright 2006 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include <interfaces/generator/field.h>
24 #include <interfaces/generator/type_checker.h>
25 #include <interfaces/generator/exceptions.h>
26 
27 #include <stdlib.h>
28 
29 
30 /** @class InterfaceField interfaces/generator/field.h
31  * Interface generator internal representation of a field as parsed from
32  * the XML template file.
33  */
34 
35 
36 /** Constructor.
37  * @param enum_constants enumeration constants that are available and which can be
38  * used as value type.
39  */
40 InterfaceField::InterfaceField(std::vector<InterfaceEnumConstant> *enum_constants)
41 {
42  this->enum_constants = enum_constants;
43  length = "";
44  length_value = 0;
45  is_enum_type = false;
46 }
47 
48 
49 /** Get name of field.
50  * @return name of field.
51  */
52 std::string
54 {
55  return name;
56 }
57 
58 
59 /** Get type of field.
60  * @return type of field.
61  */
62 std::string
64 {
65  return type;
66 }
67 
68 
69 /** Get comment of field.
70  * @return comment of field.
71  */
72 std::string
74 {
75  return comment;
76 }
77 
78 
79 /** Get type as used for accessor methods of class.
80  * @return accessor type
81  */
82 std::string
84 {
85  if (type == "string") {
86  return "char *";
87  } else {
88  if ( length != "" ) {
89  if (type == "byte") {
90  return "uint8_t *";
91  } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) {
92  return type + " *";
93  } else {
94  return type + "_t *";
95  }
96  } else {
97  if (type == "byte") {
98  return "uint8_t";
99  } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) {
100  return type;
101  } else {
102  return type + "_t";
103  }
104  }
105  }
106 }
107 
108 
109 /** Get non-array accessor type.
110  * @return accessor type
111  */
112 std::string
114 {
115  if (type == "string") {
116  return "char *";
117  } else if (type == "byte") {
118  return "uint8_t";
119  } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) {
120  return type;
121  } else {
122  return type + "_t";
123  }
124 }
125 
126 
127 /** Get type used to formulate struct.
128  * @return struct type
129  */
130 std::string
132 {
133  if (type == "string") {
134  return "char";
135  } else if (type == "byte") {
136  return "uint8_t";
137  } else if (type == "float" || type == "double" || type == "bool") {
138  return type;
139  } else if (is_enum_type) {
140  return "int32_t";
141  } else {
142  return type + "_t";
143  }
144 }
145 
146 
147 /** Check if type is an enum type.
148  * @return true if the type of this field is an enum type, false otherwise
149  */
150 bool
152 {
153  return is_enum_type;
154 }
155 
156 /** Get field length.
157  * @return field length
158  */
159 std::string
161 {
162  return length;
163 }
164 
165 
166 /** Get length value.
167  * This gives the length of the value as a uint instead of a string
168  * which is sufficient for the generation of the interface but may not
169  * be sufficient for more elaborated usage.
170  * @return length of the value
171  */
172 unsigned int
174 {
175  return length_value;
176 }
177 
178 
179 /** Get valid for time.
180  * @return valid for time
181  */
182 std::string
184 {
185  return validfor;
186 }
187 
188 
189 /** Get default value.
190  * @return default value
191  */
192 std::string
194 {
195  return default_value;
196 }
197 
198 
199 /** Get flags.
200  * @return flags.
201  */
202 std::vector<std::string>
204 {
205  return flags;
206 }
207 
208 
209 /** Set type of field.
210  * @param type new type of field.
211  */
212 void
213 InterfaceField::setType(const std::string &type)
214 {
215  is_enum_type = false;
216  if ( enum_constants != NULL ) {
217  std::vector<InterfaceEnumConstant>::iterator i;
218  for (i = enum_constants->begin(); i != enum_constants->end(); ++i) {
219  if ( type == (*i).get_name() ) {
220  is_enum_type = true;
221  }
222  }
223  }
224  this->type = type;
225 }
226 
227 
228 /** Set name of field.
229  * @param name new name of field.
230  */
231 void
232 InterfaceField::setName(const std::string &name)
233 {
234  this->name = name;
235 }
236 
237 
238 /** Set comment of field.
239  * @param comment new comment of field.
240  */
241 void
242 InterfaceField::setComment(const std::string &comment)
243 {
244  this->comment = comment;
245 }
246 
247 
248 /** Set length of field.
249  * @param length set length of field.
250  */
251 void
252 InterfaceField::setLength(const std::string &length)
253 {
254  this->length_value = (unsigned int)atoi(length.c_str());
255  this->length = length;
256 }
257 
258 
259 /** Set valid for time.
260  * @param validfor new valid for time
261  */
262 void
263 InterfaceField::setValidFor(const std::string &validfor)
264 {
265  this->validfor = validfor;
266 }
267 
268 
269 /** Set default value.
270  * @param default_value new default value
271  */
272 void
273 InterfaceField::setDefaultValue(const std::string &default_value)
274 {
275  this->default_value = default_value;
276 }
277 
278 
279 /** Set flags.
280  * @param flags new flags of field
281  */
282 void
283 InterfaceField::setFlags(const std::vector<std::string> &flags)
284 {
285  this->flags = flags;
286 }
287 
288 
289 /** Tokenize given string.
290  * @param str tsring to tokenize
291  * @param tokens vector where result will be stored
292  * @param delimiters string with delimiters.
293  */
294 void
295 InterfaceField::tokenize(const std::string& str,
296  std::vector<std::string>& tokens,
297  const std::string& delimiters)
298 {
299  // Skip delimiters at beginning.
300  std::string::size_type last_pos = str.find_first_not_of(delimiters, 0);
301  // Find first "non-delimiter".
302  std::string::size_type pos = str.find_first_of(delimiters, last_pos);
303 
304  while (std::string::npos != pos || std::string::npos != last_pos) {
305  // Found a token, add it to the vector.
306  tokens.push_back(str.substr(last_pos, pos - last_pos));
307  // Skip delimiters. Note the "not_of"
308  last_pos = str.find_first_not_of(delimiters, pos);
309  // Find next "non-delimiter"
310  pos = str.find_first_of(delimiters, last_pos);
311  }
312 }
313 
314 
315 /** Set attribute.
316  * @param attr_name attribute name
317  * @param attr_value attribute value.
318  */
319 void
320 InterfaceField::setAttribute(const std::string &attr_name, const std::string &attr_value)
321 {
322  if ( attr_name == "name" ) {
323  setName(attr_value);
324  } else if ( attr_name == "type" ) {
325  setType(attr_value);
326  } else if ( attr_name == "length" ) {
327  setLength(attr_value);
328  } else if ( attr_name == "validfor" ) {
329  setValidFor(attr_value);
330  } else if ( attr_name == "default" ) {
331  setDefaultValue(attr_value);
332  } else if ( attr_name == "flags" ) {
333  tokenize(attr_value, flags, ",");
334  }
335 }
336 
337 
338 /** Assert validity.
339  * Calling valid() acts like an assertion. An Exception is thrown if something is wrong.
340  * @exception InterfaceGeneratorInvalidTypeException thrown if InterfaceDataTypeChecker
341  * reports invalid type.
342  * @exception InterfaceGeneratorInvalidValueException thrown if any supplied value is
343  * illegal.
344  * @exception InterfaceGeneratorInvalidFlagException thrown if invalid flag has been
345  * supplied.
346  */
347 void
349 {
350  if ( ! InterfaceDataTypeChecker::validType(type, enum_constants) ) {
351  throw InterfaceGeneratorInvalidTypeException("field", name.c_str(), type.c_str());
352  }
353  if ( (name.length() == 0) || (name.find(" ") != std::string::npos) ) {
354  throw InterfaceGeneratorInvalidValueException("name", "string", "name must not contain spaces");
355  }
356  if ( (length.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", length) ) {
357  throw InterfaceGeneratorInvalidValueException("length", "uint32", length.c_str());
358  }
359  if ( (validfor.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", validfor) ) {
360  throw InterfaceGeneratorInvalidValueException("validfor", "uint32", validfor.c_str());
361  }
362  if ( (default_value.length() > 0) &&
363  ! InterfaceDataTypeChecker::validValue(type, default_value) ) {
364  throw InterfaceGeneratorInvalidValueException("default", type.c_str(), validfor.c_str());
365  }
366  for (std::vector<std::string>::iterator i = flags.begin(); i != flags.end(); ++i) {
367  if ( *i != "changed_indicator" ) {
368  throw InterfaceGeneratorInvalidFlagException(name.c_str(), (*i).c_str());
369  }
370  }
371  /*
372  if ( (type == "char") && (length.length() == 0) ) {
373  throw InterfaceGeneratorMissingAttributeException(name.c_str(), type.c_str(), "length");
374  }
375  */
376 }
377 
378 
379 /** Check order of two elements.
380  * The overall order is like the following:
381  * 1. unsigned int
382  * 2. int
383  * 3. unsigned long int
384  * 4. long int
385  * 5. float
386  * 6. double
387  * 7. bool
388  * 8. byte
389  * 9. char *
390  * @param f field to compare to
391  * @return true, if current instance is small than f, false otherwise
392  */
393 bool
395 {
396  if ( (type == "unsigned int") ) {
397  return (f.type != "unsigned int");
398 
399  } else if ( type == "int" ) {
400  return ( (f.type != "int") &&
401  (f.type != "unsigned int") );
402 
403 
404  } else if ( type == "unsigned long int" ) {
405  return ( (f.type != "unsigned long int") &&
406  (f.type != "unsigned int") &&
407  (f.type != "int") );
408 
409  } else if ( type == "long int" ) {
410  return ( (f.type != "long int") &&
411  (f.type != "unsigned int") &&
412  (f.type != "int") &&
413  (f.type != "unsigned long int") );
414 
415  } else if ( type == "float" ) {
416  return ( (f.type != "float") &&
417  (f.type != "unsigned int") &&
418  (f.type != "int") );
419 
420  } else if ( type == "double" ) {
421  return ( (f.type != "double") &&
422  (f.type != "unsigned int") &&
423  (f.type != "int") &&
424  (f.type != "float") );
425 
426  } else if ( type == "bool" ) {
427  return ( (f.type != "bool") &&
428  (f.type != "double") &&
429  (f.type != "unsigned int") &&
430  (f.type != "int") &&
431  (f.type != "float") );
432 
433  } else if ( type == "byte" ) {
434  return ( (f.type != "byte") &&
435  (f.type != "bool") &&
436  (f.type != "double") &&
437  (f.type != "unsigned int") &&
438  (f.type != "int") &&
439  (f.type != "float") );
440 
441  } else {
442  // char or unknown, char is always last and thus >=
443  return false;
444  }
445 }
std::string getDefaultValue() const
Get default value.
Definition: field.cpp:193
void setFlags(const std::vector< std::string > &flags)
Set flags.
Definition: field.cpp:283
void setName(const std::string &name)
Set name of field.
Definition: field.cpp:232
std::string getName() const
Get name of field.
Definition: field.cpp:53
std::string getStructType() const
Get type used to formulate struct.
Definition: field.cpp:131
bool isEnumType() const
Check if type is an enum type.
Definition: field.cpp:151
static bool validValue(const std::string &type, const std::string &value)
Check value validity for given type.
Interface generator internal representation of a field as parsed from the XML template file...
Definition: field.h:31
void setType(const std::string &type)
Set type of field.
Definition: field.cpp:213
std::string getPlainAccessType() const
Get non-array accessor type.
Definition: field.cpp:113
std::string getAccessType() const
Get type as used for accessor methods of class.
Definition: field.cpp:83
unsigned int getLengthValue() const
Get length value.
Definition: field.cpp:173
Thrown if illegal value is supplied.
Definition: exceptions.h:90
std::string getLength() const
Get field length.
Definition: field.cpp:160
void valid()
Assert validity.
Definition: field.cpp:348
InterfaceField(std::vector< InterfaceEnumConstant > *enum_constants=NULL)
Constructor.
Definition: field.cpp:40
std::string getValidFor() const
Get valid for time.
Definition: field.cpp:183
std::vector< std::string > getFlags() const
Get flags.
Definition: field.cpp:203
bool operator<(const InterfaceField &f) const
Check order of two elements.
Definition: field.cpp:394
std::string getType() const
Get type of field.
Definition: field.cpp:63
void setComment(const std::string &comment)
Set comment of field.
Definition: field.cpp:242
static bool validType(const std::string &type, std::vector< InterfaceEnumConstant > *enum_constants=0)
Check type validity.
void setValidFor(const std::string &validfor)
Set valid for time.
Definition: field.cpp:263
Thrown if illegal flag is supplied.
Definition: exceptions.h:125
std::string getComment() const
Get comment of field.
Definition: field.cpp:73
void setDefaultValue(const std::string &default_value)
Set default value.
Definition: field.cpp:273
void setAttribute(const std::string &attr_name, const std::string &attr_value)
Set attribute.
Definition: field.cpp:320
Thrown if illegal type is supplied.
Definition: exceptions.h:73
void setLength(const std::string &length)
Set length of field.
Definition: field.cpp:252