This is Unofficial EPICS BASE Doxygen Site
validator.h
Go to the documentation of this file.
1 /* validator.h */
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 #ifndef VALIDATOR_H
7 #define VALIDATOR_H
8 
9 #include <string>
10 #include <set>
11 #include <algorithm>
12 
13 #include <pv/pvIntrospect.h>
14 
15 namespace epics { namespace nt {
16 
23 struct Result {
24  struct Error {
25  std::string path;
26  enum Type {
30  } type;
31 
32  Error(std::string const & path, Type type)
33  : path(path), type(type) {}
34 
35  bool operator==(const Error& other) const {
36  return type == other.type && path == other.path;
37  }
38 
39  std::ostream& dump(std::ostream& os) const {
40  os << "Error(path=" << (path.empty() ? "<root>" : path) << ": ";
41 
42  switch(type) {
43  case MissingField: os << "missing"; break;
44  case IncorrectType: os << "incorrect type"; break;
45  case IncorrectId: os << "incorrect ID"; break;
46  }
47  os << ")";
48  return os;
49  }
50  };
51 
53  std::string path;
54  std::vector<Error> errors;
55 
56  enum result_t {
59  } result;
60 
61  Result(const epics::pvData::FieldConstPtr& field, const std::string& path = std::string())
62  : field(field), path(path), errors(), result(Pass) {}
63 
64  Result() {}
65 
66  Result& operator|=(const Result& other) {
67  result = std::max(result, other.result);
68  errors.insert(errors.end(), other.errors.begin(), other.errors.end());
69  return *this;
70  }
71 
77  inline bool valid(void) const {
78  return result == Pass;
79  }
80 
88  template<typename T>
89  Result& is(void) {
90  if (!dynamic_cast<T const *>(field.get())) {
91  result = Fail;
92  errors.push_back(Error(path, Error::IncorrectType));
93  }
94  return *this;
95  }
96 
107  template<typename T>
108  Result& is(const std::string& id) {
109  T const *s = dynamic_cast<T const *>(field.get());
110  if (!s) {
111  result = Fail;
112  errors.push_back(Error(path, Error::IncorrectType));
113  } else if (s->getID() != id) {
114  result = Fail;
115  errors.push_back(Error(path, Error::IncorrectId));
116  }
117  return *this;
118  }
119 
131  template<Result& (*fn)(Result&)>
132  Result& has(const std::string& name) {
133  return has<epics::pvData::Field>(name, false, fn);
134  }
135 
145  template<Result& (*fn)(Result&)>
146  Result& maybeHas(const std::string& name) {
147  return has<epics::pvData::Field>(name, true, fn);
148  }
149 
164  template<Result& (*fn)(Result&), typename T>
165  Result& has(const std::string& name) {
166  return has<T>(name, false, fn);
167  }
168 
181  template<Result& (*fn)(Result&), typename T>
182  Result& maybeHas(const std::string& name) {
183  return has<T>(name, true, fn);
184  }
185 
199  template<typename T>
200  Result& has(const std::string& name) {
201  return has<T>(name, false, NULL);
202  }
203 
215  template<typename T>
216  Result& maybeHas(const std::string& name) {
217  return has<T>(name, true, NULL);
218  }
219 
220  std::ostream& dump(std::ostream& os) const {
221  os << "Result(valid=" << (result == Pass) << ", errors=[ ";
222 
223  std::vector<Error>::const_iterator it;
224  for (it = errors.begin(); it != errors.end(); ++it) {
225  (*it).dump(os);
226  os << " ";
227  }
228  os << "])";
229  return os;
230  }
231 
232 private:
233  template<typename T>
234  Result& has(const std::string& name, bool optional, Result& (*check)(Result&) = NULL) {
236 
237  switch(field->getType()) {
239  subField = static_cast<epics::pvData::Structure const *>(field.get())->getField(name);
240  break;
242  subField = static_cast<epics::pvData::StructureArray const *>(field.get())->getStructure()->getField(name);
243  break;
245  subField = static_cast<epics::pvData::Union const *>(field.get())->getField(name);
246  break;
248  subField = static_cast<epics::pvData::UnionArray const *>(field.get())->getUnion()->getField(name);
249  break;
250  default:
251  // Expected a structure-like Field
252  result = Fail;
253  errors.push_back(Error(path, Error::IncorrectType));
254  return *this;
255  }
256 
257  std::string subFieldPath(path.empty() ? name : path + "." + name);
258 
259  if (!subField) {
260  if (!optional) {
261  result = Fail;
262  errors.push_back(Error(subFieldPath, Error::MissingField));
263  }
264  } else if (!dynamic_cast<T const *>(subField.get())) {
265  result = Fail;
266  errors.push_back(Error(subFieldPath, Error::IncorrectType));
267  } else if (check) {
268  Result r(subField, subFieldPath);
269  *this |= check(r);
270  }
271 
272  return *this;
273  }
274 };
275 }}
276 
277 #endif
epics::pvData::FieldConstPtr field
Definition: validator.h:52
#define max(x, y)
Definition: flexdef.h:81
This class implements introspection object for a union.
Definition: pvIntrospect.h:866
Result & is(void)
Definition: validator.h:89
Result & maybeHas(const std::string &name)
Definition: validator.h:146
Result(const epics::pvData::FieldConstPtr &field, const std::string &path=std::string())
Definition: validator.h:61
Validation methods for NT types.
Definition: validator.h:23
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
Result & is(const std::string &id)
Definition: validator.h:108
#define NULL
Definition: catime.c:38
enum epics::nt::Result::result_t result
Result & has(const std::string &name)
Definition: validator.h:165
Result & maybeHas(const std::string &name)
Definition: validator.h:182
bool operator==(const Error &other) const
Definition: validator.h:35
Error(std::string const &path, Type type)
Definition: validator.h:32
std::ostream & dump(std::ostream &os) const
Definition: validator.h:39
This class implements introspection object for a structure.
Definition: pvIntrospect.h:697
std::string path
Definition: validator.h:53
This class implements introspection object for a unionArray.
Definition: pvIntrospect.h:652
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
enum epics::nt::Result::Error::Type type
Result & operator|=(const Result &other)
Definition: validator.h:66
std::vector< Error > errors
Definition: validator.h:54
This class implements introspection object for a structureArray.
Definition: pvIntrospect.h:607
Result & has(const std::string &name)
Definition: validator.h:132
const ChannelProviderRegistry::factoryfn_t fn
std::ostream & dump(std::ostream &os) const
Definition: validator.h:220
bool valid(void) const
Definition: validator.h:77