/// /// \file PVDataHolder.h /// \author Jan Chrin, PSI /// \date November 2014 /// \version CAFE 1.0.0 /// #ifndef PVDATAHOLDER_H #define PVDATAHOLDER_H #include #include /** * \class PVDataHolder * \brief This class is the holder of data values associated with * the EPICS DBR_TIME_(dataType) structure of a given handle/pv */ class PVDataHolder : public PVHolder { friend class CAFE; friend class PVGroup; friend class Connect; friend class Conduit; //if HAVE_LIBQTXML friend class loadCollectionXMLParser; friend class restorePVGroupXMLParser; //endif friend struct change_dataBufferPVDataHolder; friend struct change_dataBufferSize_TIME; friend struct change_connectionHandlerArgs; friend struct change_pvAlias; public: epicsTimeStamp ts; bool hasTS; etsNorm _etsNorm; etsDate _etsDate; TMwdayText tmDay; TMmonthpText tmMonth; //Derived class does not inherit constructors PVDataHolder(unsigned int _sizeOfArray) { alarmStatus=-1; alarmSeverity=-1; status=ECAFE_NODATA; nelem= _sizeOfArray > 0 ? _sizeOfArray : 1; size = _sizeOfArray > 0 ? _sizeOfArray : 1; dataType=(CAFE_DATATYPE) CAFE_NO_ACCESS; dataTypeNative=(CAFE_DATATYPE) CAFE_NO_ACCESS; rule=true; beamEventNo=0; userNo=0; ts.nsec=0; ts.secPastEpoch=0; hasAlarm=true; hasTS=true; strcpy(pv,""); strcpy(pvAlias,""); strcpy(device,""); strcpy(attrib,""); val.reset( new CAFE_DATATYPE_UNION[nelem] ); for (unsigned int i=0; i0 ? nelem=_nelem : nelem=1; if (nelem>size) { size=nelem; val.reset( new CAFE_DATATYPE_UNION[size] ); } return nelem; }; epicsTimeStamp getEpicsTimeStamp() const { return ts; }; etsNorm getEpicsTimeStampAsUInt32() { _etsNorm.secPastEpoch=ts.secPastEpoch; _etsNorm.nsec=(unsigned long) ts.nsec; return _etsNorm; }; etsDate getEpicsTimeStampAsDate() { ts.nsec=(unsigned int) ts.nsec; //This may happen in timeouts; epicsTime convertor will report overflow error //However this possibility is now captured in conduitFriend.h and other if(ts.nsec >= 1000000000) { std::cout << "OVERFLOW IN gets.nsec CORRECTED for epicsTime converter " << std::endl; ts.nsec=0; } epicsTime time(ts); local_tm_nano_sec local = (local_tm_nano_sec) time; _etsDate.year = local.ansi_tm.tm_year + 1900; _etsDate.mon = local.ansi_tm.tm_mon + 1; _etsDate.day = local.ansi_tm.tm_mday; _etsDate.hour = local.ansi_tm.tm_hour; _etsDate.min = local.ansi_tm.tm_min; _etsDate.sec = local.ansi_tm.tm_sec; _etsDate.nsec = (unsigned long) ts.nsec; _etsDate.wday = local.ansi_tm.tm_wday; _etsDate.yday = local.ansi_tm.tm_yday; _etsDate.isdst = local.ansi_tm.tm_isdst; return _etsDate; } etsDate getUnixTimeAsDate(etsNorm ets) { time_t t= ets.secPastEpoch; struct tm * local; local=localtime(&t); //local_tm_nano_sec local = (local_tm_nano_sec) time; _etsDate.year = local->tm_year +1900; _etsDate.mon = local->tm_mon + 1; _etsDate.day = local->tm_mday; _etsDate.hour = local->tm_hour; _etsDate.min = local->tm_min; _etsDate.sec = local->tm_sec; _etsDate.nsec = (unsigned long) ts.nsec; _etsDate.wday = local->tm_wday; _etsDate.yday = local->tm_yday; _etsDate.isdst = local->tm_isdst; return _etsDate; } std::string getEpicsTimeStampAsString() { time_t t= ts.secPastEpoch; struct tm * local; local=localtime(&t); char buf[40]; local->tm_year=local->tm_year+20; //EPICS Time is 20 years out! strftime (buf,80,"%b %d, %Y %T.",local); std::string date=(std::string) buf; char buft[10]; sprintf(buft,"%d",ts.nsec); date.append((std::string) buft); return date; } std::string getBSTimeStampAsString() { time_t t= ts.secPastEpoch; struct tm * local; local=localtime(&t); char buf[40]; strftime (buf,80,"%b %d, %Y %T.",local); std::string date=(std::string) buf; char buft[10]; sprintf(buft,"%d",ts.nsec); date.append((std::string) buft); return date; } void print() { print(nelem) ; } void print(unsigned int nelemToPrint) { nelemToPrint=std::min(nelemToPrint,nelem); if (strcmp(pv,"")==0) { std::cout << "Process Variable NOT ASSIGNED!" << std::endl; std::cout << "Variable has not been applied to a get operation!" << std::endl; return; } std::cout << "------------------------------------------" << std::endl; //std::cout << "PVDataHolder:" << std::endl; std::cout << "processVariable= " << pv << std::endl; if (strcmp(pvAlias,pv) && strcmp(pvAlias,"")) { std::cout << "pvAlias = " << pvAlias << std::endl; } std::cout << "device = " << device << std::endl; std::cout << "attrib = " << attrib << std::endl; std::cout << "dataType = " << cafeDataTypeCode.message(dataType).c_str() << " (" << dataType << ") " << std::endl; std::cout << "dbrTypeRequest = " << dbr_type_to_text(dbrDataType) << " (" << dbrDataType << ") " << std::endl; //std::cout << "dataType = " << CAFEDataTypeCode.message(dataType).c_str() << std::endl; if (dataType != CAFE_NO_ACCESS && dataType != CAFE_TYPENOTCONN) { std::cout << "nelem = "; } else { std::cout << "nelem = "; } std::cout << nelem; std::cout << std::endl; if(!rule) { std::cout << "rule (0=false) = " << rule <