diff --git a/src/data.cpp b/src/data.cpp index a3bc571..8dcb7dd 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -619,15 +619,28 @@ void Value::copyIn(const void *ptr, StoreType type) // assign array of Struct/Union/Any auto tsrc = src.castTo(); + bool convert = false; if(desc->code!=TypeCode::AnyA) { // enforce member type for Struct[] and Union[] for(auto& val : tsrc) { if(val.desc && val.desc!=desc->members.data()) { - throw NoConvert(SB()<<"Unable to assign "<code<<" with "< scratch(tsrc.size()); + for(auto i : range(tsrc.size())) { + if(tsrc[i]) { + scratch[i] = allocMember(); + scratch[i].assign(tsrc[i]); + } + } + dest = scratch.freeze().castTo(); + } } - dest = src; + if(!convert) + dest = src; } else if(src.original_type()!=ArrayType::Value && uint8_t(desc->code.code)==uint8_t(src.original_type())) { // assign array of scalar w/o convert @@ -676,7 +689,7 @@ void Value::copyIn(const void *ptr, StoreType type) for(auto i : range(desc->miter.size())) { auto idx(desc->miter[i].second); - if(src.desc!=&desc->members[idx]) + if(!_equal(src.desc, &desc->members[idx])) continue; std::shared_ptr udesc(store->top->desc, &desc->members[idx]); diff --git a/test/testdata.cpp b/test/testdata.cpp index 960bbc8..8b99941 100644 --- a/test/testdata.cpp +++ b/test/testdata.cpp @@ -358,6 +358,56 @@ void testAssignSimilar() } } +void testAssignSimilarNDArray() +{ + testShow()<<__func__; + + Value val1, val2; + using namespace pvxs::members; + { + auto def(nt::NTNDArray{}.build()); + def += { + StructA("dimensions", { + Int32("val1"), + }), + }; + val1 = def.create(); + } + { + auto def(nt::NTNDArray{}.build()); + def += { + StructA("dimensions", { + Int32("val2"), + }), + }; + val2 = def.create(); + } + + testFalse(val1.equalType(val2)); + testTrue(val1["dimension"].equalType(val2["dimension"])); + + val1.from(val2); // nothing marked, so a no-op + + shared_array pixels({1,2,3,4,5,6}); + val1["value->ubyteValue"] = pixels; + shared_array dims;//(2); + dims.resize(2); + dims[0] = val1["dimension"].allocMember() + .update("size", 12); + dims[1] = dims[0].cloneEmpty() + .update("size", 34); + val1["dimension"] = dims.freeze(); + + val2.from(val1); + + testTrue(val2["value"].isMarked(false,false)); + testTrue(val2["dimension"].isMarked(false,false)); + testFalse(val2["timeStamp"].isMarked(true, true)); + testArrEq(pixels, val2["value"].as>()); + testEq(val2["dimension[0].size"].as(), 12u); + testEq(val2["dimension[1].size"].as(), 34u); +} + void testUnionMagicAssign() { testShow()<<__func__; @@ -445,7 +495,7 @@ void testClear() MAIN(testdata) { - testPlan(148); + testPlan(156); testSetup(); testTraverse(); testAssign(); @@ -496,6 +546,7 @@ MAIN(testdata) testConvertScalar2(0, 0x100000000llu, -0); testAssignSimilar(); + testAssignSimilarNDArray(); testUnionMagicAssign(); testExtract(); testClear();