From 2af78e5ff2ce93f4641bc4482ea62b2c598cbbd8 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 23 Mar 2016 15:40:18 -0400 Subject: [PATCH] pvif: handle scalar string fields --- pdbApp/pvif.cpp | 20 +++++++++++++++++++- testApp/testpvif.cpp | 38 +++++++++++++++++++++++++++++++++----- testApp/testpvif.db | 3 +++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/pdbApp/pvif.cpp b/pdbApp/pvif.cpp index b4e6c15..e128f66 100644 --- a/pdbApp/pvif.cpp +++ b/pdbApp/pvif.cpp @@ -142,6 +142,21 @@ struct metaENUM { enum {mask = DBR_STATUS | DBR_TIME | DBR_ENUM_STRS}; }; +struct metaSTRING { + DBRstatus + DBRtime + + // similar junk + DBRenumStrs + DBRunits + DBRprecision + DBRgrLong + DBRctrlLong + DBRalLong + + enum {mask = DBR_STATUS | DBR_TIME}; +}; + // lookup fields and populate pvCommon. Non-existant fields will be NULL. void attachMeta(pvCommon& pvm, const pvd::PVStructurePtr& pv) { @@ -262,6 +277,7 @@ void getValue(const pvScalar& pv) strncpy(buf.dbf_STRING, val.c_str(), sizeof(buf.dbf_STRING)); buf.dbf_STRING[sizeof(buf.dbf_STRING)-1] = '\0'; } + break; default: throw std::runtime_error("getValue unsupported DBR code"); } @@ -470,9 +486,9 @@ pvd::StructureConstPtr PVIF::dtype(dbChannel* chan) if(dbr==DBR_ENUM) return pvd::getStandardField()->enumerated("alarm,timeStamp"); + //TODO: ,valueAlarm for numeric std::string options("alarm,timeStamp,display,control"); - if(maxelem==1) return pvd::getStandardField()->scalar(pvt, options); else @@ -499,6 +515,8 @@ PVIF* PVIF::attach(dbChannel* chan, const epics::pvData::PVStructurePtr& root) return new PVIFScalarNumeric(chan, dbr, root); case DBR_ENUM: return new PVIFScalarNumeric(chan, dbr, root); + case DBR_STRING: + return new PVIFScalarNumeric(chan, dbr, root); } } else { switch(dbr) { diff --git a/testApp/testpvif.cpp b/testApp/testpvif.cpp index 57ffcb2..dcd8134 100644 --- a/testApp/testpvif.cpp +++ b/testApp/testpvif.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "pvif.h" #include "utilities.h" @@ -27,6 +28,7 @@ void testScalar() testdbReadDatabase("testpvif.db", NULL, NULL); longinRecord *prec_li = (longinRecord*)testdbRecordPtr("test:li"); + stringinRecord *prec_si = (stringinRecord*)testdbRecordPtr("test:si"); aiRecord *prec_ai = (aiRecord*)testdbRecordPtr("test:ai"); mbbiRecord *prec_mbbi = (mbbiRecord*)testdbRecordPtr("test:mbbi"); @@ -36,10 +38,12 @@ void testScalar() testdbGetFieldEqual("test:mbbi", DBR_SHORT, 1); DBCH chan_li("test:li"); + DBCH chan_si("test:si"); DBCH chan_ai("test:ai"); DBCH chan_ai_rval("test:ai.RVAL"); DBCH chan_mbbi("test:mbbi"); testEqual(dbChannelFieldType(chan_li), DBR_LONG); + testEqual(dbChannelFieldType(chan_si), DBR_STRING); testEqual(dbChannelFieldType(chan_ai), DBR_DOUBLE); testEqual(dbChannelFieldType(chan_ai_rval), DBR_LONG); testEqual(dbChannelFieldType(chan_mbbi), DBR_ENUM); @@ -49,12 +53,14 @@ void testScalar() testEqual(dbChannelFinalFieldType(chan_mbbi), DBR_ENUM); pvd::StructureConstPtr dtype_li(PVIF::dtype(chan_li)); + pvd::StructureConstPtr dtype_si(PVIF::dtype(chan_si)); pvd::StructureConstPtr dtype_ai(PVIF::dtype(chan_ai)); pvd::StructureConstPtr dtype_ai_rval(PVIF::dtype(chan_ai_rval)); pvd::StructureConstPtr dtype_mbbi(PVIF::dtype(chan_mbbi)); pvd::StructureConstPtr dtype_root(pvd::getFieldCreate()->createFieldBuilder() ->add("li", dtype_li) + ->add("si", dtype_si) ->add("ai", dtype_ai) ->add("ai_rval", dtype_ai_rval) ->add("mbbi", dtype_mbbi) @@ -63,6 +69,7 @@ void testScalar() pvd::PVStructurePtr root(pvd::getPVDataCreate()->createPVStructure(dtype_root)); std::auto_ptr pvif_li(PVIF::attach(chan_li, root->getSubField("li"))); + std::auto_ptr pvif_si(PVIF::attach(chan_si, root->getSubField("si"))); std::auto_ptr pvif_ai(PVIF::attach(chan_ai, root->getSubField("ai"))); std::auto_ptr pvif_ai_rval(PVIF::attach(chan_ai_rval, root->getSubField("ai_rval"))); std::auto_ptr pvif_mbbi(PVIF::attach(chan_mbbi, root->getSubField("mbbi"))); @@ -78,6 +85,15 @@ void testScalar() testEqual(toString(mask), "{2, 4, 5, 8, 9, 12, 13, 16, 18, 19}"); mask.clear(); + dbScanLock((dbCommon*)prec_si); + prec_si->time.secPastEpoch = 0x12345678; + prec_si->time.nsec = 12345678; + pvif_si->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); + dbScanUnlock((dbCommon*)prec_si); + + testEqual(toString(mask), "{22, 24, 25, 28, 29, 32, 33, 36, 38, 39}"); + mask.clear(); + dbScanLock((dbCommon*)prec_ai); prec_ai->time.secPastEpoch = 0x12345678; prec_ai->time.nsec = 12345678; @@ -85,7 +101,7 @@ void testScalar() pvif_ai_rval->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); dbScanUnlock((dbCommon*)prec_ai); - testEqual(toString(mask), "{22, 24, 25, 28, 29, 32, 33, 36, 38, 39, 42, 44, 45, 48, 49, 52, 53, 56, 58, 59}"); + testEqual(toString(mask), "{42, 44, 45, 48, 49, 52, 53, 56, 58, 59, 62, 64, 65, 68, 69, 72, 73, 76, 78, 79}"); mask.clear(); dbScanLock((dbCommon*)prec_mbbi); @@ -94,7 +110,7 @@ void testScalar() pvif_mbbi->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); dbScanUnlock((dbCommon*)prec_mbbi); - testEqual(toString(mask), "{63, 64, 66, 67, 70, 71, 72}"); + testEqual(toString(mask), "{83, 84, 86, 87, 90, 91, 92}"); mask.clear(); testFieldEqual(root, "li.value", 102042); @@ -105,6 +121,11 @@ void testScalar() testFieldEqual(root, "li.display.limitLow", 10.0); testFieldEqual(root, "li.display.units", "arb"); + testFieldEqual(root, "si.value", "hello"); + testFieldEqual(root, "si.alarm.severity", 0); + testFieldEqual(root, "si.timeStamp.secondsPastEpoch", 0x12345678+POSIX_TIME_AT_EPICS_EPOCH); + testFieldEqual(root, "si.timeStamp.nanoseconds", 12345678); + testFieldEqual(root, "ai.value", 42.2); testFieldEqual(root, "ai.alarm.severity", 2); testFieldEqual(root, "ai.timeStamp.secondsPastEpoch", 0x12345678+POSIX_TIME_AT_EPICS_EPOCH); @@ -138,19 +159,26 @@ void testScalar() } root->getSubFieldT("li.value")->put(102043); + root->getSubFieldT("si.value")->put("world"); root->getSubFieldT("ai.value")->put(44.4); root->getSubFieldT("mbbi.value.index")->put(2); mask.clear(); - mask.set(root->getSubFieldT("li.value")->getFieldOffset()); - mask.set(root->getSubFieldT("ai.value")->getFieldOffset()); - mask.set(root->getSubFieldT("mbbi.value.index")->getFieldOffset()); + mask.set(root->getSubFieldT("li.value")->getFieldOffset()); + mask.set(root->getSubFieldT("si.value")->getFieldOffset()); + mask.set(root->getSubFieldT("ai.value")->getFieldOffset()); + mask.set(root->getSubFieldT("mbbi.value.index")->getFieldOffset()); dbScanLock((dbCommon*)prec_li); pvif_li->get(mask); testOk1(prec_li->val==102043); dbScanUnlock((dbCommon*)prec_li); + dbScanLock((dbCommon*)prec_si); + pvif_si->get(mask); + testOk1(strcmp(prec_si->val, "world")==0); + dbScanUnlock((dbCommon*)prec_si); + dbScanLock((dbCommon*)prec_ai); pvif_ai->get(mask); testOk1(prec_ai->val==44.4); diff --git a/testApp/testpvif.db b/testApp/testpvif.db index 68c0de6..eac3ac9 100644 --- a/testApp/testpvif.db +++ b/testApp/testpvif.db @@ -27,3 +27,6 @@ record(mbbi, "test:mbbi") { field(TWVL, "3") info(pdbUserTag, "nslsb4") } +record(stringin, "test:si") { + field(VAL, "hello") +}