diff --git a/pvDataApp/factory/pvSubArrayCopy.cpp b/pvDataApp/factory/pvSubArrayCopy.cpp index c89aef2..405e677 100644 --- a/pvDataApp/factory/pvSubArrayCopy.cpp +++ b/pvDataApp/factory/pvSubArrayCopy.cpp @@ -15,30 +15,32 @@ #include namespace epics { namespace pvData { +using std::cout; +using std::endl; template void copy( PVValueArray & pvFrom, size_t fromOffset, + size_t fromStride, PVValueArray & pvTo, size_t toOffset, - size_t len) + size_t toStride, + size_t count) { - if(pvTo.isImmutable()) { - throw std::logic_error("pvSubArrayCopy to is immutable"); - } + 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(); - if(fromOffset+len>fromLength) { - throw std::length_error("pvSubArrayCopy from length error"); - } + size_t num = fromOffset + count*fromStride; + if(num>fromLength) throw std::invalid_argument("pvSubArrayCopy pvFrom length error"); + size_t newLength = toOffset + count*toStride; size_t capacity = pvTo.getCapacity(); - if(toOffset+len>capacity) capacity = toOffset + len; + if(newLength>capacity) capacity = newLength; shared_vector temp(capacity); typename PVValueArray::const_svector vecFrom = pvFrom.view(); typename PVValueArray::const_svector vecTo = pvTo.view(); - for(size_t i=0; i temp2(freeze(temp)); pvTo.replace(temp2); } @@ -46,9 +48,11 @@ void copy( void copy( PVScalarArray & from, size_t fromOffset, + size_t fromStride, PVScalarArray & to, size_t toOffset, - size_t len) + size_t toStride, + size_t count) { ScalarType scalarType = from.getScalarArray()->getElementType(); ScalarType otherType = to.getScalarArray()->getElementType(); @@ -59,146 +63,168 @@ void copy( { case pvBoolean: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvByte: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvShort: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvInt: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvLong: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvUByte: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvUShort: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvUInt: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvULong: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvFloat: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvDouble: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; case pvString: { - copy(dynamic_cast &>(from),fromOffset, + copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), - toOffset,len); + toOffset,toStride,count); } break; } } void copy( - PVStructureArray & from, - size_t fromOffset, - PVStructureArray & to, + PVStructureArray & pvFrom, + size_t pvFromOffset, + size_t pvFromStride, + PVStructureArray & pvTo, size_t toOffset, - size_t len) + size_t toStride, + size_t count) { - if(to.isImmutable()) { - throw std::logic_error("pvSubArrayCopy to is immutable"); + if(pvTo.isImmutable()) { + throw std::logic_error("pvSubArrayCopy pvTo is immutable"); } - StructureArrayConstPtr fromStructure = from.getStructureArray(); - StructureArrayConstPtr toStructure = to.getStructureArray(); - if(fromStructure!=toStructure) { + if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1"); + StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray(); + StructureArrayConstPtr toStructure = pvTo.getStructureArray(); + if(pvFromStructure!=toStructure) { throw std::invalid_argument( - "pvSubArrayCopy structureArray to and from have different structures"); + "pvSubArrayCopy structureArray pvTo and pvFrom have different structures"); } - size_t fromLength = from.getLength(); - if(fromOffset+len>fromLength) { - throw std::length_error("pvSubArrayCopy from length error"); - } - size_t capacity = to.getCapacity(); - if(toOffset+len>capacity) capacity = toOffset+len; + 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 = from.view(); - PVValueArray::const_svector vecTo = to.view(); - for(size_t i=0; i::const_svector vecFrom = pvFrom.view(); + PVValueArray::const_svector vecTo = pvTo.view(); + for(size_t i=0; i temp2(freeze(temp)); - to.replace(temp2); + pvTo.replace(temp2); } void copy( - PVArray & from, - size_t fromOffset, - PVArray & to, - size_t toOffset, - size_t len) + PVArray & pvFrom, + size_t pvFromOffset, + size_t pvFromStride, + PVArray & pvTo, + size_t pvToOffset, + size_t pvToStride, + size_t count) { - Type type = from.getField()->getType(); - Type otherType = to.getField()->getType(); - if(type!=otherType) { - throw std::invalid_argument("pvSubArrayCopy types do not match"); + Type pvFromType = pvFrom.getField()->getType(); + Type pvToType = pvTo.getField()->getType(); + if(pvFromType!=pvToType) throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types"); + if(pvFromType==scalarArray) { + ScalarType pvFromScalarType= static_cast(pvFromType); + ScalarType pvToScalarType = static_cast(pvToType); + if(pvFromScalarType!=pvToScalarType){ + throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types"); + } } - if(type==scalarArray) { - copy(dynamic_cast(from) ,fromOffset, - dynamic_cast(to), - toOffset,len); + if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable"); + if(pvFromType==scalarArray) { + copy(dynamic_cast(pvFrom) ,pvFromOffset,pvFromStride, + dynamic_cast(pvTo), + pvToOffset,pvToStride,count); } - if(type==structureArray) { - copy(dynamic_cast(from) ,fromOffset, - dynamic_cast(to), - toOffset,len); + if(pvFromType==structureArray) { + copy(dynamic_cast(pvFrom) ,pvFromOffset,pvFromStride, + dynamic_cast(pvTo), + pvToOffset,pvToStride,count); } } +void copy( + PVArray::shared_pointer const & pvFrom, + size_t pvFromOffset, + size_t pvFromStride, + PVArray::shared_pointer & pvTo, + size_t pvToOffset, + size_t pvToStride, + size_t count) +{ + copy(*pvFrom,pvFromOffset,pvFromStride,*pvTo,pvToOffset,pvToStride,count); +} + }} diff --git a/pvDataApp/pv/pvSubArrayCopy.h b/pvDataApp/pv/pvSubArrayCopy.h index 79110b9..04de8b6 100644 --- a/pvDataApp/pv/pvSubArrayCopy.h +++ b/pvDataApp/pv/pvSubArrayCopy.h @@ -17,68 +17,104 @@ namespace epics { namespace pvData { -/** @brief Copy a subarray from one PVValueArray to another. - * @warning The two PVValueArrays must both the same type - * @param from The source - * @param fromOffset The offset in the source - * @param to The destination - * @param toOffset The offset in the destination - * @param len The total number of elements to copy +/** @brief Copy a subarray from one scalar array to another. + * @warning The two scalar arrays must both be PVValueArrays of the same type. + * @param pvFrom The source array. + * @param fromOffset The offset in the source. + * @param fromStride The interval between elements in pvFrom. + * @param pvTo The destination array. + * @param toOffset The offset in the destination. + * @param toStride The interval between elements in pvTo. + * @param count The total number of elements to copy from pvFrom to pvTo. */ template -void copy( +epicsShareExtern void copy( PVValueArray & pvFrom, size_t fromOffset, + size_t fromStride, PVValueArray & pvTo, size_t toOffset, - size_t len); + size_t toStride, + size_t count); /** @brief Copy a subarray from one scalar array to another. - * @warning The two scalar arrays must both be PVValueArrays of the same type - * @param from The source - * @param fromOffset The offset in the source - * @param to The destination - * @param toOffset The offset in the destination - * @param len The total number of elements to copy + * @warning The two scalar arrays must both be PVValueArrays of the same type. + * @param pvFrom The source array. + * @param fromOffset The offset in the source. + * @param fromStride The interval between elements in pvFrom. + * @param pvTo The destination array. + * @param toOffset The offset in the destination. + * @param toStride The interval between elements in pvTo. + * @param count The total number of elements to copy from pvFrom to pvTo. */ epicsShareExtern void copy( - PVScalarArray & from, + PVScalarArray & pvFrom, size_t fromOffset, - PVScalarArray & to, + size_t fromStride, + PVScalarArray & pvTo, size_t toOffset, - size_t len); + size_t toStride, + size_t count); /** @brief Copy a subarray from one structure array to another. * @warning The two structure arrays must have the same * structure introspection interface. - * @param from The source - * @param fromOffset The offset in the source - * @param to The destination - * @param toOffset The offset in the destination - * @param len The total number of elements to copy + * @param pvFrom The source array. + * @param fromOffset The offset in the source. + * @param fromStride The interval between elements in pvFrom. + * @param pvTo The destination array. + * @param toOffset The offset in the destination. + * @param toStride The interval between elements in pvTo. + * @param count The total number of elements to copy from pvFrom to pvTo. */ epicsShareExtern void copy( - PVStructureArray & from, + PVStructureArray & pvFrom, size_t fromOffset, - PVStructureArray & to, + size_t fromStride, + PVStructureArray & pvToo, size_t toOffset, - size_t len); + size_t toStride, + size_t count); /** @brief Copy a subarray from one array to another. * @warning The two arrays must have the same * introspection interface. - * @param from The source - * @param fromOffset The offset in the source - * @param to The destination - * @param toOffset The offset in the destination - * @param len The total number of elements to copy + * @param pvFrom The source array. + * @param fromOffset The offset in the source. + * @param fromStride The interval between elements in pvFrom. + * @param pvTo The destination array. + * @param toOffset The offset in the destination. + * @param toStride The interval between elements in pvTo. + * @param count The total number of elements to copy from pvFrom to pvTo. */ epicsShareExtern void copy( - PVArray & from, + PVArray & pvFrom, size_t fromOffset, - PVArray & to, + size_t fromStride, + PVArray & pvToo, size_t toOffset, - size_t len); + size_t toStride, + size_t count); + +/** @brief Copy a subarray from one array to another. + * @warning The two arrays must have the same + * introspection interface. + * @param pvFrom The source array. + * @param fromOffset The offset in the source. + * @param fromStride The interval between elements in pvFrom. + * @param pvTo The destination array. + * @param toOffset The offset in the destination. + * @param toStride The interval between elements in pvTo. + * @param count The total number of elements to copy from pvFrom to pvTo. + */ +epicsShareExtern void copy( + PVArray::shared_pointer const & pvFrom, + size_t fromOffset, + size_t fromStride, + PVArray::shared_pointer & pvToo, + size_t toOffset, + size_t toStride, + size_t count); }}