diff --git a/ioc/pvalink_lset.cpp b/ioc/pvalink_lset.cpp index bde7ebe..989afda 100644 --- a/ioc/pvalink_lset.cpp +++ b/ioc/pvalink_lset.cpp @@ -252,7 +252,7 @@ long pvaGetValue(DBLINK *plink, short dbrType, void *pbuffer, long *pnRequest) n auto nReq(pnRequest ? *pnRequest : 1); auto value(self->fld_value); - if(value.type()==TypeCode::Any) + if(value.type()==TypeCode::Any || value.type()==TypeCode::Union) value = value.lookup("->"); if(nReq <= 0 || !value) { diff --git a/test/testnt.cpp b/test/testnt.cpp index 1630e23..05eb5ed 100644 --- a/test/testnt.cpp +++ b/test/testnt.cpp @@ -53,6 +53,12 @@ void testNTNDArray() auto top = nt::NTNDArray{}.create(); testTrue(top.idStartsWith("epics:nt/NTNDArray:"))<<"\n"<floatValue"] = shared_array({0.1, 0.2, 0.3, 0.4, 0.5}); + testEq(top["value"].type(), TypeCode::Union); + top = top["value"].lookup("->"); + testEq(top.type(), TypeCode::Float32A); + } void testNTURI() @@ -108,7 +114,7 @@ void testNTTable() } // namespace MAIN(testnt) { - testPlan(22); + testPlan(24); testNTScalar(); testNTNDArray(); testNTURI(); diff --git a/test/testpvalink.cpp b/test/testpvalink.cpp index 6a664c5..91daf54 100644 --- a/test/testpvalink.cpp +++ b/test/testpvalink.cpp @@ -477,13 +477,50 @@ namespace { testdbGetFieldEqual("enum:tgt:b", DBR_STRING, "one"); testTodoEnd(); } + + void testNTNDArray() + { + testDiag("==== %s ====", __func__); + auto serv(ioc::server()); + + auto ntndarray(server::SharedPV::buildReadonly()); + auto top = nt::NTNDArray{}.create(); + top["value->floatValue"] = shared_array({0.0}); + ntndarray.open(top); + serv.addPV("source:ntndarray", ntndarray); + + testqsrvWaitForLinkConnected("target:ntndarray_inp.INP"); + + { + QSrvWaitForLinkUpdate A("target:ntndarray_inp.INP"); + auto update = ntndarray.fetch().cloneEmpty(); + update["value->floatValue"] = shared_array({0.1, 0.2, 0.3, 0.4, 0.5}); + ntndarray.post(update); + } + static const epicsFloat32 expected_float_A[] = {0.1, 0.2, 0.3, 0.4, 0.5}; + testdbGetArrFieldEqual("target:ntndarray_inp", DBF_FLOAT, 5, 5, expected_float_A); + + { + QSrvWaitForLinkUpdate B("target:ntndarray_inp.INP"); + auto update = ntndarray.fetch().cloneEmpty(); + update["value->floatValue"] = shared_array({0.6, 0.7, 0.8, 0.9, 0.91}); + ntndarray.post(update); + } + static const epicsFloat32 expected_float_B[] = {0.6, 0.7, 0.8, 0.9, 0.91}; + testdbGetArrFieldEqual("target:ntndarray_inp", DBF_FLOAT, 5, 5, expected_float_B); + + serv.removePV("source:ntndarray"); + ntndarray.close(); + } + + } // namespace extern "C" void testioc_registerRecordDeviceDriver(struct dbBase *); MAIN(testpvalink) { - testPlan(92); + testPlan(94); testSetup(); pvxs::logger_config_env(); @@ -512,6 +549,7 @@ MAIN(testpvalink) testFwd(); testAtomic(); testEnum(); + testNTNDArray(); } catch (std::exception &e) { diff --git a/test/testpvalink.db b/test/testpvalink.db index 082a885..66c65f8 100644 --- a/test/testpvalink.db +++ b/test/testpvalink.db @@ -204,3 +204,9 @@ record(waveform, "sarr:inp") { field(FTVL, "STRING") field(NELM, "16") } + +record(aai, "target:ntndarray_inp") { + field(INP, {pva:{pv:"source:ntndarray", proc:"CP"}}) # created programatically with pvxs::server::SharedPV + field(NELM, "5") + field(FTVL, "FLOAT") +}