/// /// \file PVHolder.h /// \author Jan Chrin, PSI /// \date Release: February 2015 /// \version CAFE 1.0.0 /// #ifndef PVHOLDER_H #define PVHOLDER_H #include #include #include #include #include #include #include #include #include //include boost 1.57 //include #include /** * \class PVHolder * \brief The base class from which the PVDataHolder and PVCtrlHolder * classes are derived */ class PVHolder { protected: char pv [PVNAME_SIZE]; char pvAlias[PVNAME_SIZE]; char device [PVNAME_SIZE]; char attrib [PVNAME_SIZE]; CAFE_DATATYPE dataTypeNative; //enum CAFE_DATATYPE dataType; //enum CAFEDataTypeCode cafeDataTypeCode; //class enum<->string mapping CAFEStatusCode cafeStatusCode; chtype dbrDataType; //dbrTypeRequest_DataBuffer; unsigned int size; unsigned int nelem; //unsigned int nelemNative; short alarmStatus; //alarm.h 0-22 0=NO_ALARM short alarmSeverity; //alarm.h 0=NO_ALARM 1=MINOR 2=MAJOR 3=INVALID CAFEGlobalAlarmCondition acond; CAFEGlobalAlarmSeverity aseve; unsigned int userNo; //e.g. add handle unsigned long long beamEventNo; //rule is used for synchronous groups only bool rule; // to set/get or not to set/get channel; default: true (i.e. set) bool hasAlarm; int status; short noStr; // for enum char strs [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; CAFEConvert renderDouble; CAFEConvert renderFloat; CAFEConvert renderShort; CAFEConvert renderLong; CAFEConvert renderEnum; CAFEConvert renderUChar; CAFEConvert renderString; CAFEConvert renderChar; CAFEConvert renderULong; CAFEConvert renderLongLong; CAFEConvert renderULongLong; CAFEConvert renderInt; CAFEConvert renderUInt; void verifyIndex(unsigned int idx) { if(idx >= size) { std::ostringstream oss; oss << "Exception! Index " << idx << " to PVHolder method is out of range. Valid range is from 0 to " << size-1; throw std::out_of_range(oss.str()); } }; bool isIndexOutOfRange (unsigned int idx) { return (idx >= size) ? true:false; }; public: typedef boost::shared_ptr ValPtr; ValPtr val; boost::shared_ptr > ValVD_ptr; boost::shared_ptr > ValVF_ptr; boost::shared_ptr > ValVS_ptr; boost::shared_ptr > ValVI_ptr; boost::shared_ptr > ValVL_ptr; boost::shared_ptr > ValVUL_ptr; boost::shared_ptr > ValVLL_ptr; boost::shared_ptr > ValVULL_ptr; boost::shared_ptr > ValVC_ptr; boost::shared_ptr > ValVUS_ptr; boost::shared_ptr > ValVStr_ptr; typedef boost::shared_ptr ValDPtr; typedef boost::shared_ptr ValFPtr; typedef boost::shared_ptr ValSPtr; typedef boost::shared_ptr ValIPtr; typedef boost::shared_ptr ValChPtr; typedef boost::shared_ptr ValUSPtr; typedef boost::shared_ptr ValStrPtr; ValDPtr ValD_ptr; ValFPtr ValF_ptr; ValSPtr ValS_ptr; ValIPtr ValI_ptr; ValChPtr ValCh_ptr; ValUSPtr ValUS_ptr; ValStrPtr ValStr_ptr; void setUserNo(unsigned int un) { userNo=un; return; } unsigned int getUserNo() { return userNo; } void setRule(bool r) { rule=r; return; }; void setBeamEventNo (unsigned long long b) { beamEventNo=b; } void setPulseID (unsigned long long b) { beamEventNo=b; } void setStatus (int st) { status=st; //for bsread } void setAlarmStatus (int ast) { alarmStatus=ast; //for bsread } void setAlarmSeverity(int asev) { alarmSeverity=asev; //for bsread } const char * getPV() const { return pv; }; const char * getPVName() const { return pv; }; const char * getPVAlias() const { return pvAlias; }; const char * getDevice() const { return device; }; const char * getAttribute() const { return attrib; }; unsigned int getNelem() const { return nelem; }; //unsigned int getNelemNative() const {return nelemNative;}; const unsigned int getSize() const { return size; }; CAFE_DATATYPE_UNION_SEQ getVal() const { return val.get(); }; short getAlarmStatus() const { return alarmStatus; }; short getAlarmSeverity() const { return alarmSeverity; }; std::string getAlarmStatusAsString() { return acond.asString(alarmStatus); }; std::string getAlarmSeverityAsString() { return aseve.asString(alarmSeverity); }; unsigned long long getBeamEventNo() const { return beamEventNo; }; unsigned long long getPulseID() const { return beamEventNo; }; bool getRule() const { return rule; }; bool getHasAlarm() const { return hasAlarm; }; int getStatus() const { return status; }; std::string getStatusAsString() { return cafeStatusCode.msgIDAsString(status); }; CAFE_DATATYPE getDataTypeClient() const { return dataType; }; CAFE_DATATYPE getDataType() const { return dataType; }; CAFEStatusCode getStatusCode() const { return cafeStatusCode; }; short getNoEnumStrings () const { return noStr; }; char * getEnumString(short indx) const { return (char *) strs[indx]; } void setDataType(CAFE_DATATYPE cdt) { if (cdt > CAFE_DOUBLE || cdt < CAFE_STRING) { std::cout << "WARNING: INPUT VALUE NOT A VALID CAFE DATATYPE " << std::endl; return; } else { dataType=cdt; return; } }; void set(double d) { val[0].d=d; dataType=CAFE_DOUBLE; }; void set(float f) { val[0].f=f; dataType=CAFE_FLOAT; }; void set(short s) { val[0].s=s; dataType=CAFE_SHORT; }; void set(long long l) { if (l > std::numeric_limits::max()) { std::cout << "WARNING: INPUT VALUE GREATER THAN MAX LIMIT OF dbr_long_t " << std::endl; std::cout << "TYPE CASTING TO DOUBLE! " << std::endl; val[0].d= (double) l; dataType=CAFE_DOUBLE; } else { val[0].l= (int) l; dataType=CAFE_LONG; }; } void set(int l) { val[0].l=l; dataType=CAFE_LONG; }; void set(unsigned long long l) { if (l > (unsigned long long) std::numeric_limits::max()) { std::cout << "WARNING: INPUT VALUE GREATER THAN MAX LIMIT OF dbr_long_t " << std::endl; std::cout << "TYPE CASTING TO DOUBLE! " << std::endl; val[0].d= (double) l; dataType=CAFE_DOUBLE; } else { val[0].l= (int) l; dataType=CAFE_LONG; }; } //For Cython void setString(std::string str) { strcpy(val[0].str,str.c_str()); dataType=CAFE_STRING; }; void setDouble(double d) { val[0].d=d; dataType=CAFE_DOUBLE; }; void setInt(int l) { val[0].l=l; dataType=CAFE_LONG; }; void setVString(std::vector Vstr) { if(Vstr.size()!=nelem) { nelem=Vstr.size(); } for (unsigned int i=0; i Vd) { if(Vd.size()!=nelem) { nelem=Vd.size(); } for (unsigned int i=0; i Vl) { if(Vl.size()!=nelem) { nelem=Vl.size(); } for (unsigned int i=0; i Vstr) { if(Vstr.size()!=nelem) { nelem=Vstr.size(); } for (unsigned int i=0; i Vd) { if(Vd.size()!=nelem) { nelem=Vd.size(); } for (unsigned int i=0; i Vf) { if(Vf.size()!=nelem) { nelem=Vf.size(); } for (unsigned int i=0; i Vl) { if(Vl.size()!=nelem) { nelem=Vl.size(); } for (unsigned int i=0; i Vl) { if(Vl.size()!=nelem) { nelem=Vl.size(); } for (unsigned int i=0; i Vul) { if(Vul.size()!=nelem) { nelem=Vul.size(); } for (unsigned int i=0; i Vll) { if(Vll.size()!=nelem) { nelem=Vll.size(); } for (unsigned int i=0; i Vull) { if(Vull.size()!=nelem) { nelem=Vull.size(); } for (unsigned int i=0; i Vs) { if(Vs.size()!=nelem) { nelem=Vs.size(); } for (unsigned int i=0; i Vus) { if(Vus.size()!=nelem) { nelem=Vus.size(); } for (unsigned int i=0; i Vc) { if(Vc.size()!=nelem) { nelem=Vc.size(); } for (unsigned int i=0; i > getAsVDouble() { #define __METHOD__ "PVHolder::getAsVDouble " ValVD_ptr.reset(new std::vector()); ValVD_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back(val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back(val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back(val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back(val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back(val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back(val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsDouble(i)); } break; } return ValVD_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVFloat() { #define __METHOD__ "PVHolder::getAsVFloat " ValVF_ptr.reset(new std::vector()); ValVF_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((float) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back(val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back(val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back(val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back(val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back(val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsFloat(i)); } break; } //How to index shared pointer for > //std::vector * vf= ValVF_ptr.get(); //std::cout << "size/// " << vf[0].size() << std::endl; //std::cout << vf[0][0] << " val " << val[0].f << std::endl; //std::cout << vf[0][1] << " val " << val[1].f << std::endl; //std::vector vf= *ValVF_ptr.get(); //std::cout << "size/// " << vf.size() << std::endl; //std::cout << vf[0] << " val " << val[0].f << std::endl; //std::cout << vf[1] << " val " << val[1].f << std::endl; return ValVF_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVInt() { #define __METHOD__ "PVHolder::getAsVInt " ValVI_ptr.reset(new std::vector()); ValVI_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((int) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((int) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back(val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back(val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back(val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back(val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsInt(i)); } break; } return ValVI_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVLong() { #define __METHOD__ "PVHolder::getAsVInt " ValVL_ptr.reset(new std::vector()); ValVL_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((long) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((long) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((long) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((long) val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back((long) val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((long) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsLong(i)); } break; } return ValVL_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVULong() { #define __METHOD__ "PVHolder::getAsVInt " ValVUL_ptr.reset(new std::vector()); ValVUL_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((unsigned long) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((unsigned long) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((unsigned long) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((unsigned long) val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back((unsigned long) val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((unsigned long) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsULong(i)); } break; } return ValVUL_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVLongLong() { #define __METHOD__ "PVHolder::getAsVLongLong " ValVLL_ptr.reset(new std::vector()); ValVLL_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((long long) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((long long) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((long long) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((long long) val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back((long long) val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((long long) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsLongLong(i)); } break; } return ValVLL_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVULongLong() { #define __METHOD__ "PVHolder::getAsVLongLong " ValVULL_ptr.reset(new std::vector()); ValVULL_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((unsigned long long) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((unsigned long long) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((unsigned long long) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((unsigned long long) val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back((unsigned long long) val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((unsigned long long) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsULongLong(i)); } break; } return ValVULL_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVShort() { #define __METHOD__ "PVHolder::getAsVShort " ValVS_ptr.reset(new std::vector()); ValVS_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((short) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((short) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((short) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back(val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back((short) val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((unsigned short) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsShort(i)); } break; } return ValVS_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVUShort() { #define __METHOD__ "PVHolder::getAsVUShort " ValVUS_ptr.reset(new std::vector()); ValVUS_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((unsigned short) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((unsigned short) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((unsigned short) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((unsigned short)val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back( val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((unsigned short) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( getAsUShort(i)); } break; } return ValVUS_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVUChar() { #define __METHOD__ "PVHolder::getAsVUChar " ValVC_ptr.reset(new std::vector()); ValVC_ptr->reserve(nelem); switch (dataType) { case CAFE_DOUBLE: for (unsigned i=0; ipush_back((unsigned char) val[i].d); } break; case CAFE_FLOAT: for (unsigned i=0; ipush_back((unsigned char) val[i].f); } break; case CAFE_LONG: for (unsigned i=0; ipush_back((unsigned char) val[i].l); } break; case CAFE_SHORT: for (unsigned i=0; ipush_back((unsigned char)val[i].s); } break; case CAFE_ENUM: for (unsigned i=0; ipush_back( (unsigned char)val[i].us); } break; case CAFE_CHAR: for (unsigned i=0; ipush_back((unsigned char) val[i].ch); } break; case CAFE_STRING: default: for (unsigned i=0; ipush_back( (unsigned char) getAsChar(i)); } break; } return ValVC_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVString() { #define __METHOD__ "PVHolder::getAsVString " ValVStr_ptr.reset(new std::vector()); ValVStr_ptr->reserve(nelem); for (unsigned i=0; ipush_back( getAsString(i)); } return ValVStr_ptr; #undef __METHOD__ } std::vector getAsVectorString() { boost::shared_ptr > spVs = getAsVString(); return *spVs.get(); } std::vector getAsVectorFloat() { boost::shared_ptr > spVf = getAsVFloat(); return *spVf.get(); } std::vector getAsVectorDouble() { boost::shared_ptr > spVd = getAsVDouble(); return *spVd.get(); } std::vector getAsVectorInt() { boost::shared_ptr > spVi = getAsVInt(); return *spVi.get(); } std::vector getAsVectorLong() { boost::shared_ptr > spVl = getAsVLong(); return *spVl.get(); } std::vector getAsVectorULong() { boost::shared_ptr > spVul = getAsVULong(); return *spVul.get(); } std::vector getAsVectorLongLong() { boost::shared_ptr > spVll = getAsVLongLong(); return *spVll.get(); } std::vector getAsVectorULongLong() { boost::shared_ptr > spVull = getAsVULongLong(); return *spVull.get(); } std::vector getAsVectorShort() { boost::shared_ptr > spVsh = getAsVShort(); return *spVsh.get(); } std::vector getAsVectorUShort() { boost::shared_ptr > spVus = getAsVUShort(); return *spVus.get(); } std::vector getAsVectorUChar() { boost::shared_ptr > spVc = getAsVUChar(); return *spVc.get(); } ValDPtr getDouble() { #define __METHOD__ "PVHolder::getDouble " if (dataType!=CAFE_DOUBLE) { std::cout << "******* WARNING *******" << std::endl; std::cout << __METHOD__ << __LINE__ << std::endl; std::cout << "DataType is " << (cafeDataTypeCode.message((CAFE_DATATYPE)dataType)).c_str() << " hence getDouble method is invalid! " << std::endl; std::cout << "Use getAsDouble method if you wish to retrieve the data as a double! " << std::endl; std::cout << "**********************" << std::endl; } ValD_ptr.reset(new double[nelem]); for (unsigned i=0; i