Fawkes API Fawkes Development Version

field.cpp

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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends