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