00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CAFECONVERT_H
00009 #define CAFECONVERT_H
00010
00011 #include <cafeDataType.h>
00012 #include <cstdlib>
00013 #include <cstdio>
00014 #include <boost/math/special_functions/fpclassify.hpp>
00015
00029 template <class CTYPE> class CAFEConvert {
00030 private:
00031 CTYPE returnVal[1];
00032 public:
00033 CAFEConvert (unsigned int nelem){};
00034 CAFEConvert (){};
00035 ~CAFEConvert (){};
00036 CTYPE * get(unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val);
00037 CTYPE * getString(unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val);
00038 CTYPE * getStringFromEnum(unsigned int index, unsigned int noStr, CAFE_DATATYPE_UNION_SEQ val, char stig[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]);
00039 CTYPE * get(CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val);
00040 CTYPE * getString(CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val);
00041 };
00042
00043
00050 template <class CTYPE> CTYPE * CAFEConvert<CTYPE>::get (CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val)
00051 {
00052 #define __METHOD__ "CAFEConvert<CTYPE>::get(dt, val)"
00053
00054
00055
00056
00057
00058 switch (dt) {
00059 case CAFE_DOUBLE:
00060 if ( (boost::math::isnan)((CTYPE) val.d) ) {
00061 returnVal[0]= (CTYPE) val.d;
00062 }
00063 else {
00064 returnVal[0]= (CTYPE) 0;
00065 }
00066 break;
00067 case CAFE_FLOAT:
00068 if ( (boost::math::isnan)((CTYPE) val.f) ) {
00069 returnVal[0]= (CTYPE) val.f;
00070 } else {
00071 returnVal[0]= 0;
00072 }
00073 break;
00074 case CAFE_LONG:
00075 returnVal[0]= (CTYPE) val.l;
00076 break;
00077 case CAFE_SHORT:
00078 returnVal[0]= (CTYPE) val.s;
00079 break;
00080 case CAFE_ENUM:
00081 returnVal[0]= (CTYPE) val.us;
00082 break;
00083 case CAFE_CHAR:
00084 returnVal[0]= (CTYPE) val.ch;
00085 break;
00086 case CAFE_STRING:
00087 returnVal[0]= (CTYPE) strtod( val.str, NULL);
00088 break;
00089 case CAFE_TYPENOTCONN:
00090
00091
00092 returnVal[0]=0;
00093 break;
00094 case CAFE_NO_ACCESS:
00095
00096
00097 returnVal[0]=0;
00098 break;
00099 case CAFE_INVALID_DATATYPE:
00100
00101
00102 returnVal[0]=0;
00103 break;
00104 case CAFE_NOT_REQUESTED:
00105
00106
00107 returnVal[0]=0;
00108 break;
00109 case CAFE_NOT_SHOWN:
00110
00111
00112 returnVal[0]=0;
00113 break;
00114 default:
00115 std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__
00116 << " CAFE INTERNAL ERROR: Unknown dataType: " << dt << " " << std::endl;
00117 returnVal[0]=0;
00118 break;
00119 }
00120
00121 return (CTYPE *) returnVal;
00122
00123 #undef __METHOD__
00124 }
00125
00133 template <class CTYPE> CTYPE * CAFEConvert<CTYPE>::get (unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val)
00134 {
00135 #define __METHOD__ "CAFEConvert<CTYPE>::get(index, dt, val[])"
00136
00137 switch (dt) {
00138 case CAFE_DOUBLE:
00139 returnVal[0]= (CTYPE) val[index].d;
00140 break;
00141 case CAFE_FLOAT:
00142 returnVal[0]= (CTYPE) val[index].f;
00143 break;
00144 case CAFE_LONG:
00145 returnVal[0]= (CTYPE) val[index].l;
00146 break;
00147 case CAFE_SHORT:
00148 returnVal[0]= (CTYPE) val[index].s;
00149 break;
00150 case CAFE_ENUM:
00151 returnVal[0]= (CTYPE) val[index].us;
00152 break;
00153 case CAFE_CHAR:
00154 returnVal[0]= (CTYPE) val[index].ch;
00155 break;
00156 case CAFE_STRING:
00157 returnVal[0]= (CTYPE) strtod( val[index].str, NULL);
00158 break;
00159 case CAFE_TYPENOTCONN:
00160
00161
00162 returnVal[0]=0;
00163 break;
00164 case CAFE_NO_ACCESS:
00165
00166
00167 returnVal[0]=0;
00168 break;
00169 case CAFE_INVALID_DATATYPE:
00170
00171
00172 returnVal[0]=0;
00173 break;
00174 case CAFE_NOT_REQUESTED:
00175
00176
00177 returnVal[0]=0;
00178 break;
00179 case CAFE_NOT_SHOWN:
00180
00181
00182 returnVal[0]=0;
00183 break;
00184 default:
00185 std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__
00186 << " CAFE INTERNAL ERROR: Unknown dataType: " << dt << " " << std::endl;
00187 returnVal[0]=0;
00188 break;
00189 }
00190
00191 return (CTYPE *) returnVal;
00192
00193 #undef __METHOD__
00194 };
00195
00196
00197
00198
00207 template <class CTYPE> CTYPE * CAFEConvert<CTYPE>::getStringFromEnum (unsigned int index, unsigned int noStr, CAFE_DATATYPE_UNION_SEQ val,
00208 char stig[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE])
00209 {
00210 #define __METHOD__ "CAFEConvert<CTYPE>::getStringFromEnum(indx, noStr, val, stig)"
00211
00212
00213 unsigned int noEmptyStrings=0;
00214
00215 for (unsigned int j=0; j<noStr; ++j) {
00216 if (strcmp(stig[j],"")==0) {
00217 ++noEmptyStrings;
00218 }
00219 }
00220
00221 if (noStr==noEmptyStrings) {
00222 std::cout << "*** WARNING FROM " << __METHOD__ << " *** " << std::endl;
00223 std::cout << "ENUM STRING OPTIONS ARE ALL EMPTY! " << std::endl;
00224 std::cout << "BADLY CONFIGURED EPICS RECORD. " << std::endl;
00225 }
00226
00227
00228 if (index < noStr && noStr!=noEmptyStrings) {
00229 sprintf(returnVal[0], "%s", stig[val[index].us] );
00230 }
00231 else {
00232 sprintf(returnVal[0], "%d", val[index].us );
00233 if ( val[index].us>= noStr) {
00234 std::cout << "*** WARNING FROM " << __METHOD__ << " *** " << std::endl;
00235 std::cout << "ENUM UNSIGNED SHORT VALUE IS GREATER THAN THE NO OF ENUMERATED TYPES" << std::endl;
00236 std::cout << "VALUE (unsigned short) = " << val[index].us << std::endl;
00237 std::cout << "NO OF ENUMERATED STRINGS = " << noStr << " WITH VALUES: " << std::endl;
00238 for (unsigned int j=0; j<noStr; ++j) {
00239 std::cout << stig[j] << " [" <<j << "] ";
00240 }
00241 std::cout << std::endl;
00242 }
00243 }
00244
00245 return (CTYPE *) returnVal;
00246
00247 #undef __METHOD__
00248 };
00249
00257 template <class CTYPE> CTYPE * CAFEConvert<CTYPE>::getString (unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val)
00258 {
00259 #define __METHOD__ "CAFEConvert<CTYPE>::getString(nelem, dt, val[])"
00260
00261 switch (dt) {
00262 case CAFE_STRING:
00263 sprintf(returnVal[0], "%s", val[index].str);
00264 break;
00265 case CAFE_CHAR:
00266 sprintf(returnVal[0], "%u", val[index].ch);
00267 break;
00268 case CAFE_FLOAT:
00269 sprintf(returnVal[0], "%f", val[index].f);
00270 break;
00271 case CAFE_DOUBLE:
00272 sprintf(returnVal[0], "%.15f", val[index].d);
00273 break;
00274 case CAFE_SHORT:
00275 sprintf(returnVal[0], "%d", val[index].s);
00276 break;
00277 case CAFE_LONG:
00278 sprintf(returnVal[0], "%d", val[index].l);
00279 break;
00280 case CAFE_ENUM:
00281 sprintf(returnVal[0], "%u", val[index].us);
00282 break;
00283 case CAFE_TYPENOTCONN:
00284
00285
00286 sprintf(returnVal[0], "%s", "0");
00287 break;
00288 case CAFE_NO_ACCESS:
00289
00290
00291 sprintf(returnVal[0], "%s", "0");
00292 break;
00293 case CAFE_INVALID_DATATYPE:
00294
00295
00296 sprintf(returnVal[0], "%s", "0");
00297 break;
00298 case CAFE_NOT_REQUESTED:
00299
00300
00301 sprintf(returnVal[0], "%s", "0");
00302 break;
00303 case CAFE_NOT_SHOWN:
00304
00305
00306 sprintf(returnVal[0], "%s", "0");
00307 break;
00308 default:
00309
00310
00311 sprintf(returnVal[0], "%s", "0");
00312 break;
00313
00314 }
00315
00316 return (CTYPE *) returnVal;
00317
00318 #undef __METHOD__
00319 };
00320
00327 template <class CTYPE> CTYPE * CAFEConvert<CTYPE>::getString (CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val)
00328 {
00329 #define __METHOD__ "CAFEConvert<CTYPE>::getString(dt, val[])"
00330
00331 switch (dt) {
00332 case CAFE_STRING:
00333 sprintf(returnVal[0], "%s", val.str);
00334 break;
00335 case CAFE_CHAR:
00336 sprintf(returnVal[0], "%u", val.ch);
00337 break;
00338 case CAFE_FLOAT:
00339 sprintf(returnVal[0], "%f", val.f);
00340 break;
00341 case CAFE_DOUBLE:
00342 sprintf(returnVal[0], "%.15f", val.d);
00343 break;
00344 case CAFE_SHORT:
00345 sprintf(returnVal[0], "%d", val.s);
00346 break;
00347 case CAFE_LONG:
00348 sprintf(returnVal[0], "%d", val.l);
00349 break;
00350 case CAFE_ENUM:
00351 sprintf(returnVal[0], "%u", val.us);
00352 break;
00353 case CAFE_TYPENOTCONN:
00354
00355
00356 sprintf(returnVal[0], "%s", "0");
00357 break;
00358 case CAFE_NO_ACCESS:
00359
00360
00361 sprintf(returnVal[0], "%s", "0");
00362 break;
00363 case CAFE_INVALID_DATATYPE:
00364
00365
00366 sprintf(returnVal[0], "%s", "0");
00367 break;
00368 case CAFE_NOT_REQUESTED:
00369
00370
00371 sprintf(returnVal[0], "%s", "0");
00372 break;
00373 case CAFE_NOT_SHOWN:
00374
00375
00376 sprintf(returnVal[0], "%s", "0");
00377 break;
00378 default:
00379
00380
00381 sprintf(returnVal[0], "%s", "0");
00382 break;
00383
00384 }
00385
00386 return (CTYPE *) returnVal;
00387
00388 #undef __METHOD__
00389 };
00390
00391
00392
00393 #endif