This is Unofficial EPICS BASE Doxygen Site
ntscalarMultiChannel.cpp
Go to the documentation of this file.
1 /* ntscalarMultiChannel.cpp */
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
6 #include <algorithm>
7 #include "validator.h"
8 
9 #define epicsExportSharedSymbols
11 #include <pv/ntutils.h>
12 
13 using namespace std;
14 using namespace epics::pvData;
15 
16 namespace epics { namespace nt {
17 
18 
19 static FieldCreatePtr fieldCreate = getFieldCreate();
20 static PVDataCreatePtr pvDataCreate = getPVDataCreate();
21 static NTFieldPtr ntField = NTField::get();
22 
23 namespace detail {
24 
25 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::value(ScalarType scalarType)
26 {
27  valueType = scalarType;
28  return shared_from_this();
29 }
30 
31 
32 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addDescriptor()
33 {
34  descriptor = true;
35  return shared_from_this();
36 }
37 
38 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addAlarm()
39 {
40  alarm = true;
41  return shared_from_this();
42 }
43 
44 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addTimeStamp()
45 {
46  timeStamp = true;
47  return shared_from_this();
48 }
49 
50 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSeverity()
51 {
52  severity = true;
53  return shared_from_this();
54 }
55 
56 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addStatus()
57 {
58  status = true;
59  return shared_from_this();
60 }
61 
62 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addMessage()
63 {
64  message = true;
65  return shared_from_this();
66 }
67 
68 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSecondsPastEpoch()
69 {
70  secondsPastEpoch = true;
71  return shared_from_this();
72 }
73 
74 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addNanoseconds()
75 {
76  nanoseconds = true;
77  return shared_from_this();
78 }
79 
80 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addUserTag()
81 {
82  userTag = true;
83  return shared_from_this();
84 }
85 
86 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addIsConnected()
87 {
88  isConnected = true;
89  return shared_from_this();
90 }
91 
92 StructureConstPtr NTScalarMultiChannelBuilder::createStructure()
93 {
94  StandardFieldPtr standardField = getStandardField();
95  size_t nfields = 2;
96  size_t extraCount = extraFieldNames.size();
97  nfields += extraCount;
98  if(descriptor) ++nfields;
99  if(alarm) ++nfields;
100  if(timeStamp) ++nfields;
101  if(severity) ++nfields;
102  if(status) ++nfields;
103  if(message) ++nfields;
104  if(secondsPastEpoch) ++nfields;
105  if(nanoseconds) ++nfields;
106  if(userTag) ++nfields;
107  if(isConnected) ++nfields;
108  FieldConstPtrArray fields(nfields);
109  StringArray names(nfields);
110  size_t ind = 0;
111  names[ind] = "value";
112  fields[ind++] = fieldCreate->createScalarArray(valueType);
113  names[ind] = "channelName";
114  fields[ind++] = fieldCreate->createScalarArray(pvString);
115  if(descriptor) {
116  names[ind] = "descriptor";
117  fields[ind++] = fieldCreate->createScalar(pvString);
118  }
119  if(alarm) {
120  names[ind] = "alarm";
121  fields[ind++] = standardField->alarm();
122  }
123  if(timeStamp) {
124  names[ind] = "timeStamp";
125  fields[ind++] = standardField->timeStamp();
126  }
127  if(severity) {
128  names[ind] = "severity";
129  fields[ind++] = fieldCreate->createScalarArray(pvInt);
130  }
131  if(status) {
132  names[ind] = "status";
133  fields[ind++] = fieldCreate->createScalarArray(pvInt);
134  }
135  if(message) {
136  names[ind] = "message";
137  fields[ind++] = fieldCreate->createScalarArray(pvString);
138  }
139  if(secondsPastEpoch) {
140  names[ind] = "secondsPastEpoch";
141  fields[ind++] = fieldCreate->createScalarArray(pvLong);
142  }
143  if(nanoseconds) {
144  names[ind] = "nanoseconds";
145  fields[ind++] = fieldCreate->createScalarArray(pvInt);
146  }
147  if(userTag) {
148  names[ind] = "userTag";
149  fields[ind++] = fieldCreate->createScalarArray(pvInt);
150  }
151  if(isConnected) {
152  names[ind] = "isConnected";
153  fields[ind++] = fieldCreate->createScalarArray(pvBoolean);
154  }
155  for (size_t i = 0; i< extraCount; i++) {
156  names[ind] = extraFieldNames[i];
157  fields[ind++] = extraFields[i];
158  }
159 
160  StructureConstPtr st = fieldCreate->createStructure(NTScalarMultiChannel::URI,names,fields);
161  reset();
162  return st;
163 }
164 
165 PVStructurePtr NTScalarMultiChannelBuilder::createPVStructure()
166 {
167  return pvDataCreate->createPVStructure(createStructure());
168 }
169 
170 NTScalarMultiChannelPtr NTScalarMultiChannelBuilder::create()
171 {
172  return NTScalarMultiChannelPtr(new NTScalarMultiChannel(createPVStructure()));
173 }
174 
175 NTScalarMultiChannelBuilder::NTScalarMultiChannelBuilder()
176 : valueType(pvDouble)
177 {
178  reset();
179 }
180 
181 void NTScalarMultiChannelBuilder::reset()
182 {
183  extraFieldNames.clear();
184  extraFields.clear();
185  valueType = pvDouble;
186  descriptor = false;
187  alarm = false;
188  timeStamp = false;
189  severity = false;
190  status = false;
191  message = false;
192  secondsPastEpoch = false;
193  nanoseconds = false;
194  userTag = false;
195  isConnected = false;
196 }
197 
198 
199 NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::add(string const & name, FieldConstPtr const & field)
200 {
201  extraFields.push_back(field); extraFieldNames.push_back(name);
202  return shared_from_this();
203 }
204 
205 }
206 
207 const std::string NTScalarMultiChannel::URI("epics:nt/NTScalarMultiChannel:1.0");
208 
209 NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrap(PVStructurePtr const & pvStructure)
210 {
211  if(!isCompatible(pvStructure)) return shared_pointer();
212  return wrapUnsafe(pvStructure);
213 }
214 
215 NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrapUnsafe(PVStructurePtr const & pvStructure)
216 {
217  return shared_pointer(new NTScalarMultiChannel(pvStructure));
218 }
219 
220 bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure)
221 {
222  return NTUtils::is_a(structure->getID(), URI);
223 }
224 
225 bool NTScalarMultiChannel::is_a(PVStructurePtr const & pvStructure)
226 {
227  return is_a(pvStructure->getStructure());
228 }
229 
230 bool NTScalarMultiChannel::isCompatible(StructureConstPtr const & structure)
231 {
232  if (!structure)
233  return false;
234 
235  Result result(structure);
236 
237  return result
238  .is<Structure>()
239  .has<ScalarArray>("value")
240  .has<ScalarArray>("channelName")
241  .maybeHas<ScalarArray>("severity")
242  .maybeHas<ScalarArray>("status")
243  .maybeHas<ScalarArray>("message")
244  .maybeHas<ScalarArray>("secondsPastEpoch")
245  .maybeHas<ScalarArray>("nanoseconds")
246  .maybeHas<ScalarArray>("userTag")
247  .maybeHas<Scalar>("descriptor")
248  .maybeHas<&NTField::isAlarm, Structure>("alarm")
249  .maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
250  .valid();
251 }
252 
253 bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
254 {
255  if(!pvStructure.get()) return false;
256 
257  return isCompatible(pvStructure->getStructure());
258 }
259 
260 bool NTScalarMultiChannel::isValid()
261 {
262  size_t valueLength = getValue()->getLength();
263  if (getChannelName()->getLength() != valueLength) return false;
264 
265  PVScalarArrayPtr arrayFields[] = {
266  getSeverity(), getStatus(), getMessage(),
267  getSecondsPastEpoch(), getNanoseconds(), getUserTag()
268  };
269  size_t N = sizeof(arrayFields)/sizeof(arrayFields[0]);
270 
271  PVScalarArrayPtr arrayField;
272  for (PVScalarArrayPtr * pa = arrayFields; pa != arrayFields+N; ++pa)
273  {
274  arrayField = *pa;
275  if (arrayField.get() && arrayField->getLength() != valueLength)
276  return false;
277  }
278  return true;
279 }
280 
281 NTScalarMultiChannelBuilderPtr NTScalarMultiChannel::createBuilder()
282 {
284 }
285 
286 
287 NTScalarMultiChannel::NTScalarMultiChannel(PVStructurePtr const & pvStructure)
288 : pvNTScalarMultiChannel(pvStructure),
289  pvTimeStamp(pvStructure->getSubField<PVStructure>("timeStamp")),
290  pvAlarm(pvStructure->getSubField<PVStructure>("alarm")),
291  pvValue(pvStructure->getSubField<PVScalarArray>("value")),
292  pvChannelName(pvStructure->getSubField<PVStringArray>("channelName")),
293  pvIsConnected(pvStructure->getSubField<PVBooleanArray>("isConnected")),
294  pvSeverity(pvStructure->getSubField<PVIntArray>("severity")),
295  pvStatus(pvStructure->getSubField<PVIntArray>("status")),
296  pvMessage(pvStructure->getSubField<PVStringArray>("message")),
297  pvSecondsPastEpoch(pvStructure->getSubField<PVLongArray>("secondsPastEpoch")),
298  pvNanoseconds(pvStructure->getSubField<PVIntArray>("nanoseconds")),
299  pvUserTag(pvStructure->getSubField<PVIntArray>("userTag")),
300  pvDescriptor(pvStructure->getSubField<PVString>("descriptor"))
301 {
302 }
303 
304 
305 bool NTScalarMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
306 {
307  if (pvTimeStamp)
308  return pv.attach(pvTimeStamp);
309  else
310  return false;
311 }
312 
313 bool NTScalarMultiChannel::attachAlarm(PVAlarm &pv) const
314 {
315  if (pvAlarm)
316  return pv.attach(pvAlarm);
317  else
318  return false;
319 }
320 
321 }}
pvac::PutEvent result
Definition: clientSync.cpp:117
Result & is(void)
Definition: validator.h:89
pvd::Status status
int i
Definition: scan.c:967
Definition: tool_lib.h:67
bool attach(PVFieldPtr const &pvField)
Definition: pvAlarm.cpp:26
Validation methods for NT types.
Definition: validator.h:23
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
std::tr1::shared_ptr< NTField > NTFieldPtr
Definition: ntfield.h:35
std::tr1::shared_ptr< StandardField > StandardFieldPtr
Definition: standardField.h:22
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
PVString is special case, since it implements SerializableArray.
Definition: pvData.h:521
FORCE_INLINE const StandardFieldPtr & getStandardField()
Interface for in-line creating of NTScalarMultiChannel.
pvData
Definition: monitor.h:428
This class implements introspection object for a structure.
Definition: pvIntrospect.h:697
template class for all extensions of PVArray.
Definition: pvData.h:55
std::tr1::shared_ptr< detail::NTScalarMultiChannelBuilder > NTScalarMultiChannelBuilderPtr
Methods for accessing a timeStamp structure.
Definition: pvTimeStamp.h:38
Base class for a scalarArray.
Definition: pvData.h:618
Methods for accessing an alarm structure.
Definition: pvAlarm.h:37
std::vector< FieldConstPtr > FieldConstPtrArray
Definition: pvIntrospect.h:146
Data interface for a structure,.
Definition: pvData.h:712
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
This class implements introspection object for scalar array.
Definition: pvIntrospect.h:497
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
std::vector< std::string > StringArray
Definition: pvType.h:110
std::tr1::shared_ptr< FieldCreate > FieldCreatePtr
Definition: caget.c:48
Convenience Class for NTScalarMultiChannel.
std::tr1::shared_ptr< PVScalarArray > PVScalarArrayPtr
Definition: pvData.h:82
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
bool attach(PVFieldPtr const &pvField)
Definition: pvTimeStamp.cpp:26
std::tr1::shared_ptr< NTScalarMultiChannel > NTScalarMultiChannelPtr