This is Unofficial EPICS BASE Doxygen Site
pvArrayPlugin.cpp
Go to the documentation of this file.
1 /* pvArrayPlugin.cpp */
2 /*
3  * The License for this software can be found in the file LICENSE that is included with the distribution.
4  */
5 
6 #include <stdlib.h>
7 #include <pv/pvData.h>
8 #include <pv/bitSet.h>
9 #include <pv/convert.h>
10 #include <pv/pvSubArrayCopy.h>
11 #define epicsExportSharedSymbols
12 #include "pv/pvArrayPlugin.h"
13 
14 using std::string;
15 using std::size_t;
16 using std::cout;
17 using std::endl;
19 using std::vector;
20 using namespace epics::pvData;
21 
22 namespace epics { namespace pvCopy{
23 
24 static ConvertPtr convert = getConvert();
25 static std::string name("array");
26 
27 PVArrayPlugin::PVArrayPlugin()
28 {
29 }
30 
31 PVArrayPlugin::~PVArrayPlugin()
32 {
33 }
34 
35 void PVArrayPlugin::create()
36 {
37  static bool firstTime = true;
38  if(firstTime) {
39  firstTime = false;
41  PVPluginRegistry::registerPlugin(name,pvPlugin);
42  }
43 }
44 
45 PVFilterPtr PVArrayPlugin::create(
46  const std::string & requestValue,
47  const PVCopyPtr & pvCopy,
48  const PVFieldPtr & master)
49 {
50  return PVArrayFilter::create(requestValue,master);
51 }
52 
53 PVArrayFilter::~PVArrayFilter()
54 {
55 }
56 
57 static vector<string> split(string const & colonSeparatedList) {
58  string::size_type numValues = 1;
59  string::size_type index=0;
60  while(true) {
61  string::size_type pos = colonSeparatedList.find(':',index);
62  if(pos==string::npos) break;
63  numValues++;
64  index = pos +1;
65  }
66  vector<string> valueList(numValues,"");
67  index=0;
68  for(size_t i=0; i<numValues; i++) {
69  size_t pos = colonSeparatedList.find(':',index);
70  string value = colonSeparatedList.substr(index,pos-index);
71  valueList[i] = value;
72  index = pos +1;
73  }
74  return valueList;
75 }
76 
77 PVArrayFilterPtr PVArrayFilter::create(
78  const std::string & requestValue,
79  const PVFieldPtr & masterField)
80 {
81  bool masterIsUnion = false;
82  PVUnionPtr pvUnion;
83  Type type = masterField->getField()->getType();
84  if(type==epics::pvData::union_) {
85  pvUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
86  PVFieldPtr pvField = pvUnion->get();
87  if(pvField) {
88  masterIsUnion = true;
89  type = pvField->getField()->getType();
90  }
91  }
92  if(type!=scalarArray) {
94  return filter;
95  }
96  long start =0;
97  long increment =1;
98  long end = -1;
99  vector<string> values(split(requestValue));
100  long num = values.size();
101  bool ok = true;
102  string value;
103  if(num==1) {
104  value = values[0];
105  start = strtol(value.c_str(),0,10);
106  } else if(num==2) {
107  value = values[0];
108  start = strtol(value.c_str(),0,10);
109  value = values[1];
110  end = strtol(value.c_str(),0,10);
111  } else if(num==3) {
112  value = values[0];
113  start = strtol(value.c_str(),0,10);
114  value = values[1];
115  increment = strtol(value.c_str(),0,10);
116  value = values[2];
117  end = strtol(value.c_str(),0,10);
118  } else {
119  ok = false;
120  }
121  if(!ok) {
123  return filter;
124  }
125  PVScalarArrayPtr masterArray;
126  if(masterIsUnion) {
127  masterArray = static_pointer_cast<PVScalarArray>(pvUnion->get());
128  } else {
129  masterArray = static_pointer_cast<PVScalarArray>(masterField);
130  }
131  PVArrayFilterPtr filter =
133  new PVArrayFilter(start,increment,end,masterField,masterArray));
134  return filter;
135 }
136 
137 PVArrayFilter::PVArrayFilter(
138  long start,long increment,long end,
139  const PVFieldPtr & masterField,
140  const epics::pvData::PVScalarArrayPtr masterArray)
141 : start(start),
142  increment(increment),
143  end(end),
144  masterField(masterField),
145  masterArray(masterArray)
146 {
147 }
148 
149 
150 bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,bool toCopy)
151 {
152  PVFieldPtr pvCopy = pvField;
153  PVScalarArrayPtr copyArray;
154  bool isUnion = false;
155  Type type = masterField->getField()->getType();
156  if(type==epics::pvData::union_) {
157  isUnion = true;
158  PVUnionPtr pvMasterUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
159  PVUnionPtr pvCopyUnion = std::tr1::static_pointer_cast<PVUnion>(pvCopy);
160  if(toCopy) pvCopyUnion->copy(*pvMasterUnion);
161  PVFieldPtr pvField = pvCopyUnion->get();
162  copyArray = static_pointer_cast<PVScalarArray>(pvField);
163  } else {
164  copyArray = static_pointer_cast<PVScalarArray>(pvCopy);
165  }
166  long len = 0;
167  long start = this->start;
168  long end = this->end;
169  long no_elements = masterArray->getLength();
170  if(start<0) {
171  start = no_elements+start;
172  if(start<0) start = 0;
173  }
174  if (end < 0) {
175  end = no_elements + end;
176  if (end < 0) end = 0;
177 
178  }
179  if(toCopy) {
180  if (end >= no_elements) end = no_elements - 1;
181  if (end - start >= 0) len = 1 + (end - start) / increment;
182  if(len<=0 || start>=no_elements) {
183  copyArray->setLength(0);
184  return true;
185  }
186  long indfrom = start;
187  long indto = 0;
188  copyArray->setCapacity(len);
189  if(increment==1) {
190  copy(*masterArray,indfrom,1,*copyArray,indto,1,len);
191  } else {
192  for(long i=0; i<len; ++i) {
193  copy(*masterArray,indfrom,1,*copyArray,indto,1,1);
194  indfrom += increment;
195  indto += 1;
196  }
197  }
198  copyArray->setLength(len);
199  bitSet->set(pvField->getFieldOffset());
200  return true;
201  }
202  if (end - start >= 0) len = 1 + (end - start) / increment;
203  if(len<=0) return true;
204  if(no_elements<=end) masterArray->setLength(end+1);
205  long indfrom = 0;
206  long indto = start;
207  if(increment==1) {
208  copy(*copyArray,indfrom,1,*masterArray,indto,1,len);
209  } else {
210  for(long i=0; i<len; ++i) {
211  copy(*copyArray,indfrom,1,*masterArray,indto,1,1);
212  indfrom += 1;
213  indto += increment;
214  }
215  }
216  if(isUnion) masterField->postPut();
217  return true;
218 }
219 
220 string PVArrayFilter::getName()
221 {
222  return name;
223 }
224 
225 }}
Definition: link.h:174
const PVFieldPtr & get()
Definition: pvData.h:968
int i
Definition: scan.c:967
std::tr1::shared_ptr< PVFilter > PVFilterPtr
Definition: pvPlugin.h:29
std::tr1::shared_ptr< PVCopy > PVCopyPtr
Definition: pvPlugin.h:25
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
pvd::StructureConstPtr type
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
A filter that gets a sub array from a PVScalarArray.
Definition: pvArrayPlugin.h:60
std::tr1::shared_ptr< PVArrayFilter > PVArrayFilterPtr
Definition: pvArrayPlugin.h:23
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.
std::tr1::shared_ptr< PVUnion > PVUnionPtr
Definition: pvData.h:107
pvData
Definition: monitor.h:428
virtual std::size_t getLength() const =0
Base class for a scalarArray.
Definition: pvData.h:618
PVUnion has a single subfield.
Definition: pvData.h:940
void copy(const PVUnion &from)
Definition: PVUnion.cpp:199
std::tr1::shared_ptr< PVArrayPlugin > PVArrayPluginPtr
Definition: pvArrayPlugin.h:20
std::tr1::shared_ptr< PVField > PVFieldPtr
Definition: pvData.h:66
std::tr1::shared_ptr< Convert > ConvertPtr
Definition: convert.h:23
std::tr1::shared_ptr< BitSet > BitSetPtr
Definition: bitSet.h:26
std::tr1::shared_ptr< PVScalarArray > PVScalarArrayPtr
Definition: pvData.h:82
A plugin for a filter that gets a sub array from a PVScalarArray.
Definition: pvArrayPlugin.h:32