/// /// \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 int 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 setBSStatus(int st) {status=st;} //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;}; string getAlarmStatusAsString() {return acond.asString(alarmStatus);}; string getAlarmSeverityAsString() {return aseve.asString(alarmSeverity);}; unsigned int getBeamEventNo() const {return beamEventNo;}; bool getRule() const {return rule;}; bool getHasAlarm() const{return hasAlarm;}; int getStatus() const {return 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) { cout << "WARNING: INPUT VALUE NOT A VALID CAFE DATATYPE " << 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()) { cout << "WARNING: INPUT VALUE GREATER THAN MAX LIMIT OF dbr_long_t " << endl; cout << "TYPE CASTING TO DOUBLE! " << 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()) { cout << "WARNING: INPUT VALUE GREATER THAN MAX LIMIT OF dbr_long_t " << endl; cout << "TYPE CASTING TO DOUBLE! " << 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(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 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 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 > //vector * vf= ValVF_ptr.get(); //cout << "size/// " << vf[0].size() << endl; //cout << vf[0][0] << " val " << val[0].f << endl; //cout << vf[0][1] << " val " << val[1].f << endl; //vector vf= *ValVF_ptr.get(); //cout << "size/// " << vf.size() << endl; //cout << vf[0] << " val " << val[0].f << endl; //cout << vf[1] << " val " << val[1].f << endl; return ValVF_ptr; #undef __METHOD__ } boost::shared_ptr > getAsVInt(){ #define __METHOD__ "PVHolder::getAsVInt " ValVI_ptr.reset(new 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 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 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 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 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 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 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 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 vector()); ValVStr_ptr->reserve(nelem); for (unsigned i=0; ipush_back( getAsString(i));} return ValVStr_ptr; #undef __METHOD__ } vector getAsVectorString() { boost::shared_ptr > spVs = getAsVString(); return *spVs.get(); } vector getAsVectorFloat() { boost::shared_ptr > spVf = getAsVFloat(); return *spVf.get(); } vector getAsVectorDouble() { boost::shared_ptr > spVd = getAsVDouble(); return *spVd.get(); } vector getAsVectorInt() { boost::shared_ptr > spVi = getAsVInt(); return *spVi.get(); } vector getAsVectorLong() { boost::shared_ptr > spVl = getAsVLong(); return *spVl.get(); } vector getAsVectorULong() { boost::shared_ptr > spVul = getAsVULong(); return *spVul.get(); } vector getAsVectorLongLong() { boost::shared_ptr > spVll = getAsVLongLong(); return *spVll.get(); } vector getAsVectorULongLong() { boost::shared_ptr > spVull = getAsVULongLong(); return *spVull.get(); } vector getAsVectorShort() { boost::shared_ptr > spVsh = getAsVShort(); return *spVsh.get(); } vector getAsVectorUShort() { boost::shared_ptr > spVus = getAsVUShort(); return *spVus.get(); } vector getAsVectorUChar() { boost::shared_ptr > spVc = getAsVUChar(); return *spVc.get(); } ValDPtr getDouble(){ #define __METHOD__ "PVHolder::getDouble " if (dataType!=CAFE_DOUBLE) { cout << "******* WARNING *******" << endl; cout << __METHOD__ << __LINE__ << endl; cout << "DataType is " << (cafeDataTypeCode.message((CAFE_DATATYPE)dataType)).c_str() << " hence getDouble method is invalid! " << endl; cout << "Use getAsDouble method if you wish to retrieve the data as a double! " << endl; cout << "**********************" << endl; } ValD_ptr.reset(new double[nelem]); for (unsigned i=0; i