/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ /** * @author Marty Kraimer * @date 2013.07 */ #include #include #include #define epicsExportSharedSymbols #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 toStride, size_t count) { 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 newLength = toOffset + count*toStride; size_t capacity = pvTo.getCapacity(); 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); } void copy( PVScalarArray & from, size_t fromOffset, size_t fromStride, PVScalarArray & to, size_t toOffset, size_t toStride, size_t count) { ScalarType scalarType = from.getScalarArray()->getElementType(); ScalarType otherType = to.getScalarArray()->getElementType(); if(scalarType!=otherType) { throw std::invalid_argument("pvSubArrayCopy element types do not match"); } switch(scalarType) { case pvBoolean: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvByte: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvShort: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvInt: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvLong: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvUByte: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvUShort: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvUInt: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvULong: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvFloat: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvDouble: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; case pvString: { copy(dynamic_cast &>(from),fromOffset,fromStride, dynamic_cast& >(to), toOffset,toStride,count); } break; } } void copy( PVStructureArray & pvFrom, size_t pvFromOffset, size_t pvFromStride, PVStructureArray & 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"); StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray(); StructureArrayConstPtr toStructure = pvTo.getStructureArray(); if(pvFromStructure!=toStructure) { 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 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; icreatePVStructure(toStructure->getStructure()); for(size_t i=0; i temp2(freeze(temp)); pvTo.replace(temp2); } void copy( PVArray & pvFrom, size_t pvFromOffset, size_t pvFromStride, PVArray & pvTo, size_t pvToOffset, size_t pvToStride, size_t count) { 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(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(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); } }}