/// /// \file transpose.h /// \author Jan Chrin, PSI /// \date Release: February 2015 /// \version CAFE 1.0.0 /// #ifndef TRANSPOSE_H #define TRANSPOSE_H #include #include #include #include /** * Transpose Template \n * CTYPE is the type of data to be rendered to/from the client \n * method get() will receive data transmitted by CA with dataTypeRequest \n * and then convert to CTYPE * method getString() will receive data transmitted by CA with dataTypeRequest \n * and then convert to a string * method put() will convert data of type CTYPE to the native type \n * and then transmit to CA * method putString() will convert a string type to the native type \n * and then transmit to CA */ template class Transpose { public: Transpose () {}; ~Transpose () {}; HandleHelper handleHelper; int put(const unsigned int _handle, const CTYPE * val, const chtype cdt); int put(const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt); int putString (const unsigned int _handle, dbr_string_t * val); int get( const unsigned int _handle, CTYPE * val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest); int get( //union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, CTYPE * val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, bool isCacheRequest) { epicsTimeStamp ts; alarmStatus =0; alarmSeverity =0; return get (//PVDataL, //channelRequestMetaDataClient, //channelRepositoryMetaData, _handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest); }; int get( //union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, CTYPE * val, bool isCacheRequest) { epicsTimeStamp ts; dbr_short_t alarmStatus; dbr_short_t alarmSeverity; ts.secPastEpoch=0; ts.nsec =0; alarmStatus =0; alarmSeverity =0; return get(//PVDataL, //channelRequestMetaDataClient, //channelRepositoryMetaData, _handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest); }; int getCtrl ( //const CAFEConduit &cc, union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, CTYPE * val, dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, dbr_short_t &precision, CTYPE &RISC_pad, CTYPE &upperDispLimit, CTYPE &lowerDispLimit, CTYPE &upperAlarmLimit, CTYPE &upperWarningLimit, CTYPE &lowerWarningLimit, CTYPE &lowerAlarmLimit, CTYPE &upperCtrlLimit, CTYPE &lowerCtrlLimit, char units[MAX_UNITS_SIZE], short &noStr, char strs [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE], bool isCacheRequest); private: CTYPE * val; int status; CAFEStatus cafeStatus; CAFEDataTypeCode cafeDataTypeCode; union db_access_val * PVDataL; unsigned int nelem; unsigned int offset; chtype dbrTypeRequest_DataBuffer; chtype dbrTypeRequest_CtrlBuffer; chtype _dataTypeClient; char stig [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Transpose Template Specialization for dbr_string_t char[40]\n */ template <> class Transpose { //dbr_string_t * val; public: Transpose () {}; ~Transpose () {}; int putString (const unsigned int _handle, dbr_string_t * val); int putString (const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val); //dbr_string_t * val); int get(//union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, dbr_string_t * val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest ); int get(//union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, dbr_string_t * val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, bool isCacheRequest ) { epicsTimeStamp ts; alarmStatus =0; alarmSeverity =0; return get (//PVDataL, //channelRequestMetaDataClient, //channelRepositoryMetaData, _handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest); }; int get(//union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, dbr_string_t * val, bool isCacheRequest) { epicsTimeStamp ts; dbr_short_t alarmStatus; dbr_short_t alarmSeverity; ts.secPastEpoch=0; ts.nsec =0; alarmStatus =0; alarmSeverity =0; return get ( //PVDataL, //channelRequestMetaDataClient, //channelRepositoryMetaData, _handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest ); }; int getCtrl(//const CAFEConduit & cc, const unsigned int _handle, dbr_string_t * val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, bool isCacheRequest ); private: int status; CAFEStatus cafeStatus; union db_access_val * PVDataL; unsigned int nelem; unsigned int offset; chtype dbrTypeRequest_DataBuffer; chtype dbrTypeRequest_CtrlBuffer; chtype _dataTypeClient; char stig [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Transpose Template Specialization for CAFE_DATATYPE_UNION_SEQ\n */ template <> class Transpose { // CAFE_DATATYPE_UNION_SEQ val; public: Transpose () {}; ~Transpose () {}; //long put(const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt); //long putString (const unsigned int _handle, dbr_string_t * val) { return ICAFE_NORMAL;} int get(//const CAFEConduit & cc, const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest); int get(//const CAFEConduit & cc, const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, dbr_short_t & alarmStatus, dbr_short_t &alarmSeverity, bool isCacheRequest) { epicsTimeStamp ts; alarmStatus =0; alarmSeverity =0; return get (_handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest); }; int get(//const CAFEConduit & cc, const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, bool isCacheRequest) { epicsTimeStamp ts; dbr_short_t alarmStatus; dbr_short_t alarmSeverity; ts.secPastEpoch=0; ts.nsec =0; alarmStatus =0; alarmSeverity =0; return get (_handle, val, alarmStatus, alarmSeverity, ts, isCacheRequest); }; private: int status; CAFEStatus cafeStatus; union db_access_val * PVDataL; unsigned int nelem; unsigned int offset; chtype dbrTypeRequest_DataBuffer; chtype _dataTypeClient; char stig [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; }; /** * \brief Transforms data from CTYPE * val to PutBuffer * \param _handle input: Conduit object * \param val input: CTYPE datatype * \param _dbrType input: chtype * \return ICAFE_NORMAL as local data conversion should not incur an error */ template int Transpose::put(const unsigned int _handle, const CTYPE * val, const chtype _dbrType) { #define __METHOD__ "Transpose::put(_handle, CTYPE * val, const chtype cdt)" status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getPutBuffer (); nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); //dbrTypeRequest_DataBuffer is the chtype used in ca_get //Only ever fille the Union with the native type as //Need to first check if this is really an enum!? if (dbrTypeRequest_DataBuffer==DBR_ENUM) { dbr_ctrl_enum * dataEnum = (dbr_ctrl_enum *) (*it_handle).getCtrlBuffer(); dbr_short_t noStrings = ((struct dbr_ctrl_enum *) dataEnum)->no_str; if(noStrings >0) { for (unsigned int i=0; i= noStrings ) { memcpy( stig, &(((struct dbr_ctrl_enum *) dataEnum)->strs), sizeof(stig )) ; std::cout << __FILE__ << "//" << __LINE__ << "//" <<__METHOD__ << std::endl; cafeStatus.report(ECAFE_INVALID_ENUM_INDEX); std::cout << val[i] << " is not a a valid enum index " << std::endl; std::cout << "VALID STRING [ENUM] OPTIONS ARE: " << std::endl; for (dbr_short_t ij=0; ij0 }//if switch (dbrTypeRequest_DataBuffer) { case DBR_STRING: // 0 switch(_dbrType) { case CAFE_SHORT: for (unsigned int i=0; i(&val[i])); } break; case CAFE_FLOAT: for (unsigned int i=0; i(&val[i])); } break; case CAFE_ENUM: for (unsigned int i=0; i(&val[i])); } break; case CAFE_CHAR: for (unsigned int i=0; i(&val[i])); } break; case CAFE_LONG: for (unsigned int i=0; i(&val[i])); } break; case CAFE_DOUBLE: for (unsigned int i=0; i(&val[i])); } break; case CAFE_STRING: memcpy( PVDataL, val, sizeof(dbr_string_t)*nelem); break; default: std::cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; cafeStatus.report(ECAFE_INVALID_SWITCH_CASE); std::cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <::put( const unsigned int _handle, // CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt) template int Transpose::put( const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt) { #define __METHOD__ "Transpose::put()" status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getPutBuffer (); nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); //dbrTypeRequest_DataBuffer is the chtype used in ca_get //Only ever fille the Union with the native type as dbr_ctrl_enum * dataEnum; dbr_short_t noStrings =0; switch (dbrTypeRequest_DataBuffer) { case DBR_STRING: // 0 switch(cdt) { case CAFE_SHORT: for (unsigned int i=0; i(&val[i].s)); } break; case CAFE_FLOAT: for (unsigned int i=0; i(&val[i].f)); } break; case CAFE_ENUM: for (unsigned int i=0; i(&val[i].us)); } break; case CAFE_CHAR: for (unsigned int i=0; i(&val[i].ch)); } break; case CAFE_LONG: for (unsigned int i=0; i(&val[i].l)); } break; case CAFE_DOUBLE: for (unsigned int i=0; i(&val[i].d)); } break; case CAFE_STRING: for (unsigned int i=0; i(&val[i].str)); //std::cout << "after " << *((dbr_string_t *) (PVDataL) + i) << std::endl; } break; default: std::cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; cafeStatus.report(ECAFE_INVALID_SWITCH_CASE); std::cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << cdt <no_str; memcpy( stig, &(((struct dbr_ctrl_enum *) dataEnum)->strs), sizeof(stig )) ; switch(cdt) { case CAFE_SHORT: for (unsigned int i=0; i= (dbr_enum_t) noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_FLOAT: //2 for (unsigned int i=0; i= (dbr_enum_t) noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_ENUM: //3 for (unsigned int i=0; i= (dbr_enum_t) noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_CHAR: //4 for (unsigned int i=0; i= (dbr_enum_t) noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_LONG: //5 for (unsigned int i=0; i= (dbr_enum_t)noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_DOUBLE: //6 for (unsigned int i=0; i= (dbr_enum_t)noStrings) { status=ECAFE_INVALID_ENUM_INDEX; } } break; case CAFE_STRING: //0 status=putString(_handle, (dbr_string_t *) val); break; default: std::cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; cafeStatus.report(ECAFE_INVALID_SWITCH_CASE); std::cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << cdt < int Transpose::putString (const unsigned int _handle, dbr_string_t * val) { #define __METHOD__ "Transpose::putString" cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getPutBuffer (); nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); dbr_ctrl_enum * dataEnum; dbr_short_t noStrings =0; bool allStringsAreValid=true; // Client is String // Native type is one of the following std::istringstream ss; switch(dbrTypeRequest_DataBuffer) { case DBR_STRING://0 for (unsigned int i=0; i>s; if ( !ss.fail()) { *((dbr_short_t *) (PVDataL) + i ) = s; } else { std::cout << __METHOD__ << __LINE__ << std::endl; std::cout << "***WARNING*** NO STRING TO DBR_SHORT CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << std::endl; std::cout << "***WARNING*** COULD NOT CONVERT: "; std::cout << val[i]; std::cout << " TO SHORT; PUT REQUEST NOT MADE!" << std::endl; //AT THE MERCY OF THE CA SERVER!" << std::endl; //NOT MADE!" << std::endl; allStringsAreValid=false; } } break; case DBR_FLOAT://2 for (unsigned int i=0; i>f; if ( !ss.fail()) { *((dbr_float_t *) (PVDataL) + i ) = f; } else { std::cout << __METHOD__ << __LINE__ << std::endl; std::cout << "***WARNING*** NO STRING TO DBR_FLOAT CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << std::endl; std::cout << "***WARNING*** COULD NOT CONVERT: "; std::cout << val[i]; std::cout << " TO FLOAT; PUT REQUEST NOT MADE!" << std::endl; //AT THE MERCY OF THE CA SERVER!" << std::endl; //NOT MADE! " << std::endl; allStringsAreValid=false; } } break; case DBR_ENUM: //3 // CHANGE THE STRING TO CORRESPONDING ENUM! dataEnum = (dbr_ctrl_enum *) (*it_handle).getCtrlBuffer(); noStrings = ((struct dbr_ctrl_enum *) dataEnum)->no_str; memcpy( stig, &(((struct dbr_ctrl_enum *) dataEnum)->strs), sizeof(stig )) ; for (unsigned int i=0; i= b) { if (*c == ' ') { *c = '\0'; // This was reported at www.programmingforums.org/thread35790.html to cause a bus error!? } else { break; } c--; } sprintf(a, "%s", b); */ bool isValidString=false; for (int j=0; j>us; // Is this a valid number? if ( !ss.fail()) { if (us==0 || (us>0 && us >ch; char *b = (char *) val[i]; if ( !ss.fail()) { *((dbr_char_t *) (PVDataL) + i ) = ch; } else if (*b != '\0') { *((dbr_char_t *) (PVDataL) + i ) = *b; } else { std::cout << __FILE__ << "//" << __METHOD__ << "//" << __LINE__ << std::endl; std::cout << "***WARNING*** NO STRING TO DBR_CHAR CONVERSION for ELEMENT index " << i << " in array of length " << nelem; std::cout << ", i.e., with index range [0-" << (nelem-1) << "] " << " !! " << std::endl; std::cout << "***WARNING*** COULD NOT CONVERT: "; std::cout << val[i]; std::cout << " TO UNSIGNED CHAR; PUT REQUEST NOT MADE!" << std::endl; //AT THE MERCY OF THE CA SERVER!" << std::endl; //NOT MADE!" << std::endl; allStringsAreValid=false; } } break; case DBR_LONG: //5 for (unsigned int i=0; i>l; if ( !ss.fail()) { *((dbr_long_t *) (PVDataL) + i ) = l; } else { std::cout << __METHOD__ << __LINE__ << std::endl; std::cout << "***WARNING*** NO STRING TO DBR_LONG CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << std::endl; std::cout << "***WARNING*** COULD NOT CONVERT: "; std::cout << val[i]; std::cout << " TO LONG; PUT REQUEST NOT MADE!" << std::endl; //AT THE MERCY OF THE CA SERVER!" << std::endl; //NOT MADE!" << std::endl; allStringsAreValid=false; } } break; case DBR_DOUBLE: //6 for (unsigned int i=0; i>d; if ( !ss.fail()) { *((dbr_double_t *) (PVDataL) + i ) = d; } else { std::cout << __METHOD__ << __LINE__ << std::endl; std::cout << "***WARNING*** NO STRING TO DBR_DOUBLE CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << std::endl; std::cout << "***WARNING*** COULD NOT CONVERT: "; std::cout << val[i]; std::cout << " TO DOUBLE; PUT REQUEST NOT MADE!" << std::endl; //AT THE MERCY OF THE CA SERVER!" << std::endl; //PUT REQUEST NOT MADE!" << std::endl; allStringsAreValid=false; } }//for break; } //switch if(!allStringsAreValid) { if (status==ECAFE_INVALID_ENUM_INDEX) { return status; } return ECAFE_NO_CONVERT; } else { return ICAFE_NORMAL; } } else { cafeStatus.report(ECAFE_INVALID_HANDLE); return ECAFE_INVALID_HANDLE; } return ICAFE_NORMAL; #undef __METHOD__ } /** * \brief Retrieves data transmitted by CA with dbrTypeRequest_DataBuffer * and then converts to CTYPE i.e. _dataTypeClient * \param _handle input: handle to Conduit object * \param val output: CTYPE datatype * \param alarmStatus output: dbr_short_t * \param alarmSeverity output: dbr_short_t * \param ts output: epicsTimeStamp * \param isCacheRequest input: bool * \return ICAFE_NORMAL as local data conversion should not incur an error **/ template int Transpose::get( const unsigned int _handle, CTYPE * val, dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest) { #define __METHOD__ "Transpose::get()" cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); //std::cout << __FILE__ << "//" << __METHOD__ << std::endl; if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getDataBuffer(); offset = (*it_handle).getChannelRequestMetaDataClient().getOffset(); //std::cout << "offset client " << offset << std::endl; //std::cout << "offset client too...... " << handleHelper.getOffset(_handle) << std::endl; //std::cout << "offsetLast ...... " << handleHelper.getOffsetLast(_handle) << std::endl; // Difference between using cache and not // when not cache offset is that requested by client.. // when not cache nelem is no of elements requested by client plus the offset requested by client // when cache offset is actual offset in last transaction // when cache nelem is no of elements from cache if(isCacheRequest) { offset = (*it_handle).getChannelRequestMetaData().getOffset( ); // equivalent to handleHelper.getOffsetLast(_handle); nelem = (*it_handle).getChannelRequestMetaData().getNelemCache();// + offset; // not (*it_handle).getChannelRequestMetaData().getOffset() //Could be that the number of elements in the data buffer is actually less! //std::cout << "nelem1 + data offset " << nelem << " " << (*it_handle).getChannelRequestMetaData().getNelemCache() << " + " << //(*it_handle).getChannelRequestMetaData().getOffset() << std::endl; //nelem = min(nelem, (*it_handle).getChannelRequestMetaData().getNelemCache()+ offset); //std::cout << "nelem2 " << nelem << " " << (*it_handle).getChannelRequestMetaData().getNelemCache() << " + " << offset << std::endl; //std::cout << __METHOD__ << __LINE__ << std::endl; //std::cout << "nelem = " << (*it_handle).getChannelRequestMetaData().getNelem() << std::endl; //std::cout << "nelemCache = " << (*it_handle).getChannelRequestMetaData().getNelemCache() << std::endl; //std::cout << "offset = " << (*it_handle).getChannelRequestMetaData().getOffset() << std::endl; //std::cout << "offsetLast ...... " << handleHelper.getOffsetLast(_handle) << std::endl; //std::cout << "nelem = " << nelem << std::endl; } else { nelem = (*it_handle).getChannelRequestMetaData().getNelem()-offset; //std::cout << __METHOD__ << " nelem " << nelem << std::endl; //std::cout << "getChannelRequestMetaData().getNelem()=" << (*it_handle).getChannelRequestMetaData().getNelem() << std::endl; //std::cout << "getChannelRequestMetaDataClient().offset " << offset << std::endl; } //Something wrong, just read last element if (nelem <=0) { std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; std::cout << "Something funny with the offset; hence will read last element only!"<< std::endl; std::cout << "Changing offset from=" << offset; offset = (*it_handle).getChannelRequestMetaData().getNelem()-1; if(isCacheRequest) { //this does not mean much for cache nelem = (*it_handle).getChannelRequestMetaData().getNelemCache(); //(*it_handle).getChannelRequestMetaData().getOffset(); //add offset for cache } else { nelem = (*it_handle).getChannelRequestMetaData().getNelem()-offset; } std::cout << " to=" << offset << std::endl; } dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaData().getDbrDataType(); _dataTypeClient = (*it_handle).getChannelRequestMetaDataClient().getDataType(); //if (_handle==1) { // _dataTypeClient=DBR_FLOAT; //} //std::cout << "WHAT IS ON THE DATA BUFFER = " << dbrTypeRequest_DataBuffer << std::endl; //std::cout << "WHAT THE CLIENT WANTS = " << _dataTypeClient << std::endl; ////dbr_string_t * val2 = new dbr_string_t[nelem]; ts.secPastEpoch=0; ts.nsec =0; alarmStatus =-1; alarmSeverity =-1; //This will happen for DBF_NO_ACCESS = 7 // in which case do not use dbr_type_to_text !! if (_dataTypeClient < DBR_STRING || _dataTypeClient > DBR_DOUBLE) { std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; std::cout << "Datatype requested " << dbr_type_to_text(_dataTypeClient) << " is not within allowed range: " << std::endl; std::cout << "DBR_STRING <= dataType <= DBR_DOUBLE" << std::endl; std::cout << "CAFE ERROR: ECAFE_INVALID_SWITCH_CASE" << std::endl; return ECAFE_INVALID_SWITCH_CASE; } //dbrTypeRequest_DataBuffer is the chtype used in ca_get //_dataTypeCLient is the chtype requested by client switch (dbrTypeRequest_DataBuffer) { case DBR_CHAR: switch(_dataTypeClient) { case DBR_CHAR: memcpy( val, &(&((PVDataL)->charval))[offset], sizeof(dbr_char_t)*nelem); break; default: for (unsigned int i=0; icharval)+i+offset)); } break; } break; case DBR_FLOAT: switch(_dataTypeClient) { case DBR_FLOAT: memcpy( val, &(&((PVDataL)->fltval))[offset], sizeof(dbr_float_t)*nelem); break; default: for (unsigned int i=0; ifltval)+i+offset)); } break; } break; case DBR_DOUBLE: switch(_dataTypeClient) { case DBR_DOUBLE: memcpy( val, &(&((PVDataL)->doubleval))[offset], sizeof(dbr_double_t)*nelem); break; default: for (unsigned int i=0; idoubleval)+i+offset)); } break; } break; case DBR_SHORT: switch(_dataTypeClient) { case DBR_SHORT: memcpy( val, &(&((PVDataL)->shrtval))[offset], sizeof(dbr_short_t)*nelem); break; default: for (unsigned int i=0; ishrtval)+i+offset)); } break; } break; case DBR_LONG: switch(_dataTypeClient) { case DBR_LONG: memcpy( val, &(&((PVDataL)->longval))[offset], sizeof(dbr_long_t)*nelem); break; default: for (unsigned int i=0; ilongval)+i+offset)); } break; } break; case DBR_ENUM: switch(_dataTypeClient) { case DBR_ENUM: memcpy( val, &(&((PVDataL)->enmval))[offset], sizeof(dbr_enum_t)*nelem); break; default: for (unsigned int i=0; ienmval)+i+offset)); } break; } break; case DBR_STRING: switch(_dataTypeClient) { case DBR_STRING: memcpy( val, &(&((PVDataL)->strval))[offset], sizeof(dbr_string_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: for (unsigned int i=0; istrval)+i+offset)), NULL, 0); } break; case DBR_FLOAT: case DBR_DOUBLE: default: // If no valid conversion could be performed, the function returns zero (0.0). for (unsigned int i=0; istrval)+i+offset)), NULL); } break; } break; case DBR_STS_CHAR: switch(_dataTypeClient) { case DBR_CHAR: memcpy( val, &(&((PVDataL)->schrval.value))[offset], sizeof(dbr_char_t)*nelem); break; default: for (unsigned int i=0; ischrval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_char *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_char *) PVDataL)->severity; break; case DBR_STS_FLOAT: switch(_dataTypeClient) { case DBR_FLOAT: memcpy( val, &(&((PVDataL)->sfltval.value))[offset], sizeof(dbr_float_t)*nelem); break; default: for (unsigned int i=0; isfltval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_float *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_float *) PVDataL)->severity; break; case DBR_STS_DOUBLE: switch(_dataTypeClient) { case DBR_DOUBLE: memcpy( val, &(&((PVDataL)->sdblval.value))[offset], sizeof(dbr_double_t)*nelem); break; default: for (unsigned int i=0; isdblval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_double *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_double *) PVDataL)->severity; break; case DBR_STS_SHORT: switch(_dataTypeClient) { case DBR_SHORT: memcpy( val, &(&((PVDataL)->sshrtval.value))[offset], sizeof(dbr_short_t)*nelem); break; default: for (unsigned int i=0; isshrtval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_short *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_short *) PVDataL)->severity; break; case DBR_STS_LONG: switch(_dataTypeClient) { case DBR_LONG: memcpy( val, &(&((PVDataL)->slngval.value))[offset], sizeof(dbr_long_t)*nelem); break; default: for (unsigned int i=0; islngval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_long *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_long *) PVDataL)->severity; break; case DBR_STS_ENUM: switch(_dataTypeClient) { case DBR_ENUM: memcpy( val, &(&((PVDataL)->senmval.value))[offset], sizeof(dbr_enum_t)*nelem); break; default: for (unsigned int i=0; isenmval.value)+i+offset)); } break; } alarmStatus = ((struct dbr_sts_enum *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_enum *) PVDataL)->severity; break; case DBR_STS_STRING: switch(_dataTypeClient) { case DBR_STRING: memcpy( val, &(&((PVDataL)->sstrval.value))[offset], sizeof(dbr_string_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: for (unsigned int i=0; isstrval.value)+i+offset)), NULL, 0); } break; case DBR_FLOAT: case DBR_DOUBLE: default: for (unsigned int i=0; isstrval.value)+i+offset)), NULL); } break; } alarmStatus = ((struct dbr_sts_string *) PVDataL)->status; alarmSeverity = ((struct dbr_sts_string *) PVDataL)->severity; break; case DBR_TIME_CHAR: switch(_dataTypeClient) { case DBR_CHAR: memcpy( val, &(&((PVDataL)->tchrval.value))[offset], sizeof(dbr_char_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_FLOAT: case DBR_DOUBLE: default: for (unsigned int i=0; itchrval.value)+i+offset)); } break; // strings are handled by getString - but are handled HERE when calling getCache()!! //case DBR_STRING: // for (unsigned int i=0; itchrval.value)+i))); } ts = ((struct dbr_time_char *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_char *) PVDataL)->status; alarmSeverity = ((struct dbr_time_char *) PVDataL)->severity; break; case DBR_TIME_FLOAT: switch(_dataTypeClient) { case DBR_FLOAT: memcpy( val, &(&((PVDataL)->tfltval.value))[offset], sizeof(dbr_float_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_DOUBLE: default: //std::cout << __FILE__ << "//" << __METHOD__ << std::endl; //std::cout << "offset=" << offset << " nelem= " << nelem << std::endl; for (unsigned int i=0; itfltval.value)+i+offset)); } break; } ts = ((struct dbr_time_float *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_float *) PVDataL)->status; alarmSeverity = ((struct dbr_time_float *) PVDataL)->severity; break; case DBR_TIME_DOUBLE: switch(_dataTypeClient) { case DBR_DOUBLE: memcpy( val, &(&((PVDataL)->tdblval.value))[offset], sizeof(dbr_double_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: default: for (unsigned int i=0; itdblval.value)+i+offset)); } break; } ts = ((struct dbr_time_double *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_double *) PVDataL)->status; alarmSeverity = ((struct dbr_time_double *) PVDataL)->severity; break; case DBR_TIME_SHORT: switch(_dataTypeClient) { case DBR_SHORT: memcpy( val, &(&((PVDataL)->tshrtval.value))[offset], sizeof(dbr_short_t)*nelem); break; case DBR_DOUBLE: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: default: for (unsigned int i=0; itshrtval.value)+i+offset)); } break; //case DBR_STRING: // for (unsigned int i=0; itshrtval.value)+i))); } ts = ((struct dbr_time_short *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_short *) PVDataL)->status; alarmSeverity = ((struct dbr_time_short *) PVDataL)->severity; break; case DBR_TIME_LONG: switch(_dataTypeClient) { case DBR_LONG: memcpy( val, &(&((PVDataL)->tlngval.value))[offset], sizeof(dbr_long_t)*nelem); break; case DBR_DOUBLE: case DBR_SHORT: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: default: for (unsigned int i=0; itlngval.value)+i+offset)); } break; //case DBR_STRING: // for (unsigned int i=0; itlngval.value)+i))); //break; } ts = ((struct dbr_time_long *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_long *) PVDataL)->status; alarmSeverity = ((struct dbr_time_long *) PVDataL)->severity; break; case DBR_TIME_ENUM: switch(_dataTypeClient) { case DBR_ENUM: memcpy( val, &(&((PVDataL)->tenmval.value))[offset], sizeof(dbr_enum_t)*nelem); break; case DBR_DOUBLE: case DBR_SHORT: case DBR_LONG: case DBR_CHAR: case DBR_FLOAT: default: for (unsigned int i=0; itenmval.value)+i+offset)); } break; //case DBR_STRING: // for (unsigned int i=0; itenmval.value)+i))); //break; } ts = ((struct dbr_time_enum *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_enum *) PVDataL)->status; alarmSeverity = ((struct dbr_time_enum *) PVDataL)->severity; break; case DBR_TIME_STRING: default: switch(_dataTypeClient) { case DBR_STRING: //DEFINE stringf array then copy to CTYPE memcpy( val, &(&((PVDataL)->tstrval.value))[offset], sizeof(dbr_string_t)*nelem); //for (unsigned int i=0; itstrval.value)+i+offset)), NULL, 0); } break; case DBR_FLOAT: case DBR_DOUBLE: default: for (unsigned int i=0; itstrval.value)+i+offset)), NULL); } break; } ts = ((struct dbr_time_string *) PVDataL)->stamp; alarmStatus = ((struct dbr_time_string *) PVDataL)->status; alarmSeverity = ((struct dbr_time_string *) PVDataL)->severity; break; } //helper function to set TimeStamps! //std::cout <<__METHOD__ << std::endl; //std::cout << "_dbrType" << _dbrTypeRequest_DataBuffer<< std::endl; //std::cout << ts.secPastEpoch << " " << ts.nsec << std::endl; if(!isCacheRequest) { handleHelper.setSTS(_handle, alarmStatus, alarmSeverity, ts); } ////delete [] val2; } else { cafeStatus.report(ECAFE_INVALID_HANDLE); return ECAFE_INVALID_HANDLE; } return ICAFE_NORMAL; #undef __METHOD__ } /** * \brief Retrieves ctrl data from buffer * \param _handle input: handle to Conduit Object * \param val output: CTYPE * \param alarmStatus output: dbr_short_t * \param alarmSeverity output: dbr_short_t * \param precision output: dbr_short_t * \param RISC_pad deprecated! * \param upperDispLimit output * \param lowerDispLimit output * \param upperAlarmLimit output * \param upperWarningLimit output * \param lowerWarningLimit output * \param lowerAlarmLimit output * \param upperCtrlLimit output * \param lowerCtrlLimit output * \param units output: units * \param noStr output: No of ENUM Choices * \param strs output: ENUM Choices * \param isCacheRequest input: bool true or false * \return ICAFE_NORMAL */ template int Transpose::getCtrl ( //const CAFEConduit &cc, union db_access_val * PVDataL, //ChannelRequestMetaDataClient channelRequestMetaDataClient, //ChannelRepositoryMetaData channelRepositoryMetaData, const unsigned int _handle, CTYPE * val, dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, dbr_short_t &precision, CTYPE &RISC_pad, CTYPE &upperDispLimit, CTYPE &lowerDispLimit, CTYPE &upperAlarmLimit, CTYPE &upperWarningLimit, CTYPE &lowerWarningLimit, CTYPE &lowerAlarmLimit, CTYPE &upperCtrlLimit, CTYPE &lowerCtrlLimit, char units[MAX_UNITS_SIZE], short &noStr, char strs [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE], bool isCacheRequest) { #define __METHOD__ "Transpose::getCtrl()" cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getCtrlBuffer (); offset = (*it_handle).getChannelRequestMetaCtrlClient().getOffset(); if(isCacheRequest) { offset = (*it_handle).getChannelRequestMetaCtrl().getOffset( ); nelem = (*it_handle).getChannelRequestMetaCtrl().getNelemCache();; // + (*it_handle).getChannelRequestMetaCtrl().getOffset(); //nelem = min(nelem, (*it_handle).getChannelRequestMetaCtrl().getNelem() + offset); } else { nelem = (*it_handle).getChannelRequestMetaCtrl().getNelem()-offset; } //Something wrong, just read last element if (nelem <=0) { std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; std::cout << "Something funny with the offset; just read last element! " << std::endl; std::cout << "Changing offset from=" << offset; offset = (*it_handle).getChannelRequestMetaCtrl().getNelem()-1; if(isCacheRequest) { nelem = (*it_handle).getChannelRequestMetaCtrl().getNelemCache(); // + (*it_handle).getChannelRequestMetaCtrl().getOffset(); //-offset; } else { nelem = (*it_handle).getChannelRequestMetaCtrl().getNelem()-offset; } std::cout << " to=" << offset << std::endl; } dbrTypeRequest_CtrlBuffer = (*it_handle).getChannelRequestMetaCtrl().getDbrDataType(); _dataTypeClient = (*it_handle).getChannelRequestMetaDataClient().getDataType(); alarmStatus = -1; alarmSeverity = -1; if (_dataTypeClient < DBR_STRING || _dataTypeClient > DBR_DOUBLE) { std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; std::cout << "Datatype requested " << dbr_type_to_text(_dataTypeClient) << " is not within allowed range: " << std::endl; std::cout << "DBR_STRING <= dataType <= DBR_DOUBLE" << std::endl; std::cout << "CAFE ERROR: ECAFE_INVALID_SWITCH_CASE" << std::endl; return ECAFE_INVALID_SWITCH_CASE; } noStr=0; //std::cout << __METHOD__ << std::endl; //std::cout << " dbrTypeRequest_CtrlBuffer " << dbrTypeRequest_CtrlBuffer << std::endl; //std::cout << " _dataTypeClient " << _dataTypeClient << std::endl; switch (dbrTypeRequest_CtrlBuffer) { case DBR_CTRL_CHAR: switch(_dataTypeClient) { case DBR_CHAR: memcpy(val, &(&((PVDataL)->cchrval.value))[offset], sizeof(dbr_char_t)*nelem); break; case DBR_DOUBLE: case DBR_SHORT: case DBR_ENUM: case DBR_LONG: case DBR_FLOAT: for (unsigned int i=0; icchrval.value)+i+offset)); } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = 0; // struct dbr_ctrl_char does not have the precision member RISC_pad = ((struct dbr_ctrl_char *) PVDataL)->RISC_pad; alarmStatus = ((struct dbr_ctrl_char *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_char *) PVDataL)->severity; memcpy(units, &(((struct dbr_ctrl_char *) PVDataL)->units), sizeof(char[MAX_UNITS_SIZE])); upperDispLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->upper_disp_limit; lowerDispLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->lower_disp_limit; upperAlarmLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->upper_alarm_limit; upperWarningLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->upper_warning_limit; lowerWarningLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->lower_warning_limit; lowerAlarmLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->lower_alarm_limit; upperCtrlLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->upper_ctrl_limit; lowerCtrlLimit = (CTYPE) ((struct dbr_ctrl_char *) PVDataL)->lower_ctrl_limit; break; case DBR_CTRL_ENUM: switch(_dataTypeClient) { case DBR_ENUM: memcpy(val, &(&((PVDataL)->cenmval.value))[offset], sizeof(dbr_enum_t)*nelem); //for (unsigned int i=0; icenmval.value)+i)); } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = 0; // struct dbr_ctrl_enum does not have the precision member RISC_pad = 0; // struct dbr_ctrl_char does not have the RISC_pad member alarmStatus = ((struct dbr_ctrl_enum *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_enum *) PVDataL)->severity; noStr = ((struct dbr_ctrl_enum *) PVDataL)->no_str; memcpy(strs, &(((struct dbr_ctrl_enum *) PVDataL)->strs), sizeof(char)*MAX_ENUM_STRING_SIZE*MAX_ENUM_STATES); //for (unsigned int i=0; icfltval.value))[offset], sizeof(dbr_float_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_DOUBLE: for (unsigned int i=0; icfltval.value)+i+offset)) ; } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = ((struct dbr_ctrl_float *) PVDataL)->precision; RISC_pad = ((struct dbr_ctrl_float *) PVDataL)->RISC_pad; //std::std::cout << " RISC_PAD " << ((struct dbr_ctrl_float *) PVDataL)->RISC_pad << std::std::endl; //std::std::cout << " RISC_PAD " << (short) ((struct dbr_ctrl_float *) PVDataL)->RISC_pad << std::std::endl; alarmStatus = ((struct dbr_ctrl_float *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_float *) PVDataL)->severity; memcpy(units, &(((struct dbr_ctrl_float *) PVDataL)->units), sizeof(char[MAX_UNITS_SIZE])); upperDispLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->upper_disp_limit; lowerDispLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->lower_disp_limit; upperAlarmLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->upper_alarm_limit; upperWarningLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->upper_warning_limit; lowerWarningLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->lower_warning_limit; lowerAlarmLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->lower_alarm_limit; upperCtrlLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->upper_ctrl_limit; lowerCtrlLimit = (CTYPE) ((struct dbr_ctrl_float *) PVDataL)->lower_ctrl_limit; //std::cout << "upperCtrlLimit= " << upperCtrlLimit << " upperDispLimit=" << upperDispLimit << std::endl; // std::cout << "value " << val[0] << std::endl; break; case DBR_CTRL_DOUBLE: switch(_dataTypeClient) { case DBR_DOUBLE: memcpy(val, &(&((PVDataL)->cdblval.value))[offset], sizeof(dbr_double_t)*nelem); break; case DBR_SHORT: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: for (unsigned int i=0; icdblval.value)+i+offset)); } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = ((struct dbr_ctrl_double *) PVDataL)->precision; RISC_pad = (short) ((struct dbr_ctrl_double *) PVDataL)->RISC_pad0; //short alarmStatus = ((struct dbr_ctrl_double *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_double *) PVDataL)->severity; memcpy(units, &(((struct dbr_ctrl_double *) PVDataL)->units), sizeof(char[MAX_UNITS_SIZE])); upperDispLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->upper_disp_limit; lowerDispLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->lower_disp_limit; upperAlarmLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->upper_alarm_limit; upperWarningLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->upper_warning_limit; lowerWarningLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->lower_warning_limit; lowerAlarmLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->lower_alarm_limit; upperCtrlLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->upper_ctrl_limit; lowerCtrlLimit = (CTYPE) ((struct dbr_ctrl_double *) PVDataL)->lower_ctrl_limit; break; case DBR_CTRL_SHORT: switch(_dataTypeClient) { case DBR_SHORT: memcpy(val, &(&((PVDataL)->cshrtval.value))[offset], sizeof(dbr_short_t)*nelem); break; case DBR_DOUBLE: case DBR_LONG: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: for (unsigned int i=0; icshrtval.value)+i+offset)); } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = 0; // struct dbr_ctrl_shrt does not have the precision member RISC_pad = 0; // struct dbr_ctrl_shrt does not have the RISC_pad member alarmStatus = ((struct dbr_ctrl_short *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_short *) PVDataL)->severity; memcpy(units, &(((struct dbr_ctrl_short *) PVDataL)->units), sizeof(char[MAX_UNITS_SIZE])); upperDispLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->upper_disp_limit; lowerDispLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->lower_disp_limit; upperAlarmLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->upper_alarm_limit; upperWarningLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->upper_warning_limit; lowerWarningLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->lower_warning_limit; lowerAlarmLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->lower_alarm_limit; upperCtrlLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->upper_ctrl_limit; lowerCtrlLimit = (CTYPE) ((struct dbr_ctrl_short *) PVDataL)->lower_ctrl_limit; break; case DBR_CTRL_LONG: switch(_dataTypeClient) { case DBR_LONG: memcpy(val, &(&((PVDataL)->clngval.value))[offset], sizeof(dbr_long_t)*nelem); break; case DBR_DOUBLE: case DBR_SHORT: case DBR_ENUM: case DBR_CHAR: case DBR_FLOAT: for (unsigned int i=0; iclngval.value)+i+offset)); } break; // strings are handled by a specialized template case DBR_STRING: default: break; } precision = 0; // struct dbr_ctrl_long does not have the precision member RISC_pad = 0; // struct dbr_ctrl_long does not have the RISC_pad member alarmStatus = ((struct dbr_ctrl_long *) PVDataL)->status; alarmSeverity = ((struct dbr_ctrl_long *) PVDataL)->severity; memcpy(units, &(((struct dbr_ctrl_long *) PVDataL)->units),sizeof(char[MAX_UNITS_SIZE])) ; upperDispLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->upper_disp_limit; lowerDispLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->lower_disp_limit; upperAlarmLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->upper_alarm_limit; upperWarningLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->upper_warning_limit; lowerWarningLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->lower_warning_limit; lowerAlarmLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->lower_alarm_limit; upperCtrlLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->upper_ctrl_limit; lowerCtrlLimit = (CTYPE) ((struct dbr_ctrl_long *) PVDataL)->lower_ctrl_limit; break; } } else { cafeStatus.report(ECAFE_INVALID_HANDLE); return ECAFE_INVALID_HANDLE; } return ICAFE_NORMAL; #undef __METHOD__ } #endif // TRANSPOSE_H