Fawkes API  Fawkes Development Version
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 vector of enum constants.
200  * @return const reference to vector of interface enum constants.
201  */
202 const std::vector<InterfaceEnumConstant> *
204 {
205  return enum_constants;
206 }
207 
208 /** Get specific enum constant.
209  * @param name type name of enum constant
210  * @return const reference on enum constant
211  * @exception Exception thrown if no enum constant of the given name
212  * could be found
213  */
214 const InterfaceEnumConstant &
215 InterfaceField::getEnumConstant(const std::string &name) const
216 {
217  if (! enum_constants) throw fawkes::Exception("No enum constants registered");
218 
219  std::vector<InterfaceEnumConstant>::const_iterator i;
220  for (i = enum_constants->begin(); i != enum_constants->end(); ++i) {
221  if ( type == i->get_name() ) {
222  return *i;
223  }
224  }
225 
226  throw fawkes::Exception("Enum constant %s not found", name.c_str());
227 }
228 
229 
230 /** Get flags.
231  * @return flags.
232  */
233 std::vector<std::string>
235 {
236  return flags;
237 }
238 
239 
240 /** Set type of field.
241  * @param type new type of field.
242  */
243 void
244 InterfaceField::setType(const std::string &type)
245 {
246  is_enum_type = false;
247  if ( enum_constants != NULL ) {
248  std::vector<InterfaceEnumConstant>::iterator i;
249  for (i = enum_constants->begin(); i != enum_constants->end(); ++i) {
250  if ( type == (*i).get_name() ) {
251  is_enum_type = true;
252  }
253  }
254  }
255  this->type = type;
256 }
257 
258 
259 /** Set name of field.
260  * @param name new name of field.
261  */
262 void
263 InterfaceField::setName(const std::string &name)
264 {
265  this->name = name;
266 }
267 
268 
269 /** Set comment of field.
270  * @param comment new comment of field.
271  */
272 void
273 InterfaceField::setComment(const std::string &comment)
274 {
275  this->comment = comment;
276 }
277 
278 
279 /** Set length of field.
280  * @param length set length of field.
281  */
282 void
283 InterfaceField::setLength(const std::string &length)
284 {
285  this->length_value = (unsigned int)atoi(length.c_str());
286  this->length = length;
287 }
288 
289 
290 /** Set valid for time.
291  * @param validfor new valid for time
292  */
293 void
294 InterfaceField::setValidFor(const std::string &validfor)
295 {
296  this->validfor = validfor;
297 }
298 
299 
300 /** Set default value.
301  * @param default_value new default value
302  */
303 void
304 InterfaceField::setDefaultValue(const std::string &default_value)
305 {
306  this->default_value = default_value;
307 }
308 
309 
310 /** Set flags.
311  * @param flags new flags of field
312  */
313 void
314 InterfaceField::setFlags(const std::vector<std::string> &flags)
315 {
316  this->flags = flags;
317 }
318 
319 
320 /** Tokenize given string.
321  * @param str tsring to tokenize
322  * @param tokens vector where result will be stored
323  * @param delimiters string with delimiters.
324  */
325 void
326 InterfaceField::tokenize(const std::string& str,
327  std::vector<std::string>& tokens,
328  const std::string& delimiters)
329 {
330  // Skip delimiters at beginning.
331  std::string::size_type last_pos = str.find_first_not_of(delimiters, 0);
332  // Find first "non-delimiter".
333  std::string::size_type pos = str.find_first_of(delimiters, last_pos);
334 
335  while (std::string::npos != pos || std::string::npos != last_pos) {
336  // Found a token, add it to the vector.
337  tokens.push_back(str.substr(last_pos, pos - last_pos));
338  // Skip delimiters. Note the "not_of"
339  last_pos = str.find_first_not_of(delimiters, pos);
340  // Find next "non-delimiter"
341  pos = str.find_first_of(delimiters, last_pos);
342  }
343 }
344 
345 
346 /** Set attribute.
347  * @param attr_name attribute name
348  * @param attr_value attribute value.
349  */
350 void
351 InterfaceField::setAttribute(const std::string &attr_name, const std::string &attr_value)
352 {
353  if ( attr_name == "name" ) {
354  setName(attr_value);
355  } else if ( attr_name == "type" ) {
356  setType(attr_value);
357  } else if ( attr_name == "length" ) {
358  setLength(attr_value);
359  } else if ( attr_name == "validfor" ) {
360  setValidFor(attr_value);
361  } else if ( attr_name == "default" ) {
362  setDefaultValue(attr_value);
363  } else if ( attr_name == "flags" ) {
364  tokenize(attr_value, flags, ",");
365  }
366 }
367 
368 
369 /** Assert validity.
370  * Calling valid() acts like an assertion. An Exception is thrown if something is wrong.
371  * @exception InterfaceGeneratorInvalidTypeException thrown if InterfaceDataTypeChecker
372  * reports invalid type.
373  * @exception InterfaceGeneratorInvalidValueException thrown if any supplied value is
374  * illegal.
375  * @exception InterfaceGeneratorInvalidFlagException thrown if invalid flag has been
376  * supplied.
377  */
378 void
380 {
381  if ( ! InterfaceDataTypeChecker::validType(type, enum_constants) ) {
382  throw InterfaceGeneratorInvalidTypeException("field", name.c_str(), type.c_str());
383  }
384  if ( (name.length() == 0) || (name.find(" ") != std::string::npos) ) {
385  throw InterfaceGeneratorInvalidValueException("name", "string", "name must not contain spaces");
386  }
387  if ( (length.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", length) ) {
388  throw InterfaceGeneratorInvalidValueException("length", "uint32", length.c_str());
389  }
390  if ( (validfor.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", validfor) ) {
391  throw InterfaceGeneratorInvalidValueException("validfor", "uint32", validfor.c_str());
392  }
393  if ( (default_value.length() > 0) &&
394  ! InterfaceDataTypeChecker::validValue(type, default_value) ) {
395  throw InterfaceGeneratorInvalidValueException("default", type.c_str(), validfor.c_str());
396  }
397  for (std::vector<std::string>::iterator i = flags.begin(); i != flags.end(); ++i) {
398  if ( *i != "changed_indicator" ) {
399  throw InterfaceGeneratorInvalidFlagException(name.c_str(), (*i).c_str());
400  }
401  }
402  /*
403  if ( (type == "char") && (length.length() == 0) ) {
404  throw InterfaceGeneratorMissingAttributeException(name.c_str(), type.c_str(), "length");
405  }
406  */
407 }
408 
409 
410 /** Check order of two elements.
411  * The overall order is like the following:
412  * 1. unsigned int
413  * 2. int
414  * 3. unsigned long int
415  * 4. long int
416  * 5. float
417  * 6. double
418  * 7. bool
419  * 8. byte
420  * 9. char *
421  * @param f field to compare to
422  * @return true, if current instance is small than f, false otherwise
423  */
424 bool
426 {
427  if ( (type == "unsigned int") ) {
428  return (f.type != "unsigned int");
429 
430  } else if ( type == "int" ) {
431  return ( (f.type != "int") &&
432  (f.type != "unsigned int") );
433 
434 
435  } else if ( type == "unsigned long int" ) {
436  return ( (f.type != "unsigned long int") &&
437  (f.type != "unsigned int") &&
438  (f.type != "int") );
439 
440  } else if ( type == "long int" ) {
441  return ( (f.type != "long int") &&
442  (f.type != "unsigned int") &&
443  (f.type != "int") &&
444  (f.type != "unsigned long int") );
445 
446  } else if ( type == "float" ) {
447  return ( (f.type != "float") &&
448  (f.type != "unsigned int") &&
449  (f.type != "int") );
450 
451  } else if ( type == "double" ) {
452  return ( (f.type != "double") &&
453  (f.type != "unsigned int") &&
454  (f.type != "int") &&
455  (f.type != "float") );
456 
457  } else if ( type == "bool" ) {
458  return ( (f.type != "bool") &&
459  (f.type != "double") &&
460  (f.type != "unsigned int") &&
461  (f.type != "int") &&
462  (f.type != "float") );
463 
464  } else if ( type == "byte" ) {
465  return ( (f.type != "byte") &&
466  (f.type != "bool") &&
467  (f.type != "double") &&
468  (f.type != "unsigned int") &&
469  (f.type != "int") &&
470  (f.type != "float") );
471 
472  } else {
473  // char or unknown, char is always last and thus >=
474  return false;
475  }
476 }
std::string getType() const
Get type of field.
Definition: field.cpp:63
const InterfaceEnumConstant & getEnumConstant(const std::string &name) const
Get specific enum constant.
Definition: field.cpp:215
void setFlags(const std::vector< std::string > &flags)
Set flags.
Definition: field.cpp:314
void setName(const std::string &name)
Set name of field.
Definition: field.cpp:263
unsigned int getLengthValue() const
Get length value.
Definition: field.cpp:173
Interface generator internal representation of a enum constant as parsed from the XML template file...
Definition: enum_constant.h:30
std::vector< std::string > getFlags() const
Get flags.
Definition: field.cpp:234
std::string getDefaultValue() const
Get default value.
Definition: field.cpp:193
const std::vector< InterfaceEnumConstant > * getEnumConstants() const
Get vector of enum constants.
Definition: field.cpp:203
std::string getName() const
Get name of field.
Definition: field.cpp:53
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:244
std::string getValidFor() const
Get valid for time.
Definition: field.cpp:183
std::string getPlainAccessType() const
Get non-array accessor type.
Definition: field.cpp:113
Thrown if illegal value is supplied.
Definition: exceptions.h:90
void valid()
Assert validity.
Definition: field.cpp:379
std::string getAccessType() const
Get type as used for accessor methods of class.
Definition: field.cpp:83
InterfaceField(std::vector< InterfaceEnumConstant > *enum_constants=NULL)
Constructor.
Definition: field.cpp:40
Base class for exceptions in Fawkes.
Definition: exception.h:36
std::string getComment() const
Get comment of field.
Definition: field.cpp:73
void setComment(const std::string &comment)
Set comment of field.
Definition: field.cpp:273
bool operator<(const InterfaceField &f) const
Check order of two elements.
Definition: field.cpp:425
static bool validType(const std::string &type, std::vector< InterfaceEnumConstant > *enum_constants=0)
Check type validity.
std::string getLength() const
Get field length.
Definition: field.cpp:160
void setValidFor(const std::string &validfor)
Set valid for time.
Definition: field.cpp:294
Thrown if illegal flag is supplied.
Definition: exceptions.h:125
bool isEnumType() const
Check if type is an enum type.
Definition: field.cpp:151
void setDefaultValue(const std::string &default_value)
Set default value.
Definition: field.cpp:304
void setAttribute(const std::string &attr_name, const std::string &attr_value)
Set attribute.
Definition: field.cpp:351
Thrown if illegal type is supplied.
Definition: exceptions.h:73
void setLength(const std::string &length)
Set length of field.
Definition: field.cpp:283
std::string getStructType() const
Get type used to formulate struct.
Definition: field.cpp:131