This is Unofficial EPICS BASE Doxygen Site
StandardField.cpp
Go to the documentation of this file.
1 /* StandardField.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  */
9 #include <string>
10 #include <cstdio>
11 #include <stdexcept>
12 
13 #include <epicsMutex.h>
14 #include <epicsThread.h>
15 
16 #define epicsExportSharedSymbols
17 #include <pv/lock.h>
18 #include <pv/pvIntrospect.h>
19 #include <pv/standardField.h>
20 
22 using std::string;
23 
24 namespace epics { namespace pvData {
25 
26 static
27 StructureConstPtr buildValueAlarm(ScalarType vtype)
28 {
29  return FieldBuilder::begin()
30  ->setId("valueAlarm_t")
31  ->add("active", pvBoolean)
32  ->add("lowAlarmLimit", vtype)
33  ->add("lowWarningLimit", vtype)
34  ->add("highWarningLimit", vtype)
35  ->add("highAlarmLimit", vtype)
36  ->add("lowAlarmSeverity", pvInt)
37  ->add("lowWarningSeverity", pvInt)
38  ->add("highWarningSeverity", pvInt)
39  ->add("highAlarmSeverity", pvInt)
40  ->add("hysteresis", pvByte)
41  ->createStructure();
42 }
43 
44 StandardField::StandardField()
45  :fieldCreate(getFieldCreate())
46  ,notImplemented("not implemented")
47  ,valueFieldName("value")
48 
49  ,alarmField(FieldBuilder::begin()
50  ->setId("alarm_t")
51  ->add("severity", pvInt)
52  ->add("status", pvInt)
53  ->add("message", pvString)
54  ->createStructure())
55 
56  ,timeStampField(FieldBuilder::begin()
57  ->setId("time_t")
58  ->add("secondsPastEpoch", pvLong)
59  ->add("nanoseconds", pvInt)
60  ->add("userTag", pvInt)
61  ->createStructure())
62 
63  ,displayField(FieldBuilder::begin()
64  ->setId("display_t")
65  ->add("limitLow", pvDouble)
66  ->add("limitHigh", pvDouble)
67  ->add("description", pvString)
68  ->add("format", pvString)
69  ->add("units", pvString)
70  ->createStructure())
71 
72  ,controlField(FieldBuilder::begin()
73  ->setId("control_t")
74  ->add("limitLow", pvDouble)
75  ->add("limitHigh", pvDouble)
76  ->add("minStep", pvDouble)
77  ->createStructure())
78 
79  ,booleanAlarmField(FieldBuilder::begin()
80  ->setId("valueAlarm_t")
81  ->add("active", pvBoolean)
82  ->add("falseSeverity", pvInt)
83  ->add("trueSeverity", pvInt)
84  ->add("changeStateSeverity", pvInt)
85  ->createStructure())
86 
87  ,byteAlarmField(buildValueAlarm(pvByte))
88  ,shortAlarmField(buildValueAlarm(pvShort))
89  ,intAlarmField(buildValueAlarm(pvInt))
90  ,longAlarmField(buildValueAlarm(pvLong))
91  ,ubyteAlarmField(buildValueAlarm(pvUByte))
92  ,ushortAlarmField(buildValueAlarm(pvUShort))
93  ,uintAlarmField(buildValueAlarm(pvUInt))
94  ,ulongAlarmField(buildValueAlarm(pvULong))
95  ,floatAlarmField(buildValueAlarm(pvFloat))
96  ,doubleAlarmField(buildValueAlarm(pvDouble))
97 
98  ,enumeratedAlarmField(FieldBuilder::begin()
99  ->setId("valueAlarm_t")
100  ->add("active", pvBoolean)
101  ->add("stateSeverity", pvInt)
102  ->add("changeStateSeverity", pvInt)
103  ->createStructure())
104 {}
105 
107 
108 StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,string properties)
109 {
110  bool gotAlarm = false;
111  bool gotTimeStamp = false;
112  bool gotDisplay = false;
113  bool gotControl = false;
114  bool gotValueAlarm = false;
115  int numProp = 0;
116  if(properties.find("alarm")!=string::npos) { gotAlarm = true; numProp++; }
117  if(properties.find("timeStamp")!=string::npos) { gotTimeStamp = true; numProp++; }
118  if(properties.find("display")!=string::npos) { gotDisplay = true; numProp++; }
119  if(properties.find("control")!=string::npos) { gotControl = true; numProp++; }
120  if(properties.find("valueAlarm")!=string::npos) { gotValueAlarm = true; numProp++; }
121  StructureConstPtr valueAlarm;
122  Type type= field->getType();
123  while(gotValueAlarm) {
125  ScalarType scalarType = (type==epics::pvData::scalar) ?
126  static_pointer_cast<const Scalar>(field)->getScalarType() :
127  static_pointer_cast<const ScalarArray>(field)->getElementType();
128  switch(scalarType) {
129  case pvBoolean: valueAlarm = booleanAlarmField; break;
130  case pvByte: valueAlarm = byteAlarmField; break;
131  case pvShort: valueAlarm = shortAlarmField; break;
132  case pvInt: valueAlarm = intAlarmField; break;
133  case pvLong: valueAlarm = longAlarmField; break;
134  case pvUByte: valueAlarm = ubyteAlarmField; break;
135  case pvUShort: valueAlarm = ushortAlarmField; break;
136  case pvUInt: valueAlarm = uintAlarmField; break;
137  case pvULong: valueAlarm = ulongAlarmField; break;
138  case pvFloat: valueAlarm = floatAlarmField; break;
139  case pvDouble: valueAlarm = doubleAlarmField; break;
140  case pvString:
141  throw std::logic_error(string("valueAlarm property not supported for pvString"));
142  }
143  break;
144  }
145  if(type==structure) {
146  StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
147  StringArray const & names = structurePtr->getFieldNames();
148  if(names.size()==2) {
149  FieldConstPtrArray const & fields = structurePtr->getFields();
150  FieldConstPtr first = fields[0];
151  FieldConstPtr second = fields[1];
152  string nameFirst = names[0];
153  string nameSecond = names[1];
154  int compareFirst = nameFirst.compare("index");
155  int compareSecond = nameSecond.compare("choices");
156  if(compareFirst==0 && compareSecond==0) {
157  if(first->getType()==epics::pvData::scalar
158  && second->getType()==epics::pvData::scalarArray) {
159  ScalarConstPtr scalarFirst = static_pointer_cast<const Scalar>(first);
160  ScalarArrayConstPtr scalarArraySecond =
161  static_pointer_cast<const ScalarArray>(second);
162  if(scalarFirst->getScalarType()==pvInt
163  && scalarArraySecond->getElementType()==pvString) {
164  valueAlarm = enumeratedAlarmField;
165  break;
166  }
167  }
168  }
169  }
170  }
171  throw std::logic_error(string("valueAlarm property for illegal type"));
172  }
173  size_t numFields = numProp+1;
174  FieldConstPtrArray fields(numFields);
175  StringArray names(numFields);
176  int next = 0;
177  names[0] = "value";
178  fields[next++] = field;
179  if(gotAlarm) {
180  names[next] = "alarm";
181  fields[next++] = alarmField;
182  }
183  if(gotTimeStamp) {
184  names[next] = "timeStamp";
185  fields[next++] = timeStampField;
186  }
187  if(gotDisplay) {
188  names[next] = "display";
189  fields[next++] = displayField;
190  }
191  if(gotControl) {
192  names[next] = "control";
193  fields[next++] = controlField;
194  }
195  if(gotValueAlarm) {
196  names[next] = "valueAlarm";
197  fields[next++] = valueAlarm;
198  }
199  return fieldCreate->createStructure(id,names,fields);
200 }
201 
203  ScalarType type,string const &properties)
204 {
205  ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
206  return createProperties("epics:nt/NTScalar:1.0",field,properties);
207 }
208 
210  UnionConstPtr const &field,
211  string const & properties)
212 {
213  return createProperties("epics:nt/NTUnion:1.0",field,properties);
214 }
215 
217  string const & properties)
218 {
219  UnionConstPtr field = fieldCreate->createVariantUnion();
220  return createProperties("epics:nt/NTUnion:1.0",field,properties);
221 }
222 
224  ScalarType elementType, string const &properties)
225 {
226  ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
227  return createProperties("epics:nt/NTScalarArray:1.0",field,properties);
228 }
229 
230 
232  StructureConstPtr const & structure,string const &properties)
233 {
234  StructureArrayConstPtr field = fieldCreate->createStructureArray(
235  structure);
236  return createProperties("epics:nt/NTStructureArray:1.0",field,properties);
237 }
238 
240  UnionConstPtr const & punion,string const &properties)
241 {
242  UnionArrayConstPtr field = fieldCreate->createUnionArray(
243  punion);
244  return createProperties("epics:nt/NTUnionArray:1.0",field,properties);
245 }
246 
248 {
249  size_t num = 2;
250  FieldConstPtrArray fields(num);
251  StringArray names(num);
252  names[0] = "index";
253  names[1] = "choices";
254  fields[0] = fieldCreate->createScalar(pvInt);
255  fields[1] = fieldCreate->createScalarArray(pvString);
256  return fieldCreate->createStructure("enum_t",names,fields);
257  // NOTE: if this method is used to get NTEnum without properties the ID will be wrong!
258 }
259 
260 StructureConstPtr StandardField::enumerated(string const &properties)
261 {
262  StructureConstPtr field = enumerated(); // enum_t
263  return createProperties("epics:nt/NTEnum:1.0",field,properties);
264 }
265 
266 static StandardFieldPtr *stdFieldGbl;
267 
268 static epicsThreadOnceId stdFieldGblOnce = EPICS_THREAD_ONCE_INIT;
269 
270 void StandardField::once(void*)
271 {
272  stdFieldGbl = new StandardFieldPtr;
273  stdFieldGbl->reset(new StandardField);
274 }
275 
277 {
278  epicsThreadOnce(&stdFieldGblOnce, &StandardField::once, 0);
279 
280  return *stdFieldGbl;
281 }
282 
283 }}
This class implements introspection object for Scalar.
Definition: pvIntrospect.h:397
StructureConstPtr variantUnion(std::string const &properties)
StructureConstPtr structureArray(StructureConstPtr const &structure, std::string const &properties)
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
pvd::StructureConstPtr type
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< const StructureArray > StructureArrayConstPtr
Definition: pvIntrospect.h:166
StructureConstPtr enumerated()
std::tr1::shared_ptr< StandardField > StandardFieldPtr
Definition: standardField.h:22
std::tr1::shared_ptr< const Scalar > ScalarConstPtr
Definition: pvIntrospect.h:150
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
std::tr1::shared_ptr< const Union > UnionConstPtr
Definition: pvIntrospect.h:170
StructureConstPtr scalarArray(ScalarType elementType, std::string const &properties)
This class implements introspection object for a structure.
Definition: pvIntrospect.h:697
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
std::vector< FieldConstPtr > FieldConstPtrArray
Definition: pvIntrospect.h:146
static const StandardFieldPtr & getStandardField()
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
StructureConstPtr regUnion(UnionConstPtr const &punion, std::string const &properties)
std::tr1::shared_ptr< const ScalarArray > ScalarArrayConstPtr
Definition: pvIntrospect.h:158
This class implements introspection object for scalar array.
Definition: pvIntrospect.h:497
std::vector< std::string > StringArray
Definition: pvType.h:110
StructureConstPtr scalar(ScalarType type, std::string const &properties)
Standard Fields is a class or creating or sharing Field objects for standard fields.
Definition: standardField.h:63
C++ and C descriptions for a thread.
static FieldBuilderPtr begin()
StringArray const & getFieldNames() const
Definition: pvIntrospect.h:828
std::tr1::shared_ptr< const UnionArray > UnionArrayConstPtr
Definition: pvIntrospect.h:174
StructureConstPtr unionArray(UnionConstPtr const &punion, std::string const &properties)