This is Unofficial EPICS BASE Doxygen Site
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 
14 using namespace std;
15 using namespace epics::pvData;
16 
17 namespace epics { namespace nt {
18 
19 static NTFieldPtr ntField = NTField::get();
20 
21 namespace detail {
22 
23 NTTableBuilder::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 
36 StructureConstPtr NTTableBuilder::createStructure()
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 
71 NTTableBuilder::shared_pointer NTTableBuilder::addDescriptor()
72 {
73  descriptor = true;
74  return shared_from_this();
75 }
76 
77 NTTableBuilder::shared_pointer NTTableBuilder::addAlarm()
78 {
79  alarm = true;
80  return shared_from_this();
81 }
82 
83 NTTableBuilder::shared_pointer NTTableBuilder::addTimeStamp()
84 {
85  timeStamp = true;
86  return shared_from_this();
87 }
88 
89 PVStructurePtr NTTableBuilder::createPVStructure()
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 
100 NTTablePtr NTTableBuilder::create()
101 {
102  return NTTablePtr(new NTTable(createPVStructure()));
103 }
104 
105 NTTableBuilder::NTTableBuilder()
106 {
107  reset();
108 }
109 
110 void NTTableBuilder::reset()
111 {
112  columnNames.clear();
113  types.clear();
114  descriptor = false;
115  alarm = false;
116  timeStamp = false;
117 }
118 
119 NTTableBuilder::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 
128 const std::string NTTable::URI("epics:nt/NTTable:1.0");
129 
130 NTTable::shared_pointer NTTable::wrap(PVStructurePtr const & pvStructure)
131 {
132  if(!isCompatible(pvStructure)) return shared_pointer();
133  return wrapUnsafe(pvStructure);
134 }
135 
136 NTTable::shared_pointer NTTable::wrapUnsafe(PVStructurePtr const & pvStructure)
137 {
138  return shared_pointer(new NTTable(pvStructure));
139 }
140 
141 bool NTTable::is_a(StructureConstPtr const & structure)
142 {
143  return NTUtils::is_a(structure->getID(), URI);
144 }
145 
146 bool NTTable::is_a(PVStructurePtr const & pvStructure)
147 {
148  return is_a(pvStructure->getStructure());
149 }
150 
151 bool 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 
181 bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
182 {
183  if(!pvStructure) return false;
184 
185  return isCompatible(pvStructure->getStructure());
186 }
187 
188 bool NTTable::isValid()
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  {
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 
214 NTTableBuilderPtr NTTable::createBuilder()
215 {
217 }
218 
219 bool 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 
228 bool 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 
237 PVStructurePtr NTTable::getPVStructure() const
238 {
239  return pvNTTable;
240 }
241 
242 PVStringPtr NTTable::getDescriptor() const
243 {
244  return pvNTTable->getSubField<PVString>("descriptor");
245 }
246 
247 PVStructurePtr NTTable::getTimeStamp() const
248 {
249  return pvNTTable->getSubField<PVStructure>("timeStamp");
250 }
251 
252 PVStructurePtr NTTable::getAlarm() const
253 {
254  return pvNTTable->getSubField<PVStructure>("alarm");
255 }
256 
257 PVStringArrayPtr NTTable::getLabels() const
258 {
259  return pvNTTable->getSubField<PVStringArray>("labels");
260 }
261 
262 StringArray const & NTTable::getColumnNames() const
263 {
264  return pvValue->getStructure()->getFieldNames();
265 }
266 
267 PVFieldPtr NTTable::getColumn(std::string const & columnName) const
268 {
269  return pvValue->getSubField(columnName);
270 }
271 
272 NTTable::NTTable(PVStructurePtr const & pvStructure) :
273  pvNTTable(pvStructure), pvValue(pvNTTable->getSubField<PVStructure>("value"))
274 {}
275 
276 
277 }}
FORCE_INLINE std::tr1::shared_ptr< PVField > getSubField(A a)
Definition: pvData.h:744
Definition: link.h:174
std::tr1::shared_ptr< detail::NTTableBuilder > NTTableBuilderPtr
Definition: nttable.h:128
pvac::PutEvent result
Definition: clientSync.cpp:117
Result & is(void)
Definition: validator.h:89
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
int i
Definition: scan.c:967
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< PVStringArray > PVStringArrayPtr
Definition: pvData.h:1464
std::tr1::shared_ptr< FieldBuilder > FieldBuilderPtr
PVString is special case, since it implements SerializableArray.
Definition: pvData.h:521
pvData
Definition: monitor.h:428
virtual std::size_t getLength() const =0
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
Base class for a scalarArray.
Definition: pvData.h:618
Methods for accessing an alarm structure.
Definition: pvAlarm.h:37
std::vector< PVFieldPtr > PVFieldPtrArray
Definition: pvData.h:70
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
Result & has(const std::string &name)
Definition: validator.h:132
std::tr1::shared_ptr< PVString > PVStringPtr
Definition: pvData.h:540
std::tr1::shared_ptr< NTTable > NTTablePtr
Definition: nttable.h:31
Interface for in-line creating of NTTable.
Definition: nttable.h:43
Convenience Class for NTTable.
Definition: nttable.h:137
bool valid(void) const
Definition: validator.h:77
std::vector< std::string > StringArray
Definition: pvType.h:110
std::tr1::shared_ptr< PVField > PVFieldPtr
Definition: pvData.h:66
Definition: caget.c:48
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:808
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