normativeTypesCPP 6.0.2
nttable.cpp
Go to the documentation of this file.
1/* nttable.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#include "validator.h"
9
10#define epicsExportSharedSymbols
11#include <pv/nttable.h>
12#include <pv/ntutils.h>
13
14using namespace std;
15using namespace epics::pvData;
16
17namespace epics { namespace nt {
18
19static NTFieldPtr ntField = NTField::get();
20
21namespace detail {
22
23NTTableBuilder::shared_pointer NTTableBuilder::addColumn(
24 std::string const & name, epics::pvData::ScalarType scalarType
25 )
26{
27 if (std::find(columnNames.begin(), columnNames.end(), name) != columnNames.end())
28 throw std::runtime_error("duplicate column name");
29
30 columnNames.push_back(name);
31 types.push_back(scalarType);
32
33 return shared_from_this();
34}
35
37{
38 FieldBuilderPtr builder = getFieldCreate()->createFieldBuilder();
39
40 FieldBuilderPtr nestedBuilder =
41 builder->
42 setId(NTTable::URI)->
43 addArray("labels", pvString)->
44 addNestedStructure("value");
45
46 vector<string>::size_type len = columnNames.size();
47 for (vector<string>::size_type i = 0; i < len; i++)
48 nestedBuilder->addArray(columnNames[i], types[i]);
49
50 builder = nestedBuilder->endNested();
51
52 if (descriptor)
53 builder->add("descriptor", pvString);
54
55 if (alarm)
56 builder->add("alarm", ntField->createAlarm());
57
58 if (timeStamp)
59 builder->add("timeStamp", ntField->createTimeStamp());
60
61 size_t extraCount = extraFieldNames.size();
62 for (size_t i = 0; i< extraCount; i++)
63 builder->add(extraFieldNames[i], extraFields[i]);
64
65 StructureConstPtr s = builder->createStructure();
66
67 reset();
68 return s;
69}
70
71NTTableBuilder::shared_pointer NTTableBuilder::addDescriptor()
72{
73 descriptor = true;
74 return shared_from_this();
75}
76
77NTTableBuilder::shared_pointer NTTableBuilder::addAlarm()
78{
79 alarm = true;
80 return shared_from_this();
81}
82
83NTTableBuilder::shared_pointer NTTableBuilder::addTimeStamp()
84{
85 timeStamp = true;
86 return shared_from_this();
87}
88
90{
91 // fill in labels with default values (the column names)
92 size_t len = columnNames.size();
93 shared_vector<string> l(len);
94 for(size_t i=0; i<len; ++i) l[i] = columnNames[i];
95 PVStructurePtr s = getPVDataCreate()->createPVStructure(createStructure());
96 s->getSubField<PVStringArray>("labels")->replace(freeze(l));
97 return s;
98}
99
104
105NTTableBuilder::NTTableBuilder()
106{
107 reset();
108}
109
110void NTTableBuilder::reset()
111{
112 columnNames.clear();
113 types.clear();
114 descriptor = false;
115 alarm = false;
116 timeStamp = false;
117}
118
119NTTableBuilder::shared_pointer NTTableBuilder::add(string const & name, FieldConstPtr const & field)
120{
121 extraFields.push_back(field); extraFieldNames.push_back(name);
122 return shared_from_this();
123}
124
125
126}
127
128const std::string NTTable::URI("epics:nt/NTTable:1.0");
129
130NTTable::shared_pointer NTTable::wrap(PVStructurePtr const & pvStructure)
131{
132 if(!isCompatible(pvStructure)) return shared_pointer();
133 return wrapUnsafe(pvStructure);
134}
135
136NTTable::shared_pointer NTTable::wrapUnsafe(PVStructurePtr const & pvStructure)
137{
138 return shared_pointer(new NTTable(pvStructure));
139}
140
141bool NTTable::is_a(StructureConstPtr const & structure)
142{
143 return NTUtils::is_a(structure->getID(), URI);
144}
145
146bool NTTable::is_a(PVStructurePtr const & pvStructure)
147{
148 return is_a(pvStructure->getStructure());
149}
150
151bool NTTable::isCompatible(StructureConstPtr const & structure)
152{
153 if (!structure)
154 return false;
155
156 Result result(structure);
157
158 result
159 .is<Structure>()
160 .has<Structure>("value")
161 .has<ScalarArray>("labels")
162 .maybeHas<Scalar>("descriptor")
163 .maybeHas<&NTField::isAlarm, Structure>("alarm")
164 .maybeHas<&NTField::isTimeStamp, Structure>("timeStamp");
165
166 StructureConstPtr value(structure->getField<Structure>("value"));
167 if (value) {
168 Result r(value);
169 StringArray const & names(value->getFieldNames());
170 StringArray::const_iterator it;
171
172 for (it = names.begin(); it != names.end(); ++it)
173 r.has<ScalarArray>(*it);
174
175 result |= r;
176 }
177
178 return result.valid();
179}
180
181bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
182{
183 if(!pvStructure) return false;
184
185 return isCompatible(pvStructure->getStructure());
186}
187
189{
190 PVFieldPtrArray const & columns = pvValue->getPVFields();
191
192 if (getLabels()->getLength() != columns.size()) return false;
193 bool first = true;
194 int length = 0;
195 for (PVFieldPtrArray::const_iterator it = columns.begin();
196 it != columns.end();++it)
197 {
198 PVScalarArrayPtr column = std::tr1::dynamic_pointer_cast<PVScalarArray>(*it);
199 if (!column.get()) return false;
200 int colLength = column->getLength();
201 if (first)
202 {
203 length = colLength;
204 first = false;
205 }
206 else if (length != colLength)
207 return false;
208 }
209
210 return true;
211}
212
213
218
219bool NTTable::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
220{
221 PVStructurePtr ts = getTimeStamp();
222 if (ts)
223 return pvTimeStamp.attach(ts);
224 else
225 return false;
226}
227
228bool NTTable::attachAlarm(PVAlarm &pvAlarm) const
229{
230 PVStructurePtr al = getAlarm();
231 if (al)
232 return pvAlarm.attach(al);
233 else
234 return false;
235}
236
237PVStructurePtr NTTable::getPVStructure() const
238{
239 return pvNTTable;
240}
241
242PVStringPtr NTTable::getDescriptor() const
243{
244 return pvNTTable->getSubField<PVString>("descriptor");
245}
246
247PVStructurePtr NTTable::getTimeStamp() const
248{
249 return pvNTTable->getSubField<PVStructure>("timeStamp");
250}
251
252PVStructurePtr NTTable::getAlarm() const
253{
254 return pvNTTable->getSubField<PVStructure>("alarm");
255}
256
257PVStringArrayPtr NTTable::getLabels() const
258{
259 return pvNTTable->getSubField<PVStringArray>("labels");
260}
261
262StringArray const & NTTable::getColumnNames() const
263{
264 return pvValue->getStructure()->getFieldNames();
265}
266
267PVFieldPtr NTTable::getColumn(std::string const & columnName) const
268{
269 return pvValue->getSubField(columnName);
270}
271
272NTTable::NTTable(PVStructurePtr const & pvStructure) :
273 pvNTTable(pvStructure), pvValue(pvNTTable->getSubField<PVStructure>("value"))
274{}
275
276
277}}
bool isAlarm(epics::pvData::FieldConstPtr const &field)
static NTFieldPtr get()
Definition ntfield.cpp:18
Convenience Class for NTTable.
Definition nttable.h:138
epics::pvData::StringArray const & getColumnNames() const
Definition nttable.cpp:262
epics::pvData::PVStringArrayPtr getLabels() const
Definition nttable.cpp:257
static bool is_a(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStringPtr getDescriptor() const
Definition nttable.cpp:242
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const
Definition nttable.cpp:219
static bool isCompatible(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStructurePtr getPVStructure() const
Definition nttable.cpp:237
epics::pvData::PVStructurePtr getAlarm() const
Definition nttable.cpp:252
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const &pvStructure)
Definition nttable.cpp:136
static const std::string URI
Definition nttable.h:142
epics::pvData::PVStructurePtr getTimeStamp() const
Definition nttable.cpp:247
static NTTableBuilderPtr createBuilder()
Definition nttable.cpp:214
static shared_pointer wrap(epics::pvData::PVStructurePtr const &pvStructure)
Definition nttable.cpp:130
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const
Definition nttable.cpp:228
epics::pvData::PVFieldPtr getColumn(std::string const &columnName) const
Definition nttable.cpp:267
static bool is_a(const std::string &u1, const std::string &u2)
Definition ntutils.cpp:14
Interface for in-line creating of NTTable.
Definition nttable.h:45
epics::pvData::PVStructurePtr createPVStructure()
Definition nttable.cpp:89
friend class ::epics::nt::NTTable
Definition nttable.h:123
shared_pointer add(std::string const &name, epics::pvData::FieldConstPtr const &field)
Definition nttable.cpp:119
epics::pvData::StructureConstPtr createStructure()
Definition nttable.cpp:36
shared_pointer addColumn(std::string const &name, epics::pvData::ScalarType elementType)
Definition nttable.cpp:23
std::tr1::shared_ptr< detail::NTTableBuilder > NTTableBuilderPtr
Definition nttable.h:128
std::tr1::shared_ptr< NTField > NTFieldPtr
Definition ntfield.h:36
std::tr1::shared_ptr< NTTable > NTTablePtr
Definition nttable.h:32