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