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 */
38InterfaceField::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 */
49std::string
51{
52 return name;
53}
54
55/** Get type of field.
56 * @return type of field.
57 */
58std::string
60{
61 return type;
62}
63
64/** Get comment of field.
65 * @return comment of field.
66 */
67std::string
69{
70 return comment;
71}
72
73/** Get type as used for accessor methods of class.
74 * @return accessor type
75 */
76std::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 */
105std::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 */
122std::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 */
141bool
143{
144 return is_enum_type;
145}
146
147/** Get field length.
148 * @return field length
149 */
150std::string
152{
153 return length;
154}
155
156/** Get maximum index (length - 1)
157 * @return maximum index
158 */
159std::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 */
171unsigned int
173{
174 return length_value;
175}
176
177/** Get valid for time.
178 * @return valid for time
179 */
180std::string
182{
183 return validfor;
184}
185
186/** Get default value.
187 * @return default value
188 */
189std::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 */
198const 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 */
211InterfaceField::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 */
229std::vector<std::string>
231{
232 return flags;
233}
234
235/** Set type of field.
236 * @param type new type of field.
237 */
238void
239InterfaceField::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 */
256void
257InterfaceField::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 */
265void
266InterfaceField::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 */
274void
275InterfaceField::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 */
285void
286InterfaceField::setValidFor(const std::string &validfor)
287{
288 this->validfor = validfor;
289}
290
291/** Set default value.
292 * @param default_value new default value
293 */
294void
295InterfaceField::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 */
303void
304InterfaceField::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 */
314void
315InterfaceField::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 */
338void
339InterfaceField::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 */
366void
367InterfaceField::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 */
416bool
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