2 #include <epicsStdio.h>
5 #include <dbStaticLib.h>
8 #include <epicsString.h>
9 #include <epicsVersion.h>
11 #include <pv/status.h>
12 #include <pv/bitSet.h>
13 #include <pv/pvData.h>
14 #include <pv/anyscalar.h>
18 namespace pvd = epics::pvData;
22 pvd::ScalarType DBR2PVD(
short dbr)
25 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case DBR_##DBFTYPE: return pvd::pv##PVACODE;
26 #define CASE_SKIP_BOOL
27 #define CASE_REAL_INT64
28 #include "pv/typemap.h"
30 #undef CASE_REAL_INT64
32 case DBF_ENUM:
return pvd::pvUShort;
33 case DBF_STRING:
return pvd::pvString;
35 throw std::invalid_argument(
"Unsupported DBR code");
38 long copyPVD2DBF(
const pvd::PVField::const_shared_pointer& inraw,
39 void *outbuf,
short outdbf,
long *outnReq)
41 long nreq = outnReq ? *outnReq : 1;
42 if(!inraw || nreq <= 0 || INVALID_DB_REQ(outdbf))
return S_db_errArg;
44 pvd::ScalarType outpvd = DBR2PVD(outdbf);
46 pvd::PVField::const_shared_pointer in(inraw);
48 if(outdbf != DBF_STRING && in->getField()->getType() == pvd::structure) {
51 in =
static_cast<const pvd::PVStructure*
>(in.get())->getSubField(
"index");
52 if(!in)
return S_db_errArg;
55 if(in->getField()->getType() == pvd::structure) {
56 assert(outdbf == DBF_STRING);
57 char *outsbuf = (
char*)outbuf;
61 const pvd::PVStructure* sin =
static_cast<const pvd::PVStructure*
>(in.get());
63 pvd::PVScalar::const_shared_pointer index(sin->getSubField<pvd::PVScalar>(
"index"));
64 if(!index)
return S_db_badField;
70 pvd::uint16 ival = index->getAs<pvd::uint16>();
73 pvd::PVStringArray::const_shared_pointer choices(sin->getSubField<pvd::PVStringArray>(
"choices"));
76 pvd::PVStringArray::const_svector strs(choices->view());
78 if(ival < strs.size()) {
81 const std::string& sval = strs[ival];
82 size_t slen = std::min(sval.size(), size_t(MAX_STRING_SIZE-1));
83 memcpy(outbuf, sval.c_str(), slen);
91 epicsSnprintf(outsbuf, MAX_STRING_SIZE,
"%u", ival);
94 }
else if(in->getField()->getType() == pvd::scalarArray) {
95 const pvd::PVScalarArray* sarr =
static_cast<const pvd::PVScalarArray*
>(in.get());
96 pvd::shared_vector<const void> arr;
98 size_t elemsize = pvd::ScalarTypeFunc::elementSize(arr.original_type());
100 arr.slice(0, nreq*elemsize);
101 nreq = arr.size()/elemsize;
103 if(outdbf == DBF_STRING) {
104 char *outsbuf = (
char*)outbuf;
107 pvd::shared_vector<std::string> strs(nreq);
109 pvd::castUnsafeV(nreq, pvd::pvString, strs.data(), arr.original_type(), arr.data());
111 for(
long i =0; i<nreq; i++, outsbuf += MAX_STRING_SIZE) {
112 size_t slen = std::min(strs[i].size(),
size_t(MAX_STRING_SIZE-1));
113 memcpy(outsbuf, strs[i].c_str(), slen);
114 outsbuf[slen] =
'\0';
118 pvd::castUnsafeV(nreq, outpvd, outbuf, arr.original_type(), arr.data());
125 }
else if(in->getField()->getType() == pvd::scalar) {
126 char *outsbuf = (
char*)outbuf;
127 const pvd::PVScalar* sval =
static_cast<const pvd::PVScalar*
>(in.get());
131 if(outdbf == DBF_STRING && val.type()==pvd::pvString) {
133 size_t len = std::min(val.as<std::string>().size(), size_t(MAX_STRING_SIZE-1));
135 memcpy(outbuf, val.as<std::string>().c_str(), len);
138 }
else if(outdbf == DBF_STRING) {
142 pvd::castUnsafeV(1, pvd::pvString, &temp, val.type(), val.unsafe());
144 size_t len = std::min(temp.size(), size_t(MAX_STRING_SIZE-1));
146 memcpy(outbuf, temp.c_str(), len);
151 pvd::castUnsafeV(1, outpvd, outbuf, val.type(), val.unsafe());
160 return S_dbLib_badField;
164 long copyDBF2PVD(
const pvd::shared_vector<const void> &inbuf,
165 const pvd::PVField::shared_pointer& outraw,
166 pvd::BitSet& changed,
167 const pvd::PVStringArray::const_svector &choices)
170 pvd::ScalarType inpvd = inbuf.original_type();
171 size_t incnt = inbuf.size()/pvd::ScalarTypeFunc::elementSize(inpvd);
173 if(!outraw)
return S_db_errArg;
175 pvd::PVField::shared_pointer out(outraw);
177 if(inpvd != pvd::pvString && out->getField()->getType() == pvd::structure) {
180 out =
static_cast<pvd::PVStructure*
>(out.get())->getSubField(
"index");
181 if(!out)
return S_db_errArg;
184 if(out->getField()->getType() == pvd::structure) {
185 assert(inpvd == pvd::pvString);
190 const pvd::shared_vector<const std::string> insbuf(pvd::static_shared_vector_cast<const std::string>(inbuf));
191 const std::string& instr(insbuf[0]);
195 pvd::PVStructure* sout =
static_cast<pvd::PVStructure*
>(out.get());
197 pvd::PVScalar::shared_pointer index(sout->getSubField<pvd::PVScalar>(
"index"));
198 if(!index)
return S_db_badField;
200 pvd::uint16 result = pvd::uint16(-1);
203 for(
size_t i=0, N=std::min(
size_t(0xffff), choices.size()); i<N; i++) {
204 if(choices[i] == instr) {
206 result = pvd::uint16(i);
214 result = pvd::castUnsafe<pvd::uint16>(instr);
215 }
catch(std::exception&){
220 index->putFrom(result);
224 }
else if(out->getField()->getType() == pvd::scalarArray) {
225 pvd::PVScalarArray* sarr =
static_cast<pvd::PVScalarArray*
>(out.get());
227 sarr->putFrom(inbuf);
229 }
else if(out->getField()->getType() == pvd::scalar) {
230 pvd::PVScalar* sval =
static_cast<pvd::PVScalar*
>(out.get());
232 if(incnt==0)
return S_db_errArg;
234 pvd::AnyScalar val(inpvd, inbuf.data());
240 return S_db_badField;
243 changed.set(out->getFieldOffset());