9 #include <dbStaticLib.h>
12 #include <epicsVersion.h>
14 #include <pv/status.h>
15 #include <pv/bitSet.h>
16 #include <pv/pvData.h>
17 #include <pv/anyscalar.h>
22 # define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
25 #ifndef EPICS_VERSION_INT
26 # define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
29 #if EPICS_VERSION_INT>=VERSION_INT(3,16,0,2)
30 # define USE_MULTILOCK
44 class ChannelRequester;
48 short PVD2DBR(epics::pvData::ScalarType pvt);
52 long copyPVD2DBF(
const epics::pvData::PVField::const_shared_pointer& in,
53 void *outbuf,
short outdbf,
long *outnReq);
56 long copyDBF2PVD(
const epics::pvData::shared_vector<const void>& buf,
57 const epics::pvData::PVField::shared_pointer& out,
58 epics::pvData::BitSet &changed,
59 const epics::pvData::PVStringArray::const_svector& choices);
65 epicsUInt16 dbf_USHORT;
68 epicsUInt32 dbf_ULONG;
69 epicsFloat32 dbf_FLOAT;
70 epicsFloat64 dbf_DOUBLE;
72 #ifdef EPICS_VERSION_INT
73 # if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
75 epicsUInt64 dbf_UINT64;
78 char dbf_STRING[MAX_STRING_SIZE];
84 explicit DBCH(dbChannel *ch);
85 explicit DBCH(
const std::string& name);
90 operator dbChannel*() {
return chan; }
91 operator const dbChannel*()
const {
return chan; }
92 dbChannel *operator->() {
return chan; }
93 const dbChannel *operator->()
const {
return chan; }
102 std::vector<char> user, host;
103 std::vector<std::vector<char> > groups;
104 void update(
const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& request);
109 std::vector<ASCLIENTPVT> grppvt;
113 void add(dbChannel* chan,
ASCred& cred);
121 dbInitEntry(pdbbase, &ent);
122 if(dbFindRecordPart(&ent, &name))
123 throw std::runtime_error(ent.message);
129 const char *info(
const char *key,
const char *def =0)
131 if(dbFindInfo(&ent, key))
133 return dbGetInfoString(&ent);
142 dbInitEntry(pdbbase, &ent);
143 m_done = dbFirstRecordType(&ent)!=0;
145 if(dbFirstRecord(&ent)==0)
148 m_done = dbNextRecordType(&ent)!=0;
153 #if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
154 dbInitEntryFromRecord(dbChannelRecord(chan), &ent);
156 dbInitEntry(pdbbase, &ent);
157 if(dbFindRecord(&ent, dbChannelRecord(chan)->name)!=0)
158 throw std::logic_error(
"Record not found");
162 #if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0)
165 dbInitEntryFromRecord(prec, &ent);
173 bool done()
const {
return m_done; }
175 if(!m_done && dbNextRecord(&ent)!=0)
179 m_done = dbNextRecordType(&ent)!=0;
181 if(dbFirstRecord(&ent)==0)
188 dbCommon* record()
const {
189 return m_done ? NULL : (dbCommon*)ent.precnode->precord;
191 const char *name()
const {
192 return m_done ? NULL : ent.precnode->recordname;
194 const char *info(
const char *key,
const char *def =0)
196 if(m_done || dbFindInfo(&ent, key))
198 return dbGetInfoString(&ent);
207 dbCopyEntryContents(&const_cast<pdbRecordIterator&>(I).ent, &ent);
208 m_done = dbFirstInfo(&ent)!=0;
214 bool done()
const {
return m_done; }
216 m_done = dbNextInfo(&ent)!=0;
219 const char *name() {
return dbGetInfoName(&ent); }
220 const char *value() {
return dbGetInfoString(&ent); }
225 dbEventSubscription subscript;
230 DBEvent() :subscript(NULL),
self(NULL), index(0) {}
231 DBEvent(
void* s) :subscript(NULL),
self(s), index(0) {}
233 void create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn,
unsigned mask)
235 subscript = db_add_event(ctx, ch, fn,
this, mask);
237 throw std::runtime_error(
"Failed to subscribe to dbEvent");
242 if(subscript) db_cancel_event(subscript);
244 bool operator!()
const {
return !subscript; }
254 LocalFL(db_field_log *pfl, dbChannel *pchan)
258 if(!pfl && (ellCount(&pchan->pre_chain)!=0 || ellCount(&pchan->post_chain)!=0)) {
259 pfl = db_create_read_log(pchan);
262 pfl = dbChannelRunPreChain(pchan, pfl);
263 if(pfl) pfl = dbChannelRunPostChain(pchan, pfl);
269 if(ours) db_delete_field_log(pfl);
276 DBScanLocker(dbChannel *chan) :prec(dbChannelRecord(chan))
277 { dbScanLock(prec); }
279 { dbScanLock(prec); }
281 { dbScanUnlock(prec); }
289 DBManyLock() :plock(NULL) {}
290 DBManyLock(
const std::vector<dbCommon*>& recs,
unsigned flags=0)
291 :plock(dbLockerAlloc( (recs.size() > 0 ? (dbCommon**)&recs[0] : NULL), recs.size(), flags))
293 if(!plock)
throw std::invalid_argument(
"Failed to create locker");
295 DBManyLock(dbCommon *
const *precs,
size_t nrecs,
unsigned flags=0)
296 :plock(dbLockerAlloc((dbCommon**)precs, nrecs, flags))
298 if(!plock)
throw std::invalid_argument(
"Failed to create locker");
300 ~DBManyLock() {
if(plock) dbLockerFree(plock); }
301 void swap(DBManyLock& O) { std::swap(plock, O.plock); }
302 operator dbLocker*() {
return plock; }
304 DBManyLock(
const DBManyLock&);
305 DBManyLock& operator=(
const DBManyLock&);
311 DBManyLocker(dbLocker *L) :plock(L)
313 dbScanLockMany(plock);
317 dbScanUnlockMany(plock);
328 Component(
const std::string& name, epicsUInt32 index = (epicsUInt32)-1)
329 :name(name), index(index)
331 bool isArray()
const {
return index!=(epicsUInt32)-1; }
333 typedef std::vector<Component> parts_t;
343 bool empty()
const {
return parts.empty(); }
344 size_t size()
const {
return parts.size(); }
345 const Component& operator[](
size_t i)
const {
return parts[i]; }
346 const Component& back()
const {
return parts.back(); }
351 epics::pvData::PVFieldPtr
352 lookup(
const epics::pvData::PVStructurePtr& S, epics::pvData::PVField** ppenclose)
const;
356 #if !defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
369 dbChannel *
const chan;
379 virtual void put(epics::pvData::BitSet& mask,
unsigned dbe, db_field_log *pfl) =0;
382 virtual epics::pvData::Status
get(
const epics::pvData::BitSet& mask, proc_t proc=ProcInhibit,
bool permit=
true) =0;
384 virtual unsigned dbe(
const epics::pvData::BitSet& mask) =0;
388 PVIF& operator=(
const PVIF&);
405 dbChannel*
const channel;
410 virtual epics::pvData::FieldConstPtr dtype() =0;
412 virtual epics::pvData::FieldBuilderPtr dtype(epics::pvData::FieldBuilderPtr& builder,
413 const std::string& fld);
418 virtual PVIF* attach(
const epics::pvData::PVStructurePtr& root,
const FieldName& fld) =0;
421 static PVIFBuilder* create(
const std::string& mapname, dbChannel* chan);
423 explicit PVIFBuilder(dbChannel* chan) : channel(chan) {}
432 virtual ~ScalarBuilder() {}
434 virtual epics::pvData::FieldConstPtr dtype() OVERRIDE FINAL;
435 virtual PVIF* attach(
const epics::pvData::PVStructurePtr& root,
const FieldName& fld) OVERRIDE FINAL;