normativeTypesCPP 6.0.2
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
13using namespace std;
14using namespace epics::pvData;
15
16namespace epics { namespace nt {
17
18
19static FieldCreatePtr fieldCreate = getFieldCreate();
20static PVDataCreatePtr pvDataCreate = getPVDataCreate();
21static NTFieldPtr ntField = NTField::get();
22
23namespace detail {
24
25NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::value(ScalarType scalarType)
26{
27 valueType = scalarType;
28 return shared_from_this();
29}
30
31
32NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addDescriptor()
33{
34 descriptor = true;
35 return shared_from_this();
36}
37
38NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addAlarm()
39{
40 alarm = true;
41 return shared_from_this();
42}
43
44NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addTimeStamp()
45{
46 timeStamp = true;
47 return shared_from_this();
48}
49
50NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSeverity()
51{
52 severity = true;
53 return shared_from_this();
54}
55
56NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addStatus()
57{
58 status = true;
59 return shared_from_this();
60}
61
62NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addMessage()
63{
64 message = true;
65 return shared_from_this();
66}
67
68NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSecondsPastEpoch()
69{
70 secondsPastEpoch = true;
71 return shared_from_this();
72}
73
74NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addNanoseconds()
75{
76 nanoseconds = true;
77 return shared_from_this();
78}
79
80NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addUserTag()
81{
82 userTag = true;
83 return shared_from_this();
84}
85
86NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addIsConnected()
87{
88 isConnected = true;
89 return shared_from_this();
90}
91
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
166{
167 return pvDataCreate->createPVStructure(createStructure());
168}
169
174
175NTScalarMultiChannelBuilder::NTScalarMultiChannelBuilder()
176: valueType(pvDouble)
177{
178 reset();
179}
180
181void 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
199NTScalarMultiChannelBuilder::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
207const std::string NTScalarMultiChannel::URI("epics:nt/NTScalarMultiChannel:1.0");
208
209NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrap(PVStructurePtr const & pvStructure)
210{
211 if(!isCompatible(pvStructure)) return shared_pointer();
212 return wrapUnsafe(pvStructure);
213}
214
215NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrapUnsafe(PVStructurePtr const & pvStructure)
216{
217 return shared_pointer(new NTScalarMultiChannel(pvStructure));
218}
219
220bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure)
221{
222 return NTUtils::is_a(structure->getID(), URI);
223}
224
225bool NTScalarMultiChannel::is_a(PVStructurePtr const & pvStructure)
226{
227 return is_a(pvStructure->getStructure());
228}
229
230bool 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
253bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
254{
255 if(!pvStructure.get()) return false;
256
257 return isCompatible(pvStructure->getStructure());
258}
259
261{
262 size_t valueLength = getValue()->getLength();
263 if (getChannelName()->getLength() != valueLength) return false;
264
265 PVScalarArrayPtr arrayFields[] = {
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
285
286
287NTScalarMultiChannel::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
305bool NTScalarMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
306{
307 if (pvTimeStamp)
308 return pv.attach(pvTimeStamp);
309 else
310 return false;
311}
312
314{
315 if (pvAlarm)
316 return pv.attach(pvAlarm);
317 else
318 return false;
319}
320
321}}
bool isAlarm(epics::pvData::FieldConstPtr const &field)
static NTFieldPtr get()
Definition ntfield.cpp:18
Convenience Class for NTScalarMultiChannel.
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const
static bool is_a(epics::pvData::StructureConstPtr const &structure)
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const &pvStructure)
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const
epics::pvData::PVScalarArrayPtr getValue() const
epics::pvData::PVIntArrayPtr getNanoseconds() const
static shared_pointer wrap(epics::pvData::PVStructurePtr const &pvStructure)
epics::pvData::PVIntArrayPtr getStatus() const
epics::pvData::PVIntArrayPtr getUserTag() const
epics::pvData::PVIntArrayPtr getSeverity() const
epics::pvData::PVLongArrayPtr getSecondsPastEpoch() const
static NTScalarMultiChannelBuilderPtr createBuilder()
static bool isCompatible(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStringArrayPtr getMessage() const
epics::pvData::PVStringArrayPtr getChannelName() const
static bool is_a(const std::string &u1, const std::string &u2)
Definition ntutils.cpp:14
Interface for in-line creating of NTScalarMultiChannel.
shared_pointer value(epics::pvData::ScalarType scalarType)
shared_pointer add(std::string const &name, epics::pvData::FieldConstPtr const &field)
epics::pvData::StructureConstPtr createStructure()
std::tr1::shared_ptr< NTField > NTFieldPtr
Definition ntfield.h:36
std::tr1::shared_ptr< NTScalarMultiChannel > NTScalarMultiChannelPtr
std::tr1::shared_ptr< detail::NTScalarMultiChannelBuilder > NTScalarMultiChannelBuilderPtr