This is Unofficial EPICS BASE Doxygen Site
pvSubArrayCopy.cpp
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
9 #include <string>
10 #include <stdexcept>
11 #include <memory>
12 
13 #define epicsExportSharedSymbols
14 #include <pv/pvSubArrayCopy.h>
15 
16 using std::cout;
17 using std::endl;
18 using std::string;
19 
20 namespace epics { namespace pvData {
21 
22 template<typename T>
23 void copy(
24  PVValueArray<T> & pvFrom,
25  size_t fromOffset,
26  size_t fromStride,
27  PVValueArray<T> & pvTo,
28  size_t toOffset,
29  size_t toStride,
30  size_t count)
31 {
32  if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
33  if(fromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
34  size_t fromLength = pvFrom.getLength();
35  size_t maxcount = (fromLength -fromOffset + fromStride -1)/fromStride;
36  if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
37  size_t newLength = toOffset + count*toStride;
38  size_t capacity = pvTo.getCapacity();
39  if(newLength>capacity) capacity = newLength;
40  shared_vector<T> temp(capacity);
41  typename PVValueArray<T>::const_svector vecFrom = pvFrom.view();
42  typename PVValueArray<T>::const_svector vecTo = pvTo.view();
43  for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
44  for(size_t i=pvTo.getLength(); i< capacity; ++i) temp[i] = T();
45  for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*fromStride+fromOffset];
46  shared_vector<const T> temp2(freeze(temp));
47  pvTo.replace(temp2);
48 }
49 
50 void copy(
51  PVScalarArray & from,
52  size_t fromOffset,
53  size_t fromStride,
54  PVScalarArray & to,
55  size_t toOffset,
56  size_t toStride,
57  size_t count)
58 {
59  ScalarType scalarType = from.getScalarArray()->getElementType();
60  ScalarType otherType = to.getScalarArray()->getElementType();
61  if(scalarType!=otherType) {
62  throw std::invalid_argument("pvSubArrayCopy element types do not match");
63  }
64  switch(scalarType)
65  {
66  case pvBoolean:
67  {
68  copy(dynamic_cast<PVValueArray<boolean> &>(from),fromOffset,fromStride,
69  dynamic_cast<PVValueArray<boolean>& >(to),
70  toOffset,toStride,count);
71  }
72  break;
73  case pvByte:
74  {
75  copy(dynamic_cast<PVValueArray<int8> &>(from),fromOffset,fromStride,
76  dynamic_cast<PVValueArray<int8>& >(to),
77  toOffset,toStride,count);
78  }
79  break;
80  case pvShort:
81  {
82  copy(dynamic_cast<PVValueArray<int16> &>(from),fromOffset,fromStride,
83  dynamic_cast<PVValueArray<int16>& >(to),
84  toOffset,toStride,count);
85  }
86  break;
87  case pvInt:
88  {
89  copy(dynamic_cast<PVValueArray<int32> &>(from),fromOffset,fromStride,
90  dynamic_cast<PVValueArray<int32>& >(to),
91  toOffset,toStride,count);
92  }
93  break;
94  case pvLong:
95  {
96  copy(dynamic_cast<PVValueArray<int64> &>(from),fromOffset,fromStride,
97  dynamic_cast<PVValueArray<int64>& >(to),
98  toOffset,toStride,count);
99  }
100  break;
101  case pvUByte:
102  {
103  copy(dynamic_cast<PVValueArray<uint8> &>(from),fromOffset,fromStride,
104  dynamic_cast<PVValueArray<uint8>& >(to),
105  toOffset,toStride,count);
106  }
107  break;
108  case pvUShort:
109  {
110  copy(dynamic_cast<PVValueArray<uint16> &>(from),fromOffset,fromStride,
111  dynamic_cast<PVValueArray<uint16>& >(to),
112  toOffset,toStride,count);
113  }
114  break;
115  case pvUInt:
116  {
117  copy(dynamic_cast<PVValueArray<uint32> &>(from),fromOffset,fromStride,
118  dynamic_cast<PVValueArray<uint32>& >(to),
119  toOffset,toStride,count);
120  }
121  break;
122  case pvULong:
123  {
124  copy(dynamic_cast<PVValueArray<uint64> &>(from),fromOffset,fromStride,
125  dynamic_cast<PVValueArray<uint64>& >(to),
126  toOffset,toStride,count);
127  }
128  break;
129  case pvFloat:
130  {
131  copy(dynamic_cast<PVValueArray<float> &>(from),fromOffset,fromStride,
132  dynamic_cast<PVValueArray<float>& >(to),
133  toOffset,toStride,count);
134  }
135  break;
136  case pvDouble:
137  {
138  copy(dynamic_cast<PVValueArray<double> &>(from),fromOffset,fromStride,
139  dynamic_cast<PVValueArray<double>& >(to),
140  toOffset,toStride,count);
141  }
142  break;
143  case pvString:
144  {
145  copy(dynamic_cast<PVValueArray<string> &>(from),fromOffset,fromStride,
146  dynamic_cast<PVValueArray<string>& >(to),
147  toOffset,toStride,count);
148  }
149  break;
150  }
151 }
152 
153 void copy(
154  PVStructureArray & pvFrom,
155  size_t pvFromOffset,
156  size_t pvFromStride,
157  PVStructureArray & pvTo,
158  size_t toOffset,
159  size_t toStride,
160  size_t count)
161 {
162  if(pvTo.isImmutable()) {
163  throw std::logic_error("pvSubArrayCopy pvTo is immutable");
164  }
165  if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
166  StructureArrayConstPtr pvFromStructure = pvFrom.getStructureArray();
167  StructureArrayConstPtr toStructure = pvTo.getStructureArray();
168  if(pvFromStructure->getStructure()!=toStructure->getStructure()) {
169  throw std::invalid_argument(
170  "pvSubArrayCopy structureArray pvTo and pvFrom have different structures");
171  }
172  size_t pvFromLength = pvFrom.getLength();
173  size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
174  if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
175  size_t newLength = toOffset + count*toStride;
176  size_t capacity = pvTo.getCapacity();
177  if(newLength>capacity) capacity = newLength;
178  shared_vector<PVStructurePtr> temp(capacity);
181  for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
182  for(size_t i=pvTo.getLength(); i< capacity; ++i)
183  temp[i] = getPVDataCreate()->createPVStructure(toStructure->getStructure());
184  for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
185  shared_vector<const PVStructurePtr> temp2(freeze(temp));
186  pvTo.replace(temp2);
187 }
188 
189 void copy(
190  PVUnionArray & pvFrom,
191  size_t pvFromOffset,
192  size_t pvFromStride,
193  PVUnionArray & pvTo,
194  size_t toOffset,
195  size_t toStride,
196  size_t count)
197 {
198  if(pvTo.isImmutable()) {
199  throw std::logic_error("pvSubArrayCopy pvTo is immutable");
200  }
201  if(pvFromStride<1 || toStride<1) throw std::invalid_argument("stride must be >=1");
202  UnionArrayConstPtr pvFromUnion = pvFrom.getUnionArray();
203  UnionArrayConstPtr toUnion = pvTo.getUnionArray();
204  if(pvFromUnion->getUnion()!=toUnion->getUnion()) {
205  throw std::invalid_argument(
206  "pvSubArrayCopy unionArray pvTo and pvFrom have different unions");
207  }
208  size_t pvFromLength = pvFrom.getLength();
209  size_t maxcount = (pvFromLength -pvFromOffset + pvFromStride -1)/pvFromStride;
210  if(count>maxcount) throw std::invalid_argument("pvSubArrayCopy pvFrom length error");
211  size_t newLength = toOffset + count*toStride;
212  size_t capacity = pvTo.getCapacity();
213  if(newLength>capacity) capacity = newLength;
214  shared_vector<PVUnionPtr> temp(capacity);
217  for(size_t i=0; i<pvTo.getLength(); ++i) temp[i] = vecTo[i];
218  for(size_t i=pvTo.getLength(); i< capacity; ++i)
219  temp[i] = getPVDataCreate()->createPVUnion(toUnion->getUnion());
220  for(size_t i=0; i<count; ++i) temp[i*toStride + toOffset] = vecFrom[i*pvFromStride+pvFromOffset];
221  shared_vector<const PVUnionPtr> temp2(freeze(temp));
222  pvTo.replace(temp2);
223 }
224 
225 void copy(
226  PVArray & pvFrom,
227  size_t pvFromOffset,
228  size_t pvFromStride,
229  PVArray & pvTo,
230  size_t pvToOffset,
231  size_t pvToStride,
232  size_t count)
233 {
234  Type pvFromType = pvFrom.getField()->getType();
235  Type pvToType = pvTo.getField()->getType();
236  if(pvFromType!=pvToType) throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
237  if(pvFromType==scalarArray) {
238  ScalarType pvFromScalarType= static_cast<ScalarType>(pvFromType);
239  ScalarType pvToScalarType = static_cast<ScalarType>(pvToType);
240  if(pvFromScalarType!=pvToScalarType){
241  throw std::invalid_argument("pvSubArrayCopy: pvFrom and pvTo different types");
242  }
243  }
244  if(pvTo.isImmutable()) throw std::invalid_argument("pvSubArrayCopy: pvTo is immutable");
245  if(pvFromType==scalarArray) {
246  copy(dynamic_cast<PVScalarArray &>(pvFrom) ,pvFromOffset,pvFromStride,
247  dynamic_cast<PVScalarArray&>(pvTo),
248  pvToOffset,pvToStride,count);
249  }
250  if(pvFromType==structureArray) {
251  copy(dynamic_cast<PVStructureArray &>(pvFrom) ,pvFromOffset,pvFromStride,
252  dynamic_cast<PVStructureArray&>(pvTo),
253  pvToOffset,pvToStride,count);
254  }
255  if(pvFromType==unionArray) {
256  copy(dynamic_cast<PVUnionArray &>(pvFrom) ,pvFromOffset,pvFromStride,
257  dynamic_cast<PVUnionArray&>(pvTo),
258  pvToOffset,pvToStride,count);
259  }
260 }
261 
262 void copy(
263  PVArray::shared_pointer const & pvFrom,
264  size_t pvFromOffset,
265  size_t pvFromStride,
266  PVArray::shared_pointer & pvTo,
267  size_t pvToOffset,
268  size_t pvToStride,
269  size_t count)
270 {
271  copy(*pvFrom,pvFromOffset,pvFromStride,*pvTo,pvToOffset,pvToStride,count);
272 }
273 
274 }}
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1209
Data class for a unionArray.
Definition: pvData.h:1335
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
int i
Definition: scan.c:967
StructureArrayConstPtr getStructureArray() const
Definition: pvData.h:1278
const FieldConstPtr & getField() const
Definition: pvData.h:208
virtual void replace(const const_svector &other) OVERRIDE FINAL
Definition: pvData.h:1299
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const StructureArray > StructureArrayConstPtr
Definition: pvIntrospect.h:166
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
virtual size_t getCapacity() const OVERRIDE FINAL
Definition: pvData.h:1204
virtual void replace(const const_svector &next) OVERRIDE FINAL
template class for all extensions of PVArray.
Definition: pvData.h:55
Base class for a scalarArray.
Definition: pvData.h:618
virtual size_t getCapacity() const OVERRIDE FINAL
Definition: pvData.h:1261
const ScalarArrayConstPtr getScalarArray() const
virtual size_t getLength() const OVERRIDE FINAL
Definition: pvData.h:1359
Data class for a structureArray.
Definition: pvData.h:1236
virtual size_t getCapacity() const OVERRIDE FINAL
Definition: pvData.h:1360
bool isImmutable() const
Definition: pvData.h:198
virtual void replace(const const_svector &other) OVERRIDE FINAL
Definition: pvData.h:1398
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1297
virtual size_t getLength() const OVERRIDE FINAL
Definition: pvData.h:1260
virtual size_t getLength() const OVERRIDE FINAL
Definition: pvData.h:1203
virtual const_svector view() const OVERRIDE
Fetch a read-only view of the current array data.
Definition: pvData.h:1396
PVArray is the base class for all array types.
Definition: pvData.h:551
UnionArrayConstPtr getUnionArray() const
Definition: pvData.h:1377
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
std::tr1::shared_ptr< const UnionArray > UnionArrayConstPtr
Definition: pvIntrospect.h:174