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