Fawkes API Fawkes Development Version
|
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 }