type_checker.cpp

00001  
00002 /***************************************************************************
00003  *  type_checker.cpp - Interface generator type checker
00004  *
00005  *  Generated: Wed Oct 11 15:39:10 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/type_checker.h>
00024 #include <interfaces/generator/exceptions.h>
00025 #include <core/exception.h>
00026 
00027 #include <cstdlib>
00028 #include <climits>
00029 #include <cmath>
00030 #include <cerrno>
00031 
00032 // request setting of INT8_MAX etc. constants
00033 #ifndef __STDC_LIMIT_MACROS
00034 #define __STDC_LIMIT_MACROS
00035 #endif
00036 #include <stdint.h>
00037 
00038 /** @class InterfaceDataTypeChecker <interfaces/generator/type_checker.h>
00039  * Type checker for interface types.
00040  * This classed is used by the generator to decide if a supplied type is
00041  * correct and in the case of constants if the supplied value matches the
00042  * field type.
00043  *
00044  * Valid types are:
00045  * - int
00046  * - long int
00047  * - unsigned int
00048  * - unsigned long int
00049  * - bool
00050  * - float
00051  * - double
00052  * - byte (unsigned 8-bit number)
00053  * - string
00054  */
00055 
00056 
00057 /** Check type validity.
00058  * @param type type string to check
00059  * @param enum_constants an optional vector of enumeration constants that are used for
00060  * type validation.
00061  * @return true, if type is valid, false otherwise
00062  */
00063 bool
00064 InterfaceDataTypeChecker::validType(const std::string &type, std::vector<InterfaceEnumConstant> *enum_constants)
00065 {
00066   if ( (type == "int8") ||
00067        (type == "int16") ||
00068        (type == "int32") ||
00069        (type == "int64") ||
00070        (type == "uint8") ||
00071        (type == "uint16") ||
00072        (type == "uint32") ||
00073        (type == "uint64") ||
00074        (type == "bool") ||
00075        (type == "char") ||
00076        (type == "float") ||
00077        (type == "byte") ||
00078        (type == "string") ||
00079        (type == "double") ) {
00080     return true;
00081   } else if ( enum_constants != NULL ) {
00082     for (std::vector<InterfaceEnumConstant>::iterator i = enum_constants->begin(); i != enum_constants->end(); ++i) {
00083       if ( type == (*i).getName() ) {
00084         return true;
00085       }
00086     }
00087     return false;
00088   } else {
00089     return false;
00090   }
00091 }
00092 
00093 
00094 /** Check value validity for given type.
00095  * @param type type if value
00096  * @param value value to check
00097  * @return true, if value is valid for type, false otherwise
00098  */
00099 bool
00100 InterfaceDataTypeChecker::validValue(const std::string &type, const std::string &value)
00101 {
00102   if (type.find("int") != std::string::npos) {
00103     char *endptr;
00104     long long int rv = strtoll(value.c_str(), &endptr, 10);
00105     if ( ((rv == LLONG_MIN) || (rv == LLONG_MAX)) && (errno == ERANGE) ) {
00106       throw fawkes::Exception("Could not convert value string '%s' to "
00107                               "long long int", value.c_str());
00108     }
00109     if ( (endptr != NULL) && (endptr[0] == '\0')) {
00110       if (type == "uint8") {
00111         return (rv >= 0) && (rv <= UINT8_MAX);
00112       } else if (type == "uint16") {
00113         return (rv >= 0) && (rv <= UINT16_MAX);
00114       } else if (type == "uint32") {
00115         return (rv >= 0) && (rv <= UINT32_MAX);
00116       } else if (type == "uint64") {
00117         return (rv >= 0) && ((uint64_t)rv <= UINT64_MAX);
00118       } else if (type == "int8") {
00119         return (rv >= INT8_MIN) && (rv <= INT8_MAX);
00120       } else if (type == "int16") {
00121         return (rv >= INT16_MIN) && (rv <= INT16_MAX);
00122       } else if (type == "int32") {
00123         return (rv >= INT32_MIN) && (rv <= INT32_MAX);
00124       } else if (type == "int64") {
00125         return (rv >= INT64_MIN) && (rv <= INT64_MAX);
00126       } else {
00127         return false;
00128       }
00129     } else {
00130       return false;
00131     }
00132   } else if ( type == "bool" ) {
00133     return ( (value == "true") ||
00134              (value == "false") ||
00135              (value == "yes") ||
00136              (value == "no") ||
00137              (value == "0") ||
00138              (value == "1") );
00139   } else if ( (type == "float") ||
00140               (type == "double") ) {
00141     char *endptr;
00142     float rv = strtod(value.c_str(), &endptr);
00143     if ((rv == HUGE_VAL) || (rv == -HUGE_VAL)) {
00144       throw fawkes::Exception("Could not convert string '%s' to float", value.c_str());
00145     }
00146     return ((endptr != NULL) && (endptr[0] == '\0'));
00147   } else if ( type == "string" ) {
00148     return true;
00149   } else {
00150     return false;
00151   }
00152 }

Generated on Tue Feb 22 13:32:24 2011 for Fawkes API by  doxygen 1.4.7