pvDatabaseCPP  4.5.1
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;
18 using std::tr1::static_pointer_cast;
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 & master)
80 {
81  Type type = master->getField()->getType();
82  if(type!=scalarArray) {
84  return filter;
85  }
86  long start =0;
87  long increment =1;
88  long end = -1;
89  vector<string> values(split(requestValue));
90  long num = values.size();
91  bool ok = true;
92  string value;
93  if(num==1) {
94  value = values[0];
95  start = strtol(value.c_str(),0,10);
96  } else if(num==2) {
97  value = values[0];
98  start = strtol(value.c_str(),0,10);
99  value = values[1];
100  end = strtol(value.c_str(),0,10);
101  } else if(num==3) {
102  value = values[0];
103  start = strtol(value.c_str(),0,10);
104  value = values[1];
105  increment = strtol(value.c_str(),0,10);
106  value = values[2];
107  end = strtol(value.c_str(),0,10);
108  } else {
109  ok = false;
110  }
111  if(!ok) {
113  return filter;
114  }
115  PVArrayFilterPtr filter =
117  new PVArrayFilter(
118  start,increment,end,static_pointer_cast<PVScalarArray>(master)));
119  return filter;
120 }
121 
122 PVArrayFilter::PVArrayFilter(long start,long increment,long end,const PVScalarArrayPtr & masterArray)
123 : start(start),
124  increment(increment),
125  end(end),
126  masterArray(masterArray)
127 {
128 }
129 
130 
131 bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy)
132 {
133  PVScalarArrayPtr copyArray = static_pointer_cast<PVScalarArray>(pvCopy);
134  long len = 0;
135  long start = this->start;
136  long end = this->end;
137  long no_elements = masterArray->getLength();
138  if(start<0) {
139  start = no_elements+start;
140  if(start<0) start = 0;
141  }
142  if (end < 0) {
143  end = no_elements + end;
144  if (end < 0) end = 0;
145 
146  }
147  if(toCopy) {
148  if (end >= no_elements) end = no_elements - 1;
149  if (end - start >= 0) len = 1 + (end - start) / increment;
150  if(len<=0 || start>=no_elements) {
151  copyArray->setLength(0);
152  return true;
153  }
154  long indfrom = start;
155  long indto = 0;
156  copyArray->setCapacity(len);
157  if(increment==1) {
158  copy(*masterArray,indfrom,1,*copyArray,indto,1,len);
159  } else {
160  for(long i=0; i<len; ++i) {
161  copy(*masterArray,indfrom,1,*copyArray,indto,1,1);
162  indfrom += increment;
163  indto += 1;
164  }
165  }
166  copyArray->setLength(len);
167  bitSet->set(pvCopy->getFieldOffset());
168  return true;
169  }
170  if (end - start >= 0) len = 1 + (end - start) / increment;
171  if(len<=0) return true;
172  if(no_elements<=end) masterArray->setLength(end+1);
173  long indfrom = 0;
174  long indto = start;
175  if(increment==1) {
176  copy(*copyArray,indfrom,1,*masterArray,indto,1,len);
177  } else {
178  for(long i=0; i<len; ++i) {
179  copy(*copyArray,indfrom,1,*masterArray,indto,1,1);
180  indfrom += 1;
181  indto += increment;
182  }
183  }
184  return true;
185 }
186 
187 string PVArrayFilter::getName()
188 {
189  return name;
190 }
191 
192 }}
193 
std::tr1::shared_ptr< PVFilter > PVFilterPtr
Definition: pvPlugin.h:29
std::tr1::shared_ptr< PVCopy > PVCopyPtr
Definition: pvPlugin.h:25
A filter that gets a sub array from a PVScalarArray.
Definition: pvArrayPlugin.h:60
std::tr1::shared_ptr< PVArrayFilter > PVArrayFilterPtr
Definition: pvArrayPlugin.h:23
std::tr1::shared_ptr< PVArrayPlugin > PVArrayPluginPtr
Definition: pvArrayPlugin.h:20
A plugin for a filter that gets a sub array from a PVScalarArray.
Definition: pvArrayPlugin.h:32