/// /// \file cafeConvert.h /// \author Jan Chrin, PSI /// \date Release: February 2015 /// \version CAFE 1.0.0 /// #ifndef CAFECONVERT_H #define CAFECONVERT_H #include #include // g++ 4.4.4 #include #include using namespace std; /** * CAFEConvert Template \n * CTYPE is the input data type \n * PVDataHolder methods use CAFEConvert as follows: \n * method getAsDouble() converts CTYPE to double \n * method getAsFloat () converts CTYPE to float \n * method getAsShort () converts CTYPE to short \n * method getAsEnum () converts CTYPE to enum \n * method getAsChar () converts CTYPE to char \n * method getAsLong () converts CTYPE to int \n * method getAsString() converts CTYPE to string \n * */ template class CAFEConvert { private: CTYPE returnVal[1]; public: CAFEConvert (unsigned int nelem){}; CAFEConvert (){}; ~CAFEConvert (){}; CTYPE * get(unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val); CTYPE * getString(unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val); CTYPE * getStringFromEnum(unsigned int index, unsigned int noStr, CAFE_DATATYPE_UNION_SEQ val, char stig[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]); CTYPE * get(CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val); CTYPE * getString(CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val); }; /** * Converts from native type to CTYPE * \param dt input: CAFE_DATATYPE * \param val input: CAFE_DATATYPE_UNION * \return CTYPE */ template CTYPE * CAFEConvert::get (CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val) { #define __METHOD__ "CAFEConvert::get(dt, val)" // (boost::math::isnan) calls the Boost version of the isnan macro // Valid for all types that have numeric_limits support // (brackets required) to avoid compiler error should isnan also be a native macro switch (dt) { case CAFE_DOUBLE: if ( (boost::math::isnan)((CTYPE) val.d) ) { returnVal[0]= (CTYPE) val.d; } else { returnVal[0]= (CTYPE) 0; } break; case CAFE_FLOAT: if ( (boost::math::isnan)((CTYPE) val.f) ) { returnVal[0]= (CTYPE) val.f; } else { returnVal[0]= 0; } break; case CAFE_LONG: returnVal[0]= (CTYPE) val.l; break; case CAFE_SHORT: returnVal[0]= (CTYPE) val.s; break; case CAFE_ENUM: returnVal[0]= (CTYPE) val.us; break; case CAFE_CHAR: returnVal[0]= (CTYPE) val.ch; break; case CAFE_STRING: returnVal[0]= (CTYPE) strtod( val.str, NULL); break; case CAFE_TYPENOTCONN: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_TYPENOTCONN: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NO_ACCESS: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_NO_ACCESS: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_INVALID_DATATYPE: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NOT_REQUESTED: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_NOT_REQUESTED: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NOT_SHOWN: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; returnVal[0]=0; break; default: cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << " CAFE INTERNAL ERROR: Unknown dataType: " << dt << " " << endl; returnVal[0]=0; break; } return (CTYPE *) returnVal; #undef __METHOD__ } /** * Converts from native type to CTYPE * \param index input: index to val array * \param dt input: CAFE_DATATYPE * \param val input: CAFE_DATATYPE_UNION_SEQ * \return CTYPE */ template CTYPE * CAFEConvert::get (unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val) { #define __METHOD__ "CAFEConvert::get(index, dt, val[])" switch (dt) { case CAFE_DOUBLE: returnVal[0]= (CTYPE) val[index].d; break; case CAFE_FLOAT: returnVal[0]= (CTYPE) val[index].f; break; case CAFE_LONG: returnVal[0]= (CTYPE) val[index].l; break; case CAFE_SHORT: returnVal[0]= (CTYPE) val[index].s; break; case CAFE_ENUM: returnVal[0]= (CTYPE) val[index].us; break; case CAFE_CHAR: returnVal[0]= (CTYPE) val[index].ch; break; case CAFE_STRING: returnVal[0]= (CTYPE) strtod( val[index].str, NULL); break; case CAFE_TYPENOTCONN: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_TYPENOTCONN: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NO_ACCESS: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_NO_ACCESS: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_INVALID_DATATYPE: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NOT_REQUESTED: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_NOT_REQUESTED: dataType: " << dt << " " << endl; returnVal[0]=0; break; case CAFE_NOT_SHOWN: //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ // << " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; returnVal[0]=0; break; default: cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << " CAFE INTERNAL ERROR: Unknown dataType: " << dt << " " << endl; returnVal[0]=0; break; } return (CTYPE *) returnVal; #undef __METHOD__ }; /** * Converts from DBR_ENUM type to CTYPE=STRING * \param index input: index to val array * \param noStr input: number of enumerations * \param val input: CAFE_DATATYPE_UNION_SEQ * \param stig input: stig[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE] an array of enum choices * \return CTYPE */ template CTYPE * CAFEConvert::getStringFromEnum (unsigned int index, unsigned int noStr, CAFE_DATATYPE_UNION_SEQ val, char stig[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]) { #define __METHOD__ "CAFEConvert::getStringFromEnum(indx, noStr, val, stig)" unsigned int noEmptyStrings=0; //Check for empty strings: for (unsigned int j=0; j= noStr) { cout << "*** WARNING FROM " << __METHOD__ << " *** " << endl; cout << "ENUM UNSIGNED SHORT VALUE IS GREATER THAN THE NO OF ENUMERATED TYPES" << endl; cout << "VALUE (unsigned short) = " << val[index].us << endl; cout << "NO OF ENUMERATED STRINGS = " << noStr << " WITH VALUES: " << endl; for (unsigned int j=0; j CTYPE * CAFEConvert::getString (unsigned int index, CAFE_DATATYPE dt, CAFE_DATATYPE_UNION_SEQ val) { #define __METHOD__ "CAFEConvert::getString(nelem, dt, val[])" switch (dt) { case CAFE_STRING: sprintf(returnVal[0], "%s", val[index].str); break; case CAFE_CHAR: sprintf(returnVal[0], "%u", val[index].ch); break; case CAFE_FLOAT: sprintf(returnVal[0], "%f", val[index].f); //floats offer a precision of 6 break; case CAFE_DOUBLE: sprintf(returnVal[0], "%.15f", val[index].d); //double offer a precicion of 15 break; case CAFE_SHORT: sprintf(returnVal[0], "%d", val[index].s); break; case CAFE_LONG: sprintf(returnVal[0], "%d", val[index].l); break; case CAFE_ENUM: sprintf(returnVal[0], "%u", val[index].us); break; case CAFE_TYPENOTCONN: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout << " ERROR CAFE_TYPENOTCONN: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //CAFE_TYPENOTCONN"); break; case CAFE_NO_ACCESS: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout << " CAFE_NO_ACCESS: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //"CAFE_NO_ACCESS"); break; case CAFE_INVALID_DATATYPE: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //"CAFE_INVALID_DATATYPE"); break; case CAFE_NOT_REQUESTED: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_NOT_REQUESTED: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //""); break; case CAFE_NOT_SHOWN: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_NOT_SHOWN: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); // "CAFE_NOT_SHOWN"); break; default: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE INTERNAL ERROR: Unknown dataType: "<< dt << " " << endl; sprintf(returnVal[0], "%s", "0");// "Unknown dataType"); break; } return (CTYPE *) returnVal; #undef __METHOD__ }; /** * Converts from native type to CTYPE=STRING * \param dt input: CAFE_DATATYPE * \param val CAFE_DATATYPE_UNION input * \return CTYPE */ template CTYPE * CAFEConvert::getString (CAFE_DATATYPE dt, CAFE_DATATYPE_UNION val) { #define __METHOD__ "CAFEConvert::getString(dt, val[])" switch (dt) { case CAFE_STRING: sprintf(returnVal[0], "%s", val.str); break; case CAFE_CHAR: sprintf(returnVal[0], "%u", val.ch); break; case CAFE_FLOAT: sprintf(returnVal[0], "%f", val.f); //floats offer a precision of 6 break; case CAFE_DOUBLE: sprintf(returnVal[0], "%.15f", val.d); //double offer a precicion of 15 break; case CAFE_SHORT: sprintf(returnVal[0], "%d", val.s); break; case CAFE_LONG: sprintf(returnVal[0], "%d", val.l); break; case CAFE_ENUM: sprintf(returnVal[0], "%u", val.us); break; case CAFE_TYPENOTCONN: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout << " ERROR CAFE_TYPENOTCONN: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //CAFE_TYPENOTCONN"); break; case CAFE_NO_ACCESS: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout << " CAFE_NO_ACCESS: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //"CAFE_NO_ACCESS"); break; case CAFE_INVALID_DATATYPE: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_INVALID_DATATYPE: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //"CAFE_INVALID_DATATYPE"); break; case CAFE_NOT_REQUESTED: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_NOT_REQUESTED: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); //""); break; case CAFE_NOT_SHOWN: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE_NOT_SHOWN: dataType: " << dt << " " << endl; sprintf(returnVal[0], "%s", "0"); // "CAFE_NOT_SHOWN"); break; default: //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //cout<< " CAFE INTERNAL ERROR: Unknown dataType: "<< dt << " " << endl; sprintf(returnVal[0], "%s", "0");// "Unknown dataType"); break; } return (CTYPE *) returnVal; #undef __METHOD__ }; #endif