From 3579d17a05786e2c05c43c924d388123041d198f Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Thu, 31 Oct 2013 06:44:54 -0400 Subject: [PATCH] moved pvSubArrayCopy from pvDatabaseCPP to pvDataCPP --- pvDataApp/Makefile | 2 + pvDataApp/factory/pvSubArrayCopy.cpp | 203 +++++++++++++++++++++++++++ pvDataApp/pv/pvSubArrayCopy.h | 83 +++++++++++ 3 files changed, 288 insertions(+) create mode 100644 pvDataApp/factory/pvSubArrayCopy.cpp create mode 100644 pvDataApp/pv/pvSubArrayCopy.h diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile index 3e78645..f676948 100644 --- a/pvDataApp/Makefile +++ b/pvDataApp/Makefile @@ -52,6 +52,7 @@ INC += pvData.h INC += convert.h INC += standardField.h INC += standardPVField.h +INC += pvSubArrayCopy.h SRC_DIRS += $(PVDATA)/factory @@ -67,6 +68,7 @@ LIBSRCS += PVStructure.cpp LIBSRCS += PVStructureArray.cpp LIBSRCS += PVDataCreateFactory.cpp LIBSRCS += Convert.cpp +LIBSRCS += pvSubArrayCopy.cpp LIBSRCS += Compare.cpp LIBSRCS += StandardField.cpp LIBSRCS += StandardPVField.cpp diff --git a/pvDataApp/factory/pvSubArrayCopy.cpp b/pvDataApp/factory/pvSubArrayCopy.cpp new file mode 100644 index 0000000..44cd1eb --- /dev/null +++ b/pvDataApp/factory/pvSubArrayCopy.cpp @@ -0,0 +1,203 @@ +/** + * 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 + +#include + +namespace epics { namespace pvData { + +template +void copy( + PVValueArray & pvFrom, + size_t fromOffset, + PVValueArray & pvTo, + size_t toOffset, + size_t len) +{ + if(pvTo.isImmutable()) { + throw std::logic_error("pvSubArrayCopy to is immutable"); + } + size_t fromLength = pvFrom.getLength(); + if(fromOffset+len>fromLength) { + throw std::length_error("pvSubArrayCopy from length error"); + } + size_t capacity = pvTo.getCapacity(); + if(toOffset+len>capacity) capacity = toOffset + len; + 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, + PVScalarArray & to, + size_t toOffset, + size_t len) +{ + 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, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvByte: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvShort: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvInt: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvLong: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvUByte: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvUShort: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvUInt: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvULong: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvFloat: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvDouble: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + case pvString: + { + copy(dynamic_cast &>(from),fromOffset, + dynamic_cast& >(to), + toOffset,len); + } + break; + } +} + +void copy( + PVStructureArray & from, + size_t fromOffset, + PVStructureArray & to, + size_t toOffset, + size_t len) +{ + if(to.isImmutable()) { + throw std::logic_error("pvSubArrayCopy to is immutable"); + } + StructureArrayConstPtr fromStructure = from.getStructureArray(); + StructureArrayConstPtr toStructure = to.getStructureArray(); + if(fromStructure!=toStructure) { + throw std::invalid_argument( + "pvSubArrayCopy structureArray to and from 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; + shared_vector temp(capacity); + PVValueArray::const_svector vecFrom = from.view(); + PVValueArray::const_svector vecTo = to.view(); + for(size_t i=0; i temp2(freeze(temp)); + to.replace(temp2); +} + +void copy( + PVArray & from, + size_t fromOffset, + PVArray & to, + size_t toOffset, + size_t len) +{ + Type type = from.getField()->getType(); + Type otherType = to.getField()->getType(); + if(type!=otherType) { + throw std::invalid_argument("pvSubArrayCopy types do not match"); + } + if(type==scalarArray) { + copy(dynamic_cast(from) ,fromOffset, + dynamic_cast(to), + toOffset,len); + } + if(type==structureArray) { + copy(dynamic_cast(from) ,fromOffset, + dynamic_cast(to), + toOffset,len); + } +} + +}} + diff --git a/pvDataApp/pv/pvSubArrayCopy.h b/pvDataApp/pv/pvSubArrayCopy.h new file mode 100644 index 0000000..8f62a26 --- /dev/null +++ b/pvDataApp/pv/pvSubArrayCopy.h @@ -0,0 +1,83 @@ +/* pvSubArrayCopy.h */ +/** + * 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 + */ +#ifndef PVSUBARRAYCOPY_H +#define PVSUBARRAYCOPY_H +#include + +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 + */ +template +void copy( + PVValueArray & pvFrom, + size_t fromOffset, + PVValueArray & pvTo, + size_t toOffset, + size_t len); + +/** @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 + */ +void copy( + PVScalarArray & from, + size_t fromOffset, + PVScalarArray & to, + size_t toOffset, + size_t len); + +/** @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 + */ +void copy( + PVStructureArray & from, + size_t fromOffset, + PVStructureArray & to, + size_t toOffset, + size_t len); + +/** @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 + */ +void copy( + PVArray & from, + size_t fromOffset, + PVArray & to, + size_t toOffset, + size_t len); + +}} + + +#endif /* PVSUBARRAYCOPY_H */