2160 lines
82 KiB
C++
2160 lines
82 KiB
C++
///
|
|
/// \file transpose.h
|
|
/// \author Jan Chrin, PSI
|
|
/// \date Release: February 2015
|
|
/// \version CAFE 1.0.0
|
|
///
|
|
|
|
#ifndef TRANSPOSE_H
|
|
#define TRANSPOSE_H
|
|
|
|
#include <cadef.h>
|
|
#include <global.h>
|
|
#include <statusCodes.h>
|
|
#include <handleHelper.h>
|
|
|
|
using namespace std;
|
|
|
|
/**
|
|
* 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 CTYPE> 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> {
|
|
//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> {
|
|
// 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 <class CTYPE> int Transpose<CTYPE>::put(const unsigned int _handle,
|
|
const CTYPE * val, const chtype _dbrType)
|
|
{
|
|
#define __METHOD__ "Transpose<CTYPE>::put(_handle, CTYPE * val, const chtype cdt)"
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
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<nelem; ++i) {
|
|
|
|
if ( (dbr_enum_t) val[i] >= noStrings ) {
|
|
|
|
memcpy( stig, &(((struct dbr_ctrl_enum *) dataEnum)->strs), sizeof(stig )) ;
|
|
|
|
|
|
cout << __FILE__ << "//" << __LINE__ << "//" <<__METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_ENUM_INDEX);
|
|
cout << val[i] << " is not a a valid enum index " << endl;
|
|
cout << "VALID STRING [ENUM] OPTIONS ARE: " << endl;
|
|
for (dbr_short_t ij=0; ij<noStrings; ++ij) {
|
|
cout << "'" << stig[ij] << "' " << "[" << ij << "]" << "; ";
|
|
}
|
|
cout << endl;
|
|
return ECAFE_INVALID_ENUM_INDEX;
|
|
} //if
|
|
}//for
|
|
}//if noStrings>0
|
|
|
|
}//if
|
|
|
|
switch (dbrTypeRequest_DataBuffer)
|
|
{
|
|
case DBR_STRING: // 0
|
|
switch(_dbrType){
|
|
case CAFE_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ),
|
|
"%d", *reinterpret_cast<const short*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_FLOAT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%f", *reinterpret_cast<const float*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_ENUM:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%u", *reinterpret_cast<const unsigned short*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_CHAR:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%u", *reinterpret_cast<const char*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_LONG:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%d", *reinterpret_cast<const int*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_DOUBLE:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%.15f", *reinterpret_cast<const double*>(&val[i]));
|
|
}
|
|
break;
|
|
case CAFE_STRING:
|
|
memcpy( PVDataL, val, sizeof(dbr_string_t)*nelem);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case DBR_SHORT: // 1
|
|
switch(_dbrType) {
|
|
case DBR_SHORT:
|
|
memcpy( PVDataL, val, sizeof(dbr_short_t)*nelem);
|
|
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = (dbr_short_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = (dbr_short_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = (dbr_short_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = (dbr_short_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = (dbr_short_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
case DBR_FLOAT: // 2
|
|
switch(_dbrType) {
|
|
case DBR_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = (dbr_float_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
memcpy( PVDataL, val, sizeof(dbr_float_t)*nelem);
|
|
|
|
break;
|
|
case DBR_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = (dbr_float_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = (dbr_float_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = (dbr_float_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = (dbr_float_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
case DBR_ENUM: // 3
|
|
|
|
|
|
switch(_dbrType) {
|
|
case DBR_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = (dbr_enum_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = (dbr_enum_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_ENUM: //3
|
|
memcpy( PVDataL, val, sizeof(dbr_enum_t)*nelem);
|
|
|
|
break;
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = (dbr_enum_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = (dbr_enum_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = (dbr_enum_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case DBR_CHAR: // 4
|
|
switch(_dbrType) {
|
|
case DBR_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_char_t *) (PVDataL) + i ) = (dbr_char_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_char_t *) (PVDataL) + i ) = (dbr_char_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_char_t *) (PVDataL) + i ) = (dbr_char_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_CHAR: //4
|
|
memcpy( PVDataL, val, sizeof(dbr_char_t)*nelem);
|
|
|
|
break;
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_char_t *) (PVDataL) + i ) = (dbr_char_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_char_t *) (PVDataL) + i ) = (dbr_char_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case DBR_LONG: // 5
|
|
switch(_dbrType) {
|
|
case DBR_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = (dbr_long_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = (dbr_long_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = (dbr_long_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = (dbr_long_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_LONG: //5
|
|
memcpy( PVDataL, val, sizeof(dbr_long_t)*nelem);
|
|
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = (dbr_long_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case DBR_DOUBLE: // 6
|
|
|
|
|
|
|
|
switch(_dbrType) {
|
|
|
|
case DBR_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = (dbr_double_t) val[i] ;
|
|
}
|
|
|
|
break;
|
|
|
|
case DBR_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = (dbr_double_t) val[i] ;
|
|
}
|
|
|
|
|
|
break;
|
|
case DBR_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = (dbr_double_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = (dbr_double_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = (dbr_double_t) val[i] ;
|
|
}
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
|
|
memcpy( PVDataL, val, sizeof(dbr_double_t)*nelem);
|
|
|
|
|
|
|
|
break;
|
|
case DBR_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << _dbrType <<endl;
|
|
cout << cafeDataTypeCode.message(_dbrType) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR DATATYPE=" << dbrTypeRequest_DataBuffer <<endl;
|
|
cout << cafeDataTypeCode.message(dbrTypeRequest_DataBuffer) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
#undef __METHOD__
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Transforms data from CAFE_DATATYPE_UNION_SEQ to PutBuffer
|
|
* \param _handle input: Conduit object
|
|
* \param val input: CAFE_DATATYPE_UNION_SEQ
|
|
* \param cdt input: CAFE_DATATYPE
|
|
* \return ICAFE_NORMAL as local data conversion should not incur an error
|
|
*/
|
|
//long Transpose<CAFE_DATATYPE_UNION>::put( const unsigned int _handle,
|
|
// CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt)
|
|
|
|
template <class CTYPE> int Transpose<CTYPE>::put( const unsigned int _handle,
|
|
CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt)
|
|
{
|
|
#define __METHOD__ "Transpose<CTYPE>::put()"
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
|
|
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<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ),
|
|
"%d", *reinterpret_cast<const short*>(&val[i].s));
|
|
}
|
|
break;
|
|
case CAFE_FLOAT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%f", *reinterpret_cast<const float*>(&val[i].f));
|
|
}
|
|
break;
|
|
case CAFE_ENUM:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%u", *reinterpret_cast<const unsigned short*>(&val[i].us));
|
|
}
|
|
break;
|
|
case CAFE_CHAR:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%u", *reinterpret_cast<const char*>(&val[i].ch));
|
|
}
|
|
break;
|
|
case CAFE_LONG:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%d", *reinterpret_cast<const int*>(&val[i].l));
|
|
}
|
|
break;
|
|
case CAFE_DOUBLE:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%.15lf", *reinterpret_cast<const double*>(&val[i].d));
|
|
}
|
|
break;
|
|
case CAFE_STRING:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
// cout << "before " << val[i].str << endl;
|
|
sprintf(*((dbr_string_t *) (PVDataL) + i ) ,
|
|
"%s", *reinterpret_cast<char * const *>(&val[i].str));
|
|
//cout << "after " << *((dbr_string_t *) (PVDataL) + i) << endl;
|
|
}
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << cdt <<endl;
|
|
cout << cafeDataTypeCode.message(cdt) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
|
|
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 )) ;
|
|
|
|
|
|
switch(cdt) {
|
|
|
|
case CAFE_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].s ;
|
|
if ( val[i].s < 0 || (dbr_enum_t) val[i].s >= (dbr_enum_t) noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case CAFE_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].f ;
|
|
if ( val[i].f < 0 || (dbr_enum_t) val[i].f >= (dbr_enum_t) noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
|
|
|
|
break;
|
|
case CAFE_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].us ;
|
|
if ( (dbr_enum_t) val[i].us >= (dbr_enum_t) noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
break;
|
|
case CAFE_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].ch ;
|
|
if ( (dbr_enum_t) val[i].ch >= (dbr_enum_t) noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
break;
|
|
case CAFE_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].l ;
|
|
if ( val[i].l < 0 || (dbr_enum_t) val[i].l >= (dbr_enum_t)noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
break;
|
|
case CAFE_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].d ;
|
|
if ( val[i].d < 0 || (dbr_enum_t) val[i].d >= (dbr_enum_t)noStrings) {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
|
|
|
|
break;
|
|
case CAFE_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << cdt <<endl;
|
|
cout << cafeDataTypeCode.message(cdt) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
case DBR_SHORT: // 1
|
|
case DBR_FLOAT: // 2
|
|
|
|
|
|
case DBR_CHAR: // 4
|
|
case DBR_LONG: // 5
|
|
case DBR_DOUBLE: // 6
|
|
|
|
switch(cdt) {
|
|
|
|
case CAFE_SHORT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].s ;
|
|
}
|
|
|
|
break;
|
|
|
|
case CAFE_FLOAT: //2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].f ;
|
|
}
|
|
|
|
|
|
break;
|
|
case CAFE_ENUM: //3
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].us ;
|
|
}
|
|
break;
|
|
case CAFE_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].ch ;
|
|
}
|
|
break;
|
|
case CAFE_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].l ;
|
|
}
|
|
break;
|
|
case CAFE_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
*((CTYPE *) (PVDataL) + i ) = (CTYPE) val[i].d ;
|
|
}
|
|
|
|
break;
|
|
case CAFE_STRING: //0
|
|
status=putString(_handle, (dbr_string_t *) val);
|
|
|
|
break;
|
|
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << cdt <<endl;
|
|
cout << cafeDataTypeCode.message(cdt) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR DATATYPE=" << dbrTypeRequest_DataBuffer <<endl;
|
|
cout << cafeDataTypeCode.message(dbrTypeRequest_DataBuffer) << endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
cout << "LIKELY THAT THE DATA_TYPE WAS NOT MADE KNOWN IN THE INPUT PARAMETERS" << endl;
|
|
|
|
//cout << "CAFE INTERNAL FUNNY: THIS LINE SHOULD NOT APPEAR" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
|
|
return status;
|
|
#undef __METHOD__
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Converts data from CTYPE to native type
|
|
* in preparation for transmission to CA Server
|
|
* \param _handle input: handel to Conduit object
|
|
* \param val input: Array of values of datatype dbr_string_t
|
|
* \return ICAFE_NORMAL else ECAFE_NO_CONVERT
|
|
*/
|
|
template <class CTYPE> int Transpose<CTYPE>::putString
|
|
(const unsigned int _handle, dbr_string_t * val)
|
|
{
|
|
#define __METHOD__ "Transpose<CTYPE>::putString"
|
|
|
|
cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
|
|
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
|
|
|
|
istringstream ss;
|
|
|
|
switch(dbrTypeRequest_DataBuffer) {
|
|
|
|
case DBR_STRING://0
|
|
|
|
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
strcpy( *((dbr_string_t *) (PVDataL) +i), val[i]);
|
|
}
|
|
break;
|
|
|
|
case DBR_SHORT://1
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
dbr_short_t s=0;
|
|
ss.clear();
|
|
ss.str(val[i]);
|
|
ss>>s;
|
|
|
|
if ( !ss.fail()) {
|
|
*((dbr_short_t *) (PVDataL) + i ) = s;
|
|
}
|
|
else {
|
|
cout << __METHOD__ << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_SHORT CONVERSION for ELEMENT " << i
|
|
<< " of " << nelem << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: ";
|
|
cout << val[i];
|
|
cout << " TO SHORT; PUT REQUEST NOT MADE!" << endl;
|
|
//AT THE MERCY OF THE CA SERVER!" << endl; //NOT MADE!" << endl;
|
|
allStringsAreValid=false;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DBR_FLOAT://2
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
dbr_float_t f=0;
|
|
ss.clear();
|
|
ss.str(val[i]);
|
|
ss>>f;
|
|
|
|
if ( !ss.fail()) {
|
|
*((dbr_float_t *) (PVDataL) + i ) = f;
|
|
}
|
|
else {
|
|
cout << __METHOD__ << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_FLOAT CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: ";
|
|
cout << val[i];
|
|
cout << " TO FLOAT; PUT REQUEST NOT MADE!" << endl; //AT THE MERCY OF THE CA SERVER!" << endl; //NOT MADE! " << 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<nelem; ++i) {
|
|
dbr_string_t a;
|
|
|
|
//sprintf(a, "%s", val[i]);
|
|
|
|
char *b = (char *) val[i];
|
|
char *c;
|
|
// Remove leading blanks
|
|
c = b;
|
|
while (c != '\0' && *c == ' ') {
|
|
c++;
|
|
}
|
|
b = c;
|
|
|
|
// Remove trailing blanks
|
|
c = b + strlen (b) - 1;
|
|
while (c >= 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<noStrings; ++j) {
|
|
|
|
if (strcmp((char *)a, stig[j] ) ==0) {
|
|
|
|
dbr_enum_t us= (unsigned short) j;
|
|
*((dbr_enum_t *) (PVDataL) + i ) = us;
|
|
isValidString=true;
|
|
//cout << "setting value " << j << " " << stig[j] << endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check for ENUM values given in "string" form
|
|
|
|
if (!isValidString) {
|
|
|
|
bool isValidStringAnew=false;
|
|
|
|
dbr_enum_t us=0;
|
|
ss.clear();
|
|
ss.str(a);
|
|
ss>>us;
|
|
|
|
// Is this a valid number?
|
|
if ( !ss.fail()) {
|
|
if (us==0 || (us>0 && us <noStrings)) {
|
|
*((dbr_enum_t *) (PVDataL) + i ) = us;
|
|
isValidStringAnew=true;
|
|
}
|
|
else {
|
|
status=ECAFE_INVALID_ENUM_INDEX;
|
|
}
|
|
}
|
|
|
|
if (!isValidStringAnew) {
|
|
|
|
cout << __METHOD__ << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_ENUM MATCHING for ELEMENT " << i << " of " << nelem << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: '";
|
|
cout << a; //val[i];
|
|
cout << "' TO A VALID ENUM; PUT REQUEST NOT MADE!" << endl; //AT THE MERCY OF THE CA SERVER!" << endl;
|
|
cout << "VALID STRING [ENUM] OPTIONS ARE: " << endl;
|
|
|
|
|
|
for (dbr_short_t ij=0; ij<noStrings; ++ij) {
|
|
cout << "'" << stig[ij] << "' " << "[" << ij << "]" << "; ";
|
|
}
|
|
cout << endl;
|
|
|
|
|
|
allStringsAreValid=false;
|
|
}
|
|
|
|
}
|
|
|
|
} //nelem for loop
|
|
|
|
|
|
|
|
break;
|
|
|
|
case DBR_CHAR: //4
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
dbr_char_t ch=0;
|
|
ss.clear();
|
|
ss.str(val[i]);
|
|
ss>>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 {
|
|
cout << __FILE__ << "//" << __METHOD__ << "//" << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_CHAR CONVERSION for ELEMENT index " << i << " in array of length " << nelem;
|
|
cout << ", i.e., with index range [0-" << (nelem-1) << "] " << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: ";
|
|
cout << val[i];
|
|
cout << " TO UNSIGNED CHAR; PUT REQUEST NOT MADE!" << endl; //AT THE MERCY OF THE CA SERVER!" << endl; //NOT MADE!" << endl;
|
|
allStringsAreValid=false;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case DBR_LONG: //5
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
dbr_long_t l=0;
|
|
ss.clear();
|
|
ss.str(val[i]);
|
|
ss>>l;
|
|
|
|
if ( !ss.fail()) {
|
|
*((dbr_long_t *) (PVDataL) + i ) = l;
|
|
}
|
|
else {
|
|
cout << __METHOD__ << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_LONG CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: ";
|
|
cout << val[i];
|
|
cout << " TO LONG; PUT REQUEST NOT MADE!" << endl; //AT THE MERCY OF THE CA SERVER!" << endl; //NOT MADE!" << endl;
|
|
|
|
allStringsAreValid=false;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DBR_DOUBLE: //6
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
dbr_double_t d=0;
|
|
ss.clear();
|
|
ss.str(val[i]);
|
|
ss>>d;
|
|
|
|
if ( !ss.fail()) {
|
|
*((dbr_double_t *) (PVDataL) + i ) = d;
|
|
}
|
|
else {
|
|
cout << __METHOD__ << __LINE__ << endl;
|
|
cout << "***WARNING*** NO STRING TO DBR_DOUBLE CONVERSION for ELEMENT " << i << " of " << nelem << " !! " << endl;
|
|
cout << "***WARNING*** COULD NOT CONVERT: ";
|
|
cout << val[i];
|
|
cout << " TO DOUBLE; PUT REQUEST NOT MADE!" << endl; //AT THE MERCY OF THE CA SERVER!" << endl; //PUT REQUEST NOT MADE!" << 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 <class CTYPE> int Transpose<CTYPE>::get(
|
|
const unsigned int _handle, CTYPE * val,
|
|
dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest)
|
|
{
|
|
#define __METHOD__ "Transpose<CTYPE>::get()"
|
|
|
|
cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
it_handle = handle_index.find(_handle);
|
|
|
|
if (it_handle != handle_index.end()) {
|
|
|
|
PVDataL = (*it_handle).getDataBuffer();
|
|
offset = (*it_handle).getChannelRequestMetaDataClient().getOffset();
|
|
//cout << "offset client " << offset << endl;
|
|
//cout << "offset client too...... " << handleHelper.getOffset(_handle) << endl;
|
|
//cout << "offsetLast ...... " << handleHelper.getOffsetLast(_handle) << 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!
|
|
//cout << "nelem1 + data offset " << nelem << " " << (*it_handle).getChannelRequestMetaData().getNelemCache() << " + " <<
|
|
//(*it_handle).getChannelRequestMetaData().getOffset() << endl;
|
|
//nelem = min(nelem, (*it_handle).getChannelRequestMetaData().getNelemCache()+ offset);
|
|
//cout << "nelem2 " << nelem << " " << (*it_handle).getChannelRequestMetaData().getNelemCache() << " + " << offset << endl;
|
|
//cout << __METHOD__ << __LINE__ << endl;
|
|
//cout << "nelem = " << (*it_handle).getChannelRequestMetaData().getNelem() << endl;
|
|
//cout << "nelemCache = " << (*it_handle).getChannelRequestMetaData().getNelemCache() << endl;
|
|
//cout << "offset = " << (*it_handle).getChannelRequestMetaData().getOffset() << endl;
|
|
//cout << "offsetLast ...... " << handleHelper.getOffsetLast(_handle) << endl;
|
|
//cout << "nelem = " << nelem << endl;
|
|
|
|
}
|
|
else {
|
|
nelem = (*it_handle).getChannelRequestMetaData().getNelem()-offset;
|
|
//cout << __METHOD__ << " nelem " << nelem << endl;
|
|
//cout << "getChannelRequestMetaData().getNelem()=" << (*it_handle).getChannelRequestMetaData().getNelem() << endl;
|
|
//cout << "getChannelRequestMetaDataClient().offset " << offset << endl;
|
|
|
|
}
|
|
//Something wrong, just read last element
|
|
if (nelem <=0) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Something funny with the offset; hence will read last element only!"<< endl;
|
|
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;
|
|
}
|
|
|
|
cout << " to=" << offset << endl;
|
|
}
|
|
|
|
dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaData().getDbrDataType();
|
|
_dataTypeClient = (*it_handle).getChannelRequestMetaDataClient().getDataType();
|
|
|
|
//cout << "WHAT IS ON THE DATA BUFFER = " << dbrTypeRequest_DataBuffer << endl;
|
|
//cout << "WHAT THE CLIENT WANTS = " << _dataTypeClient << endl;
|
|
|
|
ts.secPastEpoch=0;
|
|
ts.nsec =0;
|
|
alarmStatus =-1;
|
|
alarmSeverity =-1;
|
|
|
|
|
|
if (_dataTypeClient < DBR_STRING || _dataTypeClient > DBR_DOUBLE) {
|
|
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cout << "Datatype requested " << dbr_type_to_text(_dataTypeClient)
|
|
<< " is not within allowed range: " << endl;
|
|
cout << "DBR_STRING <= dataType <= DBR_DOUBLE" << endl;
|
|
cout << "CAFE ERROR: ECAFE_INVALID_SWITCH_CASE" << 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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->charval)+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; i<nelem; ++i){
|
|
val[i] = (CTYPE) (*(&((PVDataL)->fltval)+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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->doubleval)+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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->shrtval)+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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->longval)+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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->enmval)+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; i<nelem; ++i) {
|
|
val[i]= (CTYPE) strtol( (*(&((PVDataL)->strval)+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; i<nelem; ++i) {
|
|
val[i]= (CTYPE) strtod( (*(&((PVDataL)->strval)+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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->schrval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->sfltval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->sdblval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->sshrtval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->slngval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->senmval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) strtol( (*(&((PVDataL)->sstrval.value)+i+offset)), NULL, 0);
|
|
}
|
|
break;
|
|
case DBR_FLOAT:
|
|
case DBR_DOUBLE:
|
|
default:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
val[i] = (CTYPE) strtod( (*(&((PVDataL)->sstrval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tchrval.value)+i+offset));
|
|
}
|
|
break;
|
|
// strings are handled by getString - but are handled HERE when calling getCache()!!
|
|
//case DBR_STRING:
|
|
// for (unsigned int i=0; i<nelem; ++i) sprintf(val[i], "%u", (dbr_char_t) (*(&((PVDataL)->tchrval.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:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tfltval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tdblval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tshrtval.value)+i+offset));
|
|
}
|
|
break;
|
|
//case DBR_STRING:
|
|
// for (unsigned int i=0; i<nelem; ++i) sprintf(val[i], "%d",(*(&((PVDataL)->tshrtval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tlngval.value)+i+offset));
|
|
}
|
|
break;
|
|
//case DBR_STRING:
|
|
// for (unsigned int i=0; i<nelem; ++i) sprintf(val[i], "%ld", (*(&((PVDataL)->tlngval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->tenmval.value)+i+offset));
|
|
}
|
|
break;
|
|
//case DBR_STRING:
|
|
// for (unsigned int i=0; i<nelem; ++i) sprintf(val[i], "%d", (*(&((PVDataL)->tenmval.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:
|
|
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; i<nelem; ++i) {
|
|
val[i]= (CTYPE) strtol( (*(&((PVDataL)->tstrval.value)+i+offset)), NULL, 0);
|
|
}
|
|
break;
|
|
case DBR_FLOAT:
|
|
case DBR_DOUBLE:
|
|
default:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
val[i]= (CTYPE) strtod( (*(&((PVDataL)->tstrval.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!
|
|
//cout <<__METHOD__ << endl;
|
|
//cout << "_dbrType" << _dbrTypeRequest_DataBuffer<< endl;
|
|
//cout << ts.secPastEpoch << " " << ts.nsec << endl;
|
|
|
|
if(!isCacheRequest) {
|
|
handleHelper.setSTS(_handle, alarmStatus, alarmSeverity, ts);
|
|
}
|
|
|
|
}
|
|
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 <class CTYPE> int Transpose<CTYPE>::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<CTYPE>::getCtrl()"
|
|
|
|
cafeConduit_set_by_handle & handle_index=cs.get<by_handle>();
|
|
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) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Something funny with the offset; just read last element! " << endl;
|
|
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;
|
|
}
|
|
cout << " to=" << offset << endl;
|
|
}
|
|
|
|
|
|
dbrTypeRequest_CtrlBuffer = (*it_handle).getChannelRequestMetaCtrl().getDbrDataType();
|
|
_dataTypeClient = (*it_handle).getChannelRequestMetaDataClient().getDataType();
|
|
|
|
|
|
alarmStatus = -1;
|
|
alarmSeverity = -1;
|
|
|
|
if (_dataTypeClient < DBR_STRING || _dataTypeClient > DBR_DOUBLE) {
|
|
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cout << "Datatype requested " << dbr_type_to_text(_dataTypeClient)
|
|
<< " is not within allowed range: " << endl;
|
|
cout << "DBR_STRING <= dataType <= DBR_DOUBLE" << endl;
|
|
cout << "CAFE ERROR: ECAFE_INVALID_SWITCH_CASE" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
}
|
|
|
|
|
|
noStr=0;
|
|
|
|
//cout << __METHOD__ << endl;
|
|
//cout << " dbrTypeRequest_CtrlBuffer " << dbrTypeRequest_CtrlBuffer << endl;
|
|
//cout << " _dataTypeClient " << _dataTypeClient << 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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->cchrval.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; i<nelem; ++i) std::cout << val[i] << " /[" << i << "]/ "; cout << endl;
|
|
break;
|
|
case DBR_DOUBLE:
|
|
case DBR_SHORT:
|
|
case DBR_CHAR:
|
|
case DBR_LONG:
|
|
case DBR_FLOAT:
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->cenmval.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; i<noStr; ++i) cout << i << " " << strs[i] << endl;
|
|
|
|
//no units
|
|
memcpy(units,"",sizeof(char[MAX_UNITS_SIZE]));
|
|
|
|
upperDispLimit = (CTYPE) 0;
|
|
lowerDispLimit = (CTYPE) 0;
|
|
upperAlarmLimit = (CTYPE) 0;
|
|
upperWarningLimit = (CTYPE) 0;
|
|
lowerWarningLimit = (CTYPE) 0;
|
|
lowerAlarmLimit = (CTYPE) 0;
|
|
upperCtrlLimit = (CTYPE) 0;
|
|
lowerCtrlLimit = (CTYPE) 0;
|
|
|
|
break;
|
|
|
|
case DBR_CTRL_FLOAT:
|
|
switch(_dataTypeClient){
|
|
case DBR_FLOAT:
|
|
memcpy(val, &(&((PVDataL)->cfltval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->cfltval.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::cout << " RISC_PAD " << ((struct dbr_ctrl_float *) PVDataL)->RISC_pad << std::endl;
|
|
//std::cout << " RISC_PAD " << (short) ((struct dbr_ctrl_float *) PVDataL)->RISC_pad << 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;
|
|
|
|
//cout << "upperCtrlLimit= " << upperCtrlLimit << " upperDispLimit=" << upperDispLimit << endl;
|
|
// cout << "value " << val[0] << 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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->cdblval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->cshrtval.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; i<nelem; ++i) {
|
|
val[i] = (CTYPE) (*(&((PVDataL)->clngval.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
|
|
|
|
|
|
|
|
|
|
|
|
|