normativeTypesCPP 6.0.2
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
15using namespace std;
16using namespace epics::pvData;
17
18namespace epics { namespace nt {
19
20
21static FieldCreatePtr fieldCreate = getFieldCreate();
22static PVDataCreatePtr pvDataCreate = getPVDataCreate();
23static NTFieldPtr ntField = NTField::get();
24
25namespace detail {
26
27NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::value(UnionConstPtr valuePtr)
28{
29 valueType = valuePtr;
30 return shared_from_this();
31}
32
33
34NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addDescriptor()
35{
36 descriptor = true;
37 return shared_from_this();
38}
39
40NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addAlarm()
41{
42 alarm = true;
43 return shared_from_this();
44}
45
46NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addTimeStamp()
47{
48 timeStamp = true;
49 return shared_from_this();
50}
51
52NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSeverity()
53{
54 severity = true;
55 return shared_from_this();
56}
57
58NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addStatus()
59{
60 status = true;
61 return shared_from_this();
62}
63
64NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addMessage()
65{
66 message = true;
67 return shared_from_this();
68}
69
70NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSecondsPastEpoch()
71{
72 secondsPastEpoch = true;
73 return shared_from_this();
74}
75
76NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addNanoseconds()
77{
78 nanoseconds = true;
79 return shared_from_this();
80}
81
82NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addUserTag()
83{
84 userTag = true;
85 return shared_from_this();
86}
87
88NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addIsConnected()
89{
90 isConnected = true;
91 return shared_from_this();
92}
93
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
172{
173 return pvDataCreate->createPVStructure(createStructure());
174}
175
180
181NTMultiChannelBuilder::NTMultiChannelBuilder()
182{
183 reset();
184}
185
186void 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
204NTMultiChannelBuilder::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
212const std::string NTMultiChannel::URI("epics:nt/NTMultiChannel:1.0");
213
214NTMultiChannel::shared_pointer NTMultiChannel::wrap(PVStructurePtr const & pvStructure)
215{
216 if(!isCompatible(pvStructure)) return shared_pointer();
217 return wrapUnsafe(pvStructure);
218}
219
220NTMultiChannel::shared_pointer NTMultiChannel::wrapUnsafe(PVStructurePtr const & pvStructure)
221{
222 return shared_pointer(new NTMultiChannel(pvStructure));
223}
224
225bool NTMultiChannel::is_a(StructureConstPtr const &structure)
226{
227 return NTUtils::is_a(structure->getID(), URI);
228}
229
230bool NTMultiChannel::is_a(PVStructurePtr const & pvStructure)
231{
232 return is_a(pvStructure->getStructure());
233}
234
235bool 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
258bool NTMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
259{
260 if(!pvStructure.get()) return false;
261
262 return isCompatible(pvStructure->getStructure());
263}
264
265
267{
268 size_t valueLength = getValue()->getLength();
269 if (getChannelName()->getLength() != valueLength) return false;
270
271 PVScalarArrayPtr arrayFields[] = {
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
292
293NTMultiChannel::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
311bool NTMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
312{
313 if (pvTimeStamp)
314 return pv.attach(pvTimeStamp);
315 else
316 return false;
317}
318
319bool NTMultiChannel::attachAlarm(PVAlarm &pv) const
320{
321 if (pvAlarm)
322 return pv.attach(pvAlarm);
323 else
324 return false;
325}
326
327}}
bool isAlarm(epics::pvData::FieldConstPtr const &field)
static NTFieldPtr get()
Definition ntfield.cpp:18
Convenience Class for NTMultiChannel.
static const std::string URI
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const
epics::pvData::PVIntArrayPtr getSeverity() const
epics::pvData::PVIntArrayPtr getStatus() const
static bool is_a(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStringArrayPtr getChannelName() const
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const &pvStructure)
epics::pvData::PVIntArrayPtr getUserTag() const
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const
epics::pvData::PVLongArrayPtr getSecondsPastEpoch() const
epics::pvData::PVUnionArrayPtr getValue() const
epics::pvData::PVStringArrayPtr getMessage() const
static NTMultiChannelBuilderPtr createBuilder()
epics::pvData::PVIntArrayPtr getNanoseconds() const
static shared_pointer wrap(epics::pvData::PVStructurePtr const &pvStructure)
static bool isCompatible(epics::pvData::StructureConstPtr const &structure)
static bool is_a(const std::string &u1, const std::string &u2)
Definition ntutils.cpp:14
Interface for in-line creating of NTMultiChannel.
friend class ::epics::nt::NTMultiChannel
epics::pvData::StructureConstPtr createStructure()
shared_pointer add(std::string const &name, epics::pvData::FieldConstPtr const &field)
shared_pointer value(epics::pvData::UnionConstPtr valuePtr)
epics::pvData::PVStructurePtr createPVStructure()
std::tr1::shared_ptr< NTField > NTFieldPtr
Definition ntfield.h:36
std::tr1::shared_ptr< NTMultiChannel > NTMultiChannelPtr
std::tr1::shared_ptr< detail::NTMultiChannelBuilder > NTMultiChannelBuilderPtr