Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * field.cpp - Interface generator field representation 00004 * 00005 * Generated: Wed Oct 11 18:16:15 2006 00006 * Copyright 2006 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 #include <interfaces/generator/field.h> 00024 #include <interfaces/generator/type_checker.h> 00025 #include <interfaces/generator/exceptions.h> 00026 00027 #include <stdlib.h> 00028 00029 00030 /** @class InterfaceField interfaces/generator/field.h 00031 * Interface generator internal representation of a field as parsed from 00032 * the XML template file. 00033 */ 00034 00035 00036 /** Constructor. 00037 * @param enum_constants enumeration constants that are available and which can be 00038 * used as value type. 00039 */ 00040 InterfaceField::InterfaceField(std::vector<InterfaceEnumConstant> *enum_constants) 00041 { 00042 this->enum_constants = enum_constants; 00043 length = ""; 00044 length_value = 0; 00045 is_enum_type = false; 00046 } 00047 00048 00049 /** Get name of field. 00050 * @return name of field. 00051 */ 00052 std::string 00053 InterfaceField::getName() const 00054 { 00055 return name; 00056 } 00057 00058 00059 /** Get type of field. 00060 * @return type of field. 00061 */ 00062 std::string 00063 InterfaceField::getType() const 00064 { 00065 return type; 00066 } 00067 00068 00069 /** Get comment of field. 00070 * @return comment of field. 00071 */ 00072 std::string 00073 InterfaceField::getComment() const 00074 { 00075 return comment; 00076 } 00077 00078 00079 /** Get type as used for accessor methods of class. 00080 * @return accessor type 00081 */ 00082 std::string 00083 InterfaceField::getAccessType() const 00084 { 00085 if (type == "string") { 00086 return "char *"; 00087 } else { 00088 if ( length != "" ) { 00089 if (type == "byte") { 00090 return "uint8_t *"; 00091 } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) { 00092 return type + " *"; 00093 } else { 00094 return type + "_t *"; 00095 } 00096 } else { 00097 if (type == "byte") { 00098 return "uint8_t"; 00099 } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) { 00100 return type; 00101 } else { 00102 return type + "_t"; 00103 } 00104 } 00105 } 00106 } 00107 00108 00109 /** Get non-array accessor type. 00110 * @return accessor type 00111 */ 00112 std::string 00113 InterfaceField::getPlainAccessType() const 00114 { 00115 if (type == "string") { 00116 return "char *"; 00117 } else if (type == "byte") { 00118 return "uint8_t"; 00119 } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) { 00120 return type; 00121 } else { 00122 return type + "_t"; 00123 } 00124 } 00125 00126 00127 /** Get type used to formulate struct. 00128 * @return struct type 00129 */ 00130 std::string 00131 InterfaceField::getStructType() const 00132 { 00133 if (type == "string") { 00134 return "char"; 00135 } else if (type == "byte") { 00136 return "uint8_t"; 00137 } else if (type == "float" || type == "double" || type == "bool" || is_enum_type) { 00138 return type; 00139 } else { 00140 return type + "_t"; 00141 } 00142 } 00143 00144 00145 /** Check if type is an enum type. 00146 * @return true if the type of this field is an enum type, false otherwise 00147 */ 00148 bool 00149 InterfaceField::isEnumType() const 00150 { 00151 return is_enum_type; 00152 } 00153 00154 /** Get field length. 00155 * @return field length 00156 */ 00157 std::string 00158 InterfaceField::getLength() const 00159 { 00160 return length; 00161 } 00162 00163 00164 /** Get length value. 00165 * This gives the length of the value as a uint instead of a string 00166 * which is sufficient for the generation of the interface but may not 00167 * be sufficient for more elaborated usage. 00168 * @return length of the value 00169 */ 00170 unsigned int 00171 InterfaceField::getLengthValue() const 00172 { 00173 return length_value; 00174 } 00175 00176 00177 /** Get valid for time. 00178 * @return valid for time 00179 */ 00180 std::string 00181 InterfaceField::getValidFor() const 00182 { 00183 return validfor; 00184 } 00185 00186 00187 /** Get default value. 00188 * @return default value 00189 */ 00190 std::string 00191 InterfaceField::getDefaultValue() const 00192 { 00193 return default_value; 00194 } 00195 00196 00197 /** Get flags. 00198 * @return flags. 00199 */ 00200 std::vector<std::string> 00201 InterfaceField::getFlags() const 00202 { 00203 return flags; 00204 } 00205 00206 00207 /** Set type of field. 00208 * @param type new type of field. 00209 */ 00210 void 00211 InterfaceField::setType(const std::string &type) 00212 { 00213 is_enum_type = false; 00214 if ( enum_constants != NULL ) { 00215 for (std::vector<InterfaceEnumConstant>::iterator i = enum_constants->begin(); i != enum_constants->end(); ++i) { 00216 if ( type == (*i).getName() ) { 00217 is_enum_type = true; 00218 } 00219 } 00220 } 00221 this->type = type; 00222 } 00223 00224 00225 /** Set name of field. 00226 * @param name new name of field. 00227 */ 00228 void 00229 InterfaceField::setName(const std::string &name) 00230 { 00231 this->name = name; 00232 } 00233 00234 00235 /** Set comment of field. 00236 * @param comment new comment of field. 00237 */ 00238 void 00239 InterfaceField::setComment(const std::string &comment) 00240 { 00241 this->comment = comment; 00242 } 00243 00244 00245 /** Set length of field. 00246 * @param length set length of field. 00247 */ 00248 void 00249 InterfaceField::setLength(const std::string &length) 00250 { 00251 this->length_value = (unsigned int)atoi(length.c_str()); 00252 this->length = length; 00253 } 00254 00255 00256 /** Set valid for time. 00257 * @param validfor new valid for time 00258 */ 00259 void 00260 InterfaceField::setValidFor(const std::string &validfor) 00261 { 00262 this->validfor = validfor; 00263 } 00264 00265 00266 /** Set default value. 00267 * @param default_value new default value 00268 */ 00269 void 00270 InterfaceField::setDefaultValue(const std::string &default_value) 00271 { 00272 this->default_value = default_value; 00273 } 00274 00275 00276 /** Set flags. 00277 * @param flags new flags of field 00278 */ 00279 void 00280 InterfaceField::setFlags(const std::vector<std::string> &flags) 00281 { 00282 this->flags = flags; 00283 } 00284 00285 00286 /** Tokenize given string. 00287 * @param str tsring to tokenize 00288 * @param tokens vector where result will be stored 00289 * @param delimiters string with delimiters. 00290 */ 00291 void 00292 InterfaceField::tokenize(const std::string& str, 00293 std::vector<std::string>& tokens, 00294 const std::string& delimiters) 00295 { 00296 // Skip delimiters at beginning. 00297 std::string::size_type last_pos = str.find_first_not_of(delimiters, 0); 00298 // Find first "non-delimiter". 00299 std::string::size_type pos = str.find_first_of(delimiters, last_pos); 00300 00301 while (std::string::npos != pos || std::string::npos != last_pos) { 00302 // Found a token, add it to the vector. 00303 tokens.push_back(str.substr(last_pos, pos - last_pos)); 00304 // Skip delimiters. Note the "not_of" 00305 last_pos = str.find_first_not_of(delimiters, pos); 00306 // Find next "non-delimiter" 00307 pos = str.find_first_of(delimiters, last_pos); 00308 } 00309 } 00310 00311 00312 /** Set attribute. 00313 * @param attr_name attribute name 00314 * @param attr_value attribute value. 00315 */ 00316 void 00317 InterfaceField::setAttribute(const std::string &attr_name, const std::string &attr_value) 00318 { 00319 if ( attr_name == "name" ) { 00320 setName(attr_value); 00321 } else if ( attr_name == "type" ) { 00322 setType(attr_value); 00323 } else if ( attr_name == "length" ) { 00324 setLength(attr_value); 00325 } else if ( attr_name == "validfor" ) { 00326 setValidFor(attr_value); 00327 } else if ( attr_name == "default" ) { 00328 setDefaultValue(attr_value); 00329 } else if ( attr_name == "flags" ) { 00330 tokenize(attr_value, flags, ","); 00331 } 00332 } 00333 00334 00335 /** Assert validity. 00336 * Calling valid() acts like an assertion. An Exception is thrown if something is wrong. 00337 * @exception InterfaceGeneratorInvalidTypeException thrown if InterfaceDataTypeChecker 00338 * reports invalid type. 00339 * @exception InterfaceGeneratorInvalidValueException thrown if any supplied value is 00340 * illegal. 00341 * @exception InterfaceGeneratorInvalidFlagException thrown if invalid flag has been 00342 * supplied. 00343 */ 00344 void 00345 InterfaceField::valid() 00346 { 00347 if ( ! InterfaceDataTypeChecker::validType(type, enum_constants) ) { 00348 throw InterfaceGeneratorInvalidTypeException("field", name.c_str(), type.c_str()); 00349 } 00350 if ( (name.length() == 0) || (name.find(" ") != std::string::npos) ) { 00351 throw InterfaceGeneratorInvalidValueException("name", "string", "name must not contain spaces"); 00352 } 00353 if ( (length.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", length) ) { 00354 throw InterfaceGeneratorInvalidValueException("length", "uint32", length.c_str()); 00355 } 00356 if ( (validfor.length() > 0) && ! InterfaceDataTypeChecker::validValue("uint32", validfor) ) { 00357 throw InterfaceGeneratorInvalidValueException("validfor", "uint32", validfor.c_str()); 00358 } 00359 if ( (default_value.length() > 0) && 00360 ! InterfaceDataTypeChecker::validValue(type, default_value) ) { 00361 throw InterfaceGeneratorInvalidValueException("default", type.c_str(), validfor.c_str()); 00362 } 00363 for (std::vector<std::string>::iterator i = flags.begin(); i != flags.end(); ++i) { 00364 if ( *i != "changed_indicator" ) { 00365 throw InterfaceGeneratorInvalidFlagException(name.c_str(), (*i).c_str()); 00366 } 00367 } 00368 /* 00369 if ( (type == "char") && (length.length() == 0) ) { 00370 throw InterfaceGeneratorMissingAttributeException(name.c_str(), type.c_str(), "length"); 00371 } 00372 */ 00373 } 00374 00375 00376 /** Check order of two elements. 00377 * The overall order is like the following: 00378 * 1. unsigned int 00379 * 2. int 00380 * 3. unsigned long int 00381 * 4. long int 00382 * 5. float 00383 * 6. double 00384 * 7. bool 00385 * 8. byte 00386 * 9. char * 00387 * @param f field to compare to 00388 * @return true, if current instance is small than f, false otherwise 00389 */ 00390 bool 00391 InterfaceField::operator< (const InterfaceField &f) const 00392 { 00393 if ( (type == "unsigned int") ) { 00394 return (f.type != "unsigned int"); 00395 00396 } else if ( type == "int" ) { 00397 return ( (f.type != "int") && 00398 (f.type != "unsigned int") ); 00399 00400 00401 } else if ( type == "unsigned long int" ) { 00402 return ( (f.type != "unsigned long int") && 00403 (f.type != "unsigned int") && 00404 (f.type != "int") ); 00405 00406 } else if ( type == "long int" ) { 00407 return ( (f.type != "long int") && 00408 (f.type != "unsigned int") && 00409 (f.type != "int") && 00410 (f.type != "unsigned long int") ); 00411 00412 } else if ( type == "float" ) { 00413 return ( (f.type != "float") && 00414 (f.type != "unsigned int") && 00415 (f.type != "int") ); 00416 00417 } else if ( type == "double" ) { 00418 return ( (f.type != "double") && 00419 (f.type != "unsigned int") && 00420 (f.type != "int") && 00421 (f.type != "float") ); 00422 00423 } else if ( type == "bool" ) { 00424 return ( (f.type != "bool") && 00425 (f.type != "double") && 00426 (f.type != "unsigned int") && 00427 (f.type != "int") && 00428 (f.type != "float") ); 00429 00430 } else if ( type == "byte" ) { 00431 return ( (f.type != "byte") && 00432 (f.type != "bool") && 00433 (f.type != "double") && 00434 (f.type != "unsigned int") && 00435 (f.type != "int") && 00436 (f.type != "float") ); 00437 00438 } else { 00439 // char or unknown, char is always last and thus >= 00440 return false; 00441 } 00442 }