diff --git a/src/factory/pvSubArrayCopy.cpp b/src/factory/pvSubArrayCopy.cpp index 45d57ba..7129fe8 100644 --- a/src/factory/pvSubArrayCopy.cpp +++ b/src/factory/pvSubArrayCopy.cpp @@ -164,7 +164,7 @@ void copy( if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1"); StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray(); StructureArrayConstPtr toStructure = pvTo.getStructureArray(); - if(pvFromStructure!=toStructure) { + if(pvFromStructure->getStructure()!=toStructure->getStructure()) { throw std::invalid_argument( "pvSubArrayCopy structureArray pvTo and pvFrom have different structures"); } @@ -185,6 +185,42 @@ void copy( pvTo.replace(temp2); } +void copy( + PVUnionArray & pvFrom, + size_t pvFromOffset, + size_t pvFromStride, + PVUnionArray & pvTo, + size_t toOffset, + size_t toStride, + size_t count) +{ + if(pvTo.isImmutable()) { + throw std::logic_error("pvSubArrayCopy pvTo is immutable"); + } + if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1"); + UnionArrayConstPtr pvFromUnion = pvFrom.getUnionArray(); + UnionArrayConstPtr toUnion = pvTo.getUnionArray(); + if(pvFromUnion->getUnion()!=toUnion->getUnion()) { + throw std::invalid_argument( + "pvSubArrayCopy unionArray pvTo and pvFrom have different unions"); + } + size_t pvFromLength = pvFrom.getLength(); + size_t num = pvFromOffset + count*pvFromStride; + if(num>pvFromLength) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); + size_t newLength = toOffset + count*toStride; + size_t capacity = pvTo.getCapacity(); + if(newLength>capacity) capacity = newLength; + shared_vector temp(capacity); + PVValueArray::const_svector vecFrom = pvFrom.view(); + PVValueArray::const_svector vecTo = pvTo.view(); + for(size_t i=0; icreatePVUnion(toUnion->getUnion()); + for(size_t i=0; i temp2(freeze(temp)); + pvTo.replace(temp2); +} + void copy( PVArray & pvFrom, size_t pvFromOffset, @@ -215,6 +251,11 @@ void copy( dynamic_cast(pvTo), pvToOffset,pvToStride,count); } + if(pvFromType==unionArray) { + copy(dynamic_cast(pvFrom) ,pvFromOffset,pvFromStride, + dynamic_cast(pvTo), + pvToOffset,pvToStride,count); + } } void copy(