Open Lighting Architecture  0.9.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Descriptor.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * Descriptor.h
17  * Holds the metadata (schema) for a Message.
18  * Copyright (C) 2011 Simon Newton
19  */
20 
21 #ifndef INCLUDE_OLA_MESSAGING_DESCRIPTOR_H_
22 #define INCLUDE_OLA_MESSAGING_DESCRIPTOR_H_
23 
24 #include <ola/messaging/DescriptorVisitor.h>
26 #include <ola/network/MACAddress.h>
27 #include <ola/rdm/UID.h>
28 #include <map>
29 #include <string>
30 #include <vector>
31 #include <utility>
32 
33 namespace ola {
34 namespace messaging {
35 
36 class FieldDescriptorVisitor;
37 
42  public:
43  virtual ~FieldDescriptorInterface() {}
44 
45  // Returns the name of this field
46  virtual const std::string& Name() const = 0;
47 
48  // Call back into a FieldDescriptorVisitor
49  virtual void Accept(FieldDescriptorVisitor *visitor) const = 0;
50 
51  // Returns true if the size of this field is constant
52  virtual bool FixedSize() const = 0;
53 
54  // True if there is some bound on the field's size.
55  virtual bool LimitedSize() const = 0;
56 
57  // This is the max size in bytes of the field. This is only valid if
58  // LimitedSize() is true, otherwise it returns 0.
59  virtual unsigned int MaxSize() const = 0;
60 };
61 
62 
67  public:
68  explicit FieldDescriptor(const std::string &name)
69  : m_name(name) {
70  }
71  virtual ~FieldDescriptor() {}
72 
73  // Returns the name of this field
74  const std::string& Name() const { return m_name; }
75 
76  private:
77  std::string m_name;
78 };
79 
80 
85  public:
86  explicit BoolFieldDescriptor(const std::string &name)
87  : FieldDescriptor(name) {
88  }
89 
90  bool FixedSize() const { return true; }
91  bool LimitedSize() const { return true; }
92  unsigned int MaxSize() const { return 1; }
93 
94  void Accept(FieldDescriptorVisitor *visitor) const {
95  visitor->Visit(this);
96  }
97 };
98 
99 
104  public:
105  explicit IPV4FieldDescriptor(const std::string &name)
106  : FieldDescriptor(name) {
107  }
108 
109  bool FixedSize() const { return true; }
110  bool LimitedSize() const { return true; }
111  unsigned int MaxSize() const { return ola::network::IPV4Address::LENGTH; }
112 
113  void Accept(FieldDescriptorVisitor *visitor) const {
114  visitor->Visit(this);
115  }
116 };
117 
118 
123  public:
124  explicit MACFieldDescriptor(const std::string &name)
125  : FieldDescriptor(name) {
126  }
127 
128  bool FixedSize() const { return true; }
129  bool LimitedSize() const { return true; }
130  unsigned int MaxSize() const { return ola::network::MACAddress::LENGTH; }
131 
132  void Accept(FieldDescriptorVisitor *visitor) const {
133  visitor->Visit(this);
134  }
135 };
136 
137 
142  public:
143  explicit UIDFieldDescriptor(const std::string &name)
144  : FieldDescriptor(name) {
145  }
146 
147  bool FixedSize() const { return true; }
148  bool LimitedSize() const { return true; }
149  unsigned int MaxSize() const { return ola::rdm::UID::LENGTH; }
150 
151  void Accept(FieldDescriptorVisitor *visitor) const {
152  visitor->Visit(this);
153  }
154 };
155 
156 
161  public:
162  StringFieldDescriptor(const std::string &name,
163  uint8_t min_size,
164  uint8_t max_size)
165  : FieldDescriptor(name),
166  m_min_size(min_size),
167  m_max_size(max_size) {
168  }
169 
170  bool FixedSize() const { return m_min_size == m_max_size; }
171  bool LimitedSize() const { return true; }
172  unsigned int MinSize() const { return m_min_size; }
173  unsigned int MaxSize() const { return m_max_size; }
174 
175  void Accept(FieldDescriptorVisitor *visitor) const {
176  visitor->Visit(this);
177  }
178 
179  private:
180  uint8_t m_min_size, m_max_size;
181 };
182 
183 
189 template <typename type>
191  public:
192  typedef std::pair<type, type> Interval;
193  typedef std::vector<std::pair<type, type> > IntervalVector;
194  typedef std::map<std::string, type> LabeledValues;
195 
196  IntegerFieldDescriptor(const std::string &name,
197  bool little_endian = false,
198  int8_t multiplier = 0)
199  : FieldDescriptor(name),
200  m_little_endian(little_endian),
201  m_multipler(multiplier) {
202  }
203 
204  IntegerFieldDescriptor(const std::string &name,
205  const IntervalVector &intervals,
206  const LabeledValues &labels,
207  bool little_endian = false,
208  int8_t multiplier = 0)
209  : FieldDescriptor(name),
210  m_little_endian(little_endian),
211  m_multipler(multiplier),
212  m_intervals(intervals),
213  m_labels(labels) {
214  }
215 
216  bool FixedSize() const { return true; }
217  bool LimitedSize() const { return true; }
218  unsigned int MaxSize() const { return sizeof(type); }
219  int8_t Multiplier() const { return m_multipler; }
220  bool IsLittleEndian() const { return m_little_endian; }
221 
222  const IntervalVector &Intervals() const { return m_intervals; }
223 
224  bool IsValid(type value) const {
225  if (m_intervals.empty())
226  return true;
227 
228  typename IntervalVector::const_iterator iter = m_intervals.begin();
229  for (; iter != m_intervals.end(); ++iter) {
230  if (value >= iter->first && value <= iter->second)
231  return true;
232  }
233  return false;
234  }
235 
236  const LabeledValues &Labels() const { return m_labels; }
237 
238  bool LookupLabel(const std::string &label, type *value) const {
239  typename LabeledValues::const_iterator iter = m_labels.find(label);
240  if (iter == m_labels.end())
241  return false;
242  *value = iter->second;
243  return true;
244  }
245 
246  const std::string LookupValue(type value) const {
247  typename LabeledValues::const_iterator iter = m_labels.begin();
248  for (; iter != m_labels.end(); ++iter) {
249  if (iter->second == value)
250  return iter->first;
251  }
252  return "";
253  }
254 
255  void Accept(FieldDescriptorVisitor *visitor) const {
256  visitor->Visit(this);
257  }
258 
259  private:
260  bool m_little_endian;
261  int8_t m_multipler;
262  IntervalVector m_intervals;
263  LabeledValues m_labels;
264 };
265 
266 
273 
274 
321  public:
322  static const int16_t UNLIMITED_BLOCKS;
323 
324  FieldDescriptorGroup(const std::string &name,
325  const std::vector<const FieldDescriptor*> &fields,
326  uint16_t min_blocks,
327  int16_t max_blocks)
328  : FieldDescriptor(name),
329  m_fields(fields),
330  m_min_blocks(min_blocks),
331  m_max_blocks(max_blocks),
332  m_populated(false),
333  m_fixed_size(true),
334  m_limited_size(true),
335  m_block_size(0),
336  m_max_block_size(0) {
337  }
338  virtual ~FieldDescriptorGroup();
339 
340  // This is true iff all fields in a group are of a fixed size and the
341  // number of blocks is fixed
342  bool FixedSize() const { return FixedBlockSize() && FixedBlockCount(); }
343 
344  // True if the number of blocks has some bound, and all fields also have
345  // some bound.
346  bool LimitedSize() const;
347 
348  // This is the max size of the group, which is only valid if LimitedSize()
349  // is true, otherwise it returns 0.
350  unsigned int MaxSize() const;
351 
352  // Field information
353  // the number of fields in this group
354  unsigned int FieldCount() const { return m_fields.size(); }
355  // True if all the fields in this group are a fixed size. This is then a
356  // type 2 group as described above.
357  bool FixedBlockSize() const;
358  // If this block size is fixed, this returns the size of a single block,
359  // otherwise it returns 0;
360  unsigned int BlockSize() const;
361  // If this block size is bounded, this returns the size of the block.
362  unsigned int MaxBlockSize() const;
363 
364  // Blocks
365  // The minimum number of blocks, usually 0 or 1.
366  uint16_t MinBlocks() const { return m_min_blocks; }
367  // A max size of UNLIMITED_BLOCKS means no restrictions on the number of
368  // blocks
369  int16_t MaxBlocks() const { return m_max_blocks; }
370  // True if the block count is fixed.
371  bool FixedBlockCount() const { return m_min_blocks == m_max_blocks; }
372 
373 
374  const class FieldDescriptor *GetField(unsigned int index) const {
375  if (index < m_fields.size())
376  return m_fields[index];
377  return NULL;
378  }
379 
380  virtual void Accept(FieldDescriptorVisitor *visitor) const;
381 
382  protected:
383  std::vector<const class FieldDescriptor *> m_fields;
384 
385  private:
386  uint16_t m_min_blocks;
387  int16_t m_max_blocks;
388  mutable bool m_populated;
389  mutable bool m_fixed_size, m_limited_size;
390  mutable unsigned int m_block_size, m_max_block_size;
391 
392  void PopulateIfRequired() const;
393 };
394 
395 
400  public:
401  Descriptor(const std::string &name,
402  const std::vector<const FieldDescriptor*> &fields)
403  : FieldDescriptorGroup(name, fields, 1, 1) {}
404 
405  void Accept(FieldDescriptorVisitor *visitor) const;
406 };
407 } // namespace messaging
408 } // namespace ola
409 
410 #endif // INCLUDE_OLA_MESSAGING_DESCRIPTOR_H_