13 #include <epicsVersion.h> 30 #ifdef EPICS_VERSION_INT 31 # if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0) 34 # define CASE_REAL_INT64 47 :
chan(dbChannelCreate(name.c_str()))
55 throw std::invalid_argument(
"NULL channel");
56 if(dbChannelOpen(
chan)) {
57 dbChannelDelete(
chan);
58 throw std::invalid_argument(
SB()<<
"Failed to open channel "<<dbChannelName(
chan));
74 pva::PeerInfo::const_shared_pointer info(req->getPeerInfo());
75 std::string usertemp, hosttemp;
77 if(info && info->identified) {
78 hosttemp = info->peer;
79 if(info->authority==
"ca") {
80 usertemp = info->account;
81 size_t sep = usertemp.find_last_of(
'/');
82 if(sep != std::string::npos) {
84 usertemp = usertemp.substr(sep+1);
88 usertemp = info->authority +
"/" + info->account;
91 const char role[] =
"role/";
93 groups.resize(info->roles.size());
95 for(pva::PeerInfo::roles_t::const_iterator it(info->roles.begin()), end(info->roles.end()); it!=end; ++it, idx++) {
96 groups[idx].resize((*it).size()+
sizeof(role));
102 groups[idx].begin()+
sizeof(role)-1);
103 groups[idx][groups[idx].size()-1] =
'\0';
108 hosttemp = req->getRequesterName();
112 size_t sep = hosttemp.find_first_of(
':');
113 if(sep == std::string::npos) {
114 sep = hosttemp.size();
116 hosttemp.resize(sep);
118 host.resize(hosttemp.size()+1);
122 host[hosttemp.size()] =
'\0';
124 user.resize(usertemp.size()+1);
128 user[usertemp.size()] =
'\0';
134 for(
size_t i=0, N=grppvt.size();
i<N;
i++) {
143 (void)
asAddClient(&aspvt, dbChannelRecord(chan)->asp, dbChannelFldDes(chan)->as_level, &cred.
user[0], &cred.
host[0]);
145 grppvt.resize(cred.
groups.size(), 0);
147 for(
size_t i=0, N=grppvt.size();
i<N;
i++) {
149 (void)
asAddClient(&grppvt[i], dbChannelRecord(chan)->asp, dbChannelFldDes(chan)->as_level, &cred.
groups[
i][0], &cred.
host[0]);
156 for(
size_t i=0, N=grppvt.size();
i<N;
i++) {
180 pvTimeAlarm() :
chan(
NULL), nsecMask(0) {}
183 struct pvCommon :
public pvTimeAlarm {
196 struct pvScalar :
public pvCommon {
201 struct pvArray :
public pvCommon {
210 enum {mask = DBR_STATUS | DBR_TIME};
240 enum {mask = DBR_STATUS | DBR_TIME | DBR_ENUM_STRS};
255 enum {mask = DBR_STATUS | DBR_TIME};
260 #define FMAP(MNAME, PVT, FNAME, DBE) pvm.MNAME = pv->getSubFieldT<pvd::PVT>(FNAME); \ 261 pvm.mask ## DBE.set(pvm.MNAME->getFieldOffset()) 263 FMAP(severity,
PVInt,
"alarm.severity", ALARM);
264 FMAP(message, PVString,
"alarm.message", ALARM);
265 FMAP(sec,
PVLong,
"timeStamp.secondsPastEpoch", ALWAYS);
266 FMAP(nsec,
PVInt,
"timeStamp.nanoseconds", ALWAYS);
281 return pvd::freeze(fmt);
297 #define FMAP(MNAME, PVT, FNAME, DBE) pvm.MNAME = pv->getSubField<pvd::PVT>(FNAME); \ 298 if(pvm.MNAME) pvm.mask ## DBE.set(pvm.MNAME->getFieldOffset()) 299 FMAP(displayHigh,
PVDouble,
"display.limitHigh", PROPERTY);
300 FMAP(displayLow,
PVDouble,
"display.limitLow", PROPERTY);
301 FMAP(controlHigh,
PVDouble,
"control.limitHigh", PROPERTY);
302 FMAP(controlLow,
PVDouble,
"control.limitLow", PROPERTY);
303 FMAP(egu, PVString,
"display.units", PROPERTY);
304 FMAP(desc, PVString,
"display.description", PROPERTY);
306 FMAP(fmt,
PVInt,
"display.form.index", PROPERTY);
307 FMAP(warnHigh, PVScalar,
"valueAlarm.highWarningLimit", PROPERTY);
308 FMAP(warnLow, PVScalar,
"valueAlarm.lowWarningLimit", PROPERTY);
309 FMAP(alarmHigh, PVScalar,
"valueAlarm.highAlarmLimit", PROPERTY);
310 FMAP(alarmLow, PVScalar,
"valueAlarm.lowAlarmLimit", PROPERTY);
315 template<
typename PVX>
318 pvm.value = pv->getSubField<
typename PVX::pvd_type>(
"value.index");
320 pvm.value = pv->getSubFieldT<
typename PVX::pvd_type>(
"value");
322 pvm.maskVALUE.set(fld->getFieldOffset());
323 for(;fld; fld = fld->getParent()) {
325 pvm.maskVALUEPut.set(fld->getFieldOffset());
327 pvm.maskVALUEPut.set(0);
381 template<
typename META>
382 void putMetaImpl(
const pvTimeAlarm& pv,
const META& meta)
386 pv.userTag->put(nsec&pv.nsecMask);
387 nsec &= ~pv.nsecMask;
392 void putTime(
const pvTimeAlarm& pv,
unsigned dbe, db_field_log *pfl)
395 long options = (int)metaTIME::mask, nReq = 0;
397 long status = dbChannelGet(pv.chan, dbChannelFinalFieldType(pv.chan), &meta, &options, &nReq, pfl);
399 throw std::runtime_error(
"dbGet for meta fails");
401 putMetaImpl(pv, meta);
403 mapStatus(meta.status, pv.status.get(), pv.message.get());
404 pv.severity->put(meta.severity);
413 long status = dbChannelGet(chan, dbChannelFinalFieldType(chan), &buf,
NULL, &nReq, pfl);
415 throw std::runtime_error(
"dbGet for meta fails");
419 memset(&buf, 0,
sizeof(buf));
422 switch(dbChannelFinalFieldType(chan)) {
423 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: value->putFrom<PVATYPE>(buf.dbf_##DBFTYPE); break; 425 #define CASE_SKIP_BOOL 428 #undef CASE_SKIP_BOOL 435 throw std::runtime_error(
"putValue unsupported DBR code");
443 switch(dbChannelFinalFieldType(chan)) {
444 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: buf.dbf_##DBFTYPE = value->getAs<PVATYPE>(); break; 446 #define CASE_SKIP_BOOL 449 #undef CASE_SKIP_BOOL 453 std::string val(value->
getAs<std::string>());
459 throw std::runtime_error(
"getValue unsupported DBR code");
462 long status = dbChannelPut(chan, dbChannelFinalFieldType(chan), &buf, 1);
464 throw std::runtime_error(
"dbPut for meta fails");
469 short dbr = dbChannelFinalFieldType(chan);
477 long status = dbChannelPut(chan, dbr, buf.
data(), nReq);
479 throw std::runtime_error(
"dbChannelPut fails");
488 for(
size_t i=0, N=buf.
size();
i<N;
i++)
491 temp[
i*MAX_STRING_SIZE + MAX_STRING_SIZE-1] =
'\0';
494 long status = dbChannelPut(chan, dbr, &temp[0], buf.
size());
496 throw std::runtime_error(
"dbChannelPut fails");
502 const short dbr = dbChannelFinalFieldType(chan);
504 long nReq = dbChannelFinalElements(chan);
511 long status = dbChannelGet(chan, dbr, buf.
data(),
NULL, &nReq, pfl);
513 throw std::runtime_error(
"dbChannelGet for value fails");
517 value->
putFrom(pvd::freeze(buf));
522 long status = dbChannelGet(chan, dbr, &temp[0],
NULL, &nReq, pfl);
524 throw std::runtime_error(
"dbChannelGet for value fails");
527 for(
long i=0;
i<nReq;
i++) {
528 temp[
i*MAX_STRING_SIZE + MAX_STRING_SIZE-1] =
'\0';
529 buf[
i] = std::string(&temp[
i*MAX_STRING_SIZE]);
532 value->
putFrom(pvd::freeze(buf));
535 template<
typename META>
536 void putMeta(
const pvCommon& pv,
unsigned dbe, db_field_log *pfl)
539 long options = (int)META::mask, nReq = 0;
540 dbCommon *
prec = dbChannelRecord(pv.chan);
542 long status = dbChannelGet(pv.chan, dbChannelFinalFieldType(pv.chan), &meta, &options, &nReq, pfl);
544 throw std::runtime_error(
"dbGet for meta fails");
546 putMetaImpl(pv, meta);
547 #define FMAP(MNAME, FNAME) pv.MNAME->put(meta.FNAME) 549 mapStatus(meta.status, pv.status.get(), pv.message.get());
550 FMAP(severity, severity);
554 if(pv.desc) pv.desc->put(prec->desc);
555 #define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->put(meta.FNAME) 562 if(META::mask&DBR_PRECISION && pv.prec) {
565 #define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->putFrom(meta.FNAME) 568 FMAP(DBR_AL_DOUBLE, warnHigh, upper_warning_limit);
569 FMAP(DBR_AL_DOUBLE, warnLow, lower_warning_limit);
570 FMAP(DBR_AL_DOUBLE, alarmHigh, upper_alarm_limit);
571 FMAP(DBR_AL_DOUBLE, alarmLow, lower_alarm_limit);
575 for(
size_t i=0;
i<strs.
size();
i++)
577 meta.strs[
i][
sizeof(meta.strs[
i])-1] =
'\0';
578 strs[
i] = meta.strs[
i];
580 pv.enumopts->replace(pvd::freeze(strs));
585 template<
typename PVC,
typename META>
586 void putAll(
const PVC &pv,
unsigned dbe, db_field_log *pfl)
589 putValue(pv.chan, pv.value.get(), pfl);
592 putTime(pv, dbe, pfl);
594 putMeta<META>(pv,
dbe, pfl);
600 const char *UT = info.
info(
"Q:time:tag");
601 if(UT && strncmp(UT,
"nsec:lsb:", 9)==0) {
603 pvmeta.nsecMask = epics::pvData::castUnsafe<pvd::uint32>(std::string(&UT[9]));
604 }
catch(std::exception& e){
606 std::cerr<<info.
name()<<
" : Q:time:tag nsec:lsb: requires a number not '"<<UT[9]<<
"'\n";
609 if(pvmeta.nsecMask>0 && pvmeta.nsecMask<=32) {
610 pvmeta.userTag = pvalue->getSubField<
pvd::PVInt>(
"timeStamp.userTag");
611 if(!pvmeta.userTag) {
615 pvmeta.nsecMask = mask;
616 pvmeta.maskALWAYS.set(pvmeta.userTag->getFieldOffset());
624 const char *FMT = info.
info(
"Q:form");
629 for(
size_t i=0; !found &&
i<displayForms.
size();
i++) {
630 if((found=(displayForms[
i]==FMT)))
635 fmt->putFrom(std::string(FMT));
636 }
catch(std::exception& e){
637 errlogPrintf(
"%s: info(Q:form, \"%s\") is not known format: %s\n", info.
name(), FMT, e.what());
645 template<
typename PVX,
typename META>
646 struct PVIFScalarNumeric :
public PVIF 653 ,pvalue(std::tr1::dynamic_pointer_cast<pvd::PVStructure>(p))
656 throw std::runtime_error(
"Must attach to structure");
659 attachAll<PVX>(pvmeta, pvalue);
663 pvmeta.maskALWAYS.clear();
664 pvmeta.maskALWAYS.set(bit);
665 pvmeta.maskVALUE.clear();
666 pvmeta.maskVALUE.set(bit);
667 pvmeta.maskALARM.clear();
668 pvmeta.maskALARM.set(bit);
669 pvmeta.maskPROPERTY.clear();
670 pvmeta.maskPROPERTY.set(bit);
671 pvmeta.maskVALUEPut.clear();
672 pvmeta.maskVALUEPut.set(0);
673 pvmeta.maskVALUEPut.set(bit);
676 findNSMask(pvmeta, info, pvalue);
677 findFormat(pvmeta, info, pvalue);
679 virtual ~PVIFScalarNumeric() {}
684 putAll<PVX, META>(pvmeta,
dbe, pfl);
685 mask |= pvmeta.maskALWAYS;
687 mask |= pvmeta.maskVALUE;
689 mask |= pvmeta.maskALARM;
691 mask |= pvmeta.maskPROPERTY;
693 pvmeta.severity->put(3);
694 mask |= pvmeta.maskALARM;
702 bool newval = mask.logical_and(pvmeta.maskVALUEPut);
705 getValue(pvmeta.chan, pvmeta.value.get());
737 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: return pvd::pv##PVACODE; 739 #define CASE_SKIP_BOOL 742 #undef CASE_SKIP_BOOL 746 throw std::invalid_argument(
"Unsupported DBR code");
752 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case pvd::pv##PVACODE: return DBR_##DBFTYPE; 754 # define CASE_SQUEEZE_INT64 758 # undef CASE_SQUEEZE_INT64 769 short dbr = dbChannelFinalFieldType(channel);
770 const long maxelem = dbChannelFinalElements(channel);
774 throw std::invalid_argument(
"DBF code out of range");
783 builder = builder->setId(
"epics:nt/NTEnum:1.0")
784 ->addNestedStructure(
"value")
790 builder = builder->setId(
"epics:nt/NTScalar:1.0")
793 builder = builder->setId(
"epics:nt/NTScalarArray:1.0")
794 ->addArray(
"value", pvt);
796 builder = builder->add(
"alarm", standard->alarm())
797 ->add(
"timeStamp", standard->timeStamp());
800 builder = builder->addNestedStructure(
"display")
806 ->addNestedStructure(
"form")
812 ->add(
"control", standard->control());
815 builder = builder->add(
"valueAlarm", standard->doubleAlarm());
818 return builder->createStructure();
825 throw std::runtime_error(
"+type:\"scalar\" requires +channel:");
829 const short dbr = dbChannelFinalFieldType(channel);
830 const long maxelem = dbChannelFinalElements(channel);
844 return new PVIFScalarNumeric<pvScalar, metaDOUBLE>(channel, fld, enclosing);
847 return new PVIFScalarNumeric<pvScalar, metaDOUBLE>(channel, fld, enclosing);
849 return new PVIFScalarNumeric<pvScalar, metaENUM>(channel, fld, enclosing);
851 return new PVIFScalarNumeric<pvScalar, metaSTRING>(channel, fld, enclosing);
869 return new PVIFScalarNumeric<pvArray, metaDOUBLE>(channel, fld, enclosing);
873 throw std::invalid_argument(
"Channel has invalid/unsupported DBR type");
878 struct PVIFPlain :
public PVIF 880 const typename PVD::shared_pointer field;
882 dbChannel *
const channel;
886 ,field(std::tr1::static_pointer_cast<PVD>(fld))
890 throw std::logic_error(
"PVIFPlain attached type mis-match");
892 fieldOffset = enclosing->getFieldOffset();
894 fieldOffset = field->getFieldOffset();
897 virtual ~PVIFPlain() {}
902 putValue(channel, field.get(), pfl);
903 mask.
set(fieldOffset);
910 bool newval = mask.get(fieldOffset);
913 getValue(channel, field.get());
931 if(mask.
get(fieldOffset) || mask.
get(0))
939 virtual ~PlainBuilder() {}
943 const short dbr = dbChannelFinalFieldType(channel);
944 const long maxelem = dbChannelFinalElements(channel);
948 throw std::invalid_argument(
"DBF code out of range");
959 virtual PVIF* attach(dbChannel *channel,
964 throw std::runtime_error(
"+type:\"plain\" requires +channel:");
965 const long maxelem = dbChannelFinalElements(channel);
971 return new PVIFPlain<pvd::PVScalar>(channel, fld, enclosing);
973 return new PVIFPlain<pvd::PVScalarArray>(channel, fld, enclosing);
979 virtual ~AnyScalarBuilder() {}
990 virtual PVIF* attach(dbChannel *channel,
995 throw std::runtime_error(
"+type:\"any\" requires +channel:");
997 const short dbr = dbChannelFinalFieldType(channel);
998 const long maxelem = dbChannelFinalElements(channel);
1006 throw std::logic_error(
"Mis-matched attachment point");
1011 arr = create->createPVScalar(pvt);
1013 arr = create->createPVScalarArray(pvt);
1018 return new PVIFPlain<pvd::PVScalar>(channel, arr, enclosing ? enclosing : arr.get());
1020 return new PVIFPlain<pvd::PVScalarArray>(channel, arr, enclosing ? enclosing : arr.get());
1025 struct PVIFMeta :
public PVIF 1034 throw std::logic_error(
"PVIFMeta attached type mis-match");
1035 meta.chan = channel;
1037 attachTime(meta, field);
1038 findNSMask(meta, info, field);
1039 findFormat(meta, info, field);
1041 meta.maskALWAYS.clear();
1042 meta.maskALWAYS.set(enclosing->getFieldOffset());
1043 meta.maskALARM.clear();
1044 meta.maskALARM.set(enclosing->getFieldOffset());
1048 virtual ~PVIFMeta() {}
1052 mask |= meta.maskALWAYS;
1054 mask |= meta.maskALARM;
1056 putTime(meta, dbe, pfl);
1062 if(mask.logical_and(meta.maskALARM))
1077 virtual ~MetaBuilder() {}
1081 throw std::logic_error(
"Don't call me");
1085 const std::string& fld,
1090 return builder->add(
"alarm", std->alarm())
1091 ->add(
"timeStamp", std->timeStamp());
1093 return builder->addNestedStructure(fld)
1094 ->add(
"alarm", std->alarm())
1095 ->add(
"timeStamp", std->timeStamp())
1103 virtual PVIF* attach(dbChannel *channel,
1108 throw std::runtime_error(
"+type:\"meta\" requires +channel:");
1113 return new PVIFMeta(channel, fld, enclosing);
1118 struct PVIFProc :
public PVIF 1120 PVIFProc(dbChannel *channel) :
PVIF(channel) {}
1143 throw std::logic_error(
"Don't call me");
1147 const std::string& fld,
1153 virtual PVIF* attach(dbChannel *channel,
1158 throw std::runtime_error(
"+type:\"proc\" requires +channel:");
1160 return new PVIFProc(channel);
1168 dbCommon *precord = dbChannelRecord(
chan);
1171 dbChannelField(
chan) == &precord->proc ||
1172 (dbChannelFldDes(
chan)->process_passive &&
1173 precord->scan == 0);
1181 }
else if (precord->pact) {
1183 printf(
"%s: Active %s\n",
1185 precord->rpro =
TRUE;
1188 precord->putf =
TRUE;
1189 long err = dbProcess(precord);
1193 std::ostringstream msg;
1194 msg<<
"process error : "<<buf;
1205 const std::string &fld,
1209 throw std::runtime_error(
"Can't attach this +type to root");
1213 builder = builder->add(fld, ftype);
1220 if(type.empty() || type==
"scalar")
1222 else if(type==
"plain")
1223 return new PlainBuilder;
1224 else if(type==
"any")
1225 return new AnyScalarBuilder;
1226 else if(type==
"meta")
1227 return new MetaBuilder;
1228 else if(type==
"proc")
1229 return new ProcBuilder;
1231 throw std::runtime_error(std::string(
"Unknown +type=")+type);
PVScalarValue< int32 > PVInt
virtual epics::pvData::FieldConstPtr dtype(dbChannel *channel)=0
static PVIFBuilder * create(const std::string &name)
PVScalar is the base class for each scalar field.
static Status warn(const std::string &m)
std::tr1::shared_ptr< PVInt > PVIntPtr
virtual epics::pvData::FieldConstPtr dtype(dbChannel *channel) OVERRIDE FINAL
size_t elementSize(ScalarType id)
gives sizeof(T) where T depends on the scalar type id.
pointer data() const
Return Base pointer.
virtual unsigned dbe(const epics::pvData::BitSet &mask)=0
Calculate DBE mask from changed bitset.
bool get(uint32 bitIndex) const
#define asCheckPut(asClientPvt)
static Status error(const std::string &m)
const char * info(const char *key, const char *def=0)
LIBCOM_API long epicsStdCall asAddClient(ASCLIENTPVT *asClientPvt, ASMEMBERPVT asMemberPvt, int asl, const char *user, char *host)
LIBCOM_API const char *epicsStdCall epicsThreadGetNameSelf(void)
pvd::StructureConstPtr type
virtual void put(epics::pvData::BitSet &mask, unsigned dbe, db_field_log *pfl)=0
#define INVALID_DB_REQ(x)
PVField is the base class for each PVData field.
std::tr1::shared_ptr< PVLong > PVLongPtr
std::tr1::shared_ptr< PVStringArray > PVStringArrayPtr
std::tr1::shared_ptr< FieldBuilder > FieldBuilderPtr
shared_vector< void > allocArray(ScalarType id, size_t len)
Allocate an untyped array based on ScalarType.
std::size_t getFieldOffset() const
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
std::tr1::shared_ptr< StandardField > StandardFieldPtr
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
#define READ_ACCESS_ALARM
virtual epics::pvData::Status get(const epics::pvData::BitSet &mask, proc_t proc=ProcInhibit, bool permit=true)=0
std::vector< std::vector< char > > groups
PVString is special case, since it implements SerializableArray.
FORCE_INLINE const StandardFieldPtr & getStandardField()
void getAs(shared_vector< const T > &out) const
void add(dbChannel *chan, ASCred &cred)
void push_back(param_type v)
LIBCOM_API void errSymLookup(long status, char *pBuf, size_t bufLength)
template class for all extensions of PVArray.
void update(const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &request)
#define NO_ALARM
The NO_ALARM value can be used as both a severity and a status.
Base class for a scalarArray.
std::tr1::shared_ptr< PVScalar > PVScalarPtr
LIBCOM_API long epicsStdCall asRemoveClient(ASCLIENTPVT *asClientPvt)
bool logical_and(const BitSet &other) const
Returns true if any bit is set in both *this and other.
#define POSIX_TIME_AT_EPICS_EPOCH
The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC.
PVUnion has a single subfield.
const ScalarArrayConstPtr getScalarArray() const
Data interface for a structure,.
std::tr1::shared_ptr< const Field > FieldConstPtr
int errlogPrintf(const char *pFormat,...)
size_t size() const
Number of elements visible through this vector.
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
epics::pvData::PVFieldPtr lookup(const epics::pvData::PVStructurePtr &S, epics::pvData::PVField **ppenclose) const
void put(typename storage_t::arg_type v)
PVScalarValue< int64 > PVLong
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< PVString > PVStringPtr
Class that holds the data for each possible scalar type.
std::tr1::shared_ptr< PVField > PVFieldPtr
void putFrom(const shared_vector< const T > &inp)
PVValueArray< std::string > PVStringArray
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
virtual PVIF * attach(dbChannel *channel, const epics::pvData::PVStructurePtr &root, const FieldName &fld) OVERRIDE FINAL
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
BitSet & set(uint32 bitIndex)
std::tr1::shared_ptr< PVScalarArray > PVScalarArrayPtr
LIBCOM_API const char * epicsAlarmConditionStrings[ALARM_NSTATUS]
How to convert an alarm condition/status into a string.
#define FMAP(MNAME, PVT, FNAME, DBE)
#define WRITE_ACCESS_ALARM
PVScalarValue< double > PVDouble
const char * name() const
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
std::tr1::shared_ptr< PVDouble > PVDoublePtr
short PVD2DBR(pvd::ScalarType pvt)
char dbf_STRING[MAX_STRING_SIZE]