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