diff --git a/src/factory/pvSubArrayCopy.cpp b/src/factory/pvSubArrayCopy.cpp index e030488..0c11362 100644 --- a/src/factory/pvSubArrayCopy.cpp +++ b/src/factory/pvSubArrayCopy.cpp @@ -33,8 +33,8 @@ void copy( if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable"); if(fromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1"); size_t fromLength = pvFrom.getLength(); - size_t num = fromOffset + count*fromStride; - if(num>fromLength) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); + size_t maxcount = (fromLength -fromOffset + fromStride -1)/fromStride; + if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); size_t newLength = toOffset + count*toStride; size_t capacity = pvTo.getCapacity(); if(newLength>capacity) capacity = newLength; @@ -166,13 +166,13 @@ 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"); } size_t pvFromLength = pvFrom.getLength(); - size_t num = pvFromOffset + count*pvFromStride; - if(num>pvFromLength) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); + size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride; + if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); size_t newLength = toOffset + count*toStride; size_t capacity = pvTo.getCapacity(); if(newLength>capacity) capacity = newLength; @@ -187,6 +187,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 maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride; + if(count>maxcount) 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, @@ -217,6 +253,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(