Open Lighting Architecture  Latest Git
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_multiplier(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_multiplier(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_multiplier; }
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_multiplier;
262  IntervalVector m_intervals;
263  LabeledValues m_labels;
264 };
265 
266 
273 
274 
325  public:
326  static const int16_t UNLIMITED_BLOCKS;
327 
328  FieldDescriptorGroup(const std::string &name,
329  const std::vector<const FieldDescriptor*> &fields,
330  uint16_t min_blocks,
331  int16_t max_blocks)
332  : FieldDescriptor(name),
333  m_fields(fields),
334  m_min_blocks(min_blocks),
335  m_max_blocks(max_blocks),
336  m_populated(false),
337  m_fixed_size(true),
338  m_limited_size(true),
339  m_block_size(0),
340  m_max_block_size(0) {
341  }
342  virtual ~FieldDescriptorGroup();
343 
344  // This is true iff all fields in a group are of a fixed size and the
345  // number of blocks is fixed
346  bool FixedSize() const { return FixedBlockSize() && FixedBlockCount(); }
347 
348  // True if the number of blocks has some bound, and all fields also have
349  // some bound.
350  bool LimitedSize() const;
351 
352  // This is the max size of the group, which is only valid if LimitedSize()
353  // is true, otherwise it returns 0.
354  unsigned int MaxSize() const;
355 
356  // Field information
357  // the number of fields in this group
358  unsigned int FieldCount() const { return m_fields.size(); }
359  // True if all the fields in this group are a fixed size. This is then a
360  // type 2 group as described above.
361  bool FixedBlockSize() const;
362  // If this block size is fixed, this returns the size of a single block,
363  // otherwise it returns 0;
364  unsigned int BlockSize() const;
365  // If this block size is bounded, this returns the size of the block.
366  unsigned int MaxBlockSize() const;
367 
368  // Blocks
369  // The minimum number of blocks, usually 0 or 1.
370  uint16_t MinBlocks() const { return m_min_blocks; }
371  // A max size of UNLIMITED_BLOCKS means no restrictions on the number of
372  // blocks
373  int16_t MaxBlocks() const { return m_max_blocks; }
374  // True if the block count is fixed.
375  bool FixedBlockCount() const { return m_min_blocks == m_max_blocks; }
376 
377 
378  const class FieldDescriptor *GetField(unsigned int index) const {
379  if (index < m_fields.size())
380  return m_fields[index];
381  return NULL;
382  }
383 
384  virtual void Accept(FieldDescriptorVisitor *visitor) const;
385 
386  protected:
387  std::vector<const class FieldDescriptor *> m_fields;
388 
389  private:
390  uint16_t m_min_blocks;
391  int16_t m_max_blocks;
392  mutable bool m_populated;
393  mutable bool m_fixed_size, m_limited_size;
394  mutable unsigned int m_block_size, m_max_block_size;
395 
396  void PopulateIfRequired() const;
397 };
398 
399 
404  public:
405  Descriptor(const std::string &name,
406  const std::vector<const FieldDescriptor*> &fields)
407  : FieldDescriptorGroup(name, fields, 1, 1) {}
408 
409  void Accept(FieldDescriptorVisitor *visitor) const;
410 };
411 } // namespace messaging
412 } // namespace ola
413 
414 #endif // INCLUDE_OLA_MESSAGING_DESCRIPTOR_H_
Definition: Descriptor.h:84
Definition: DescriptorVisitor.h:43
Definition: Descriptor.h:66
A RDM unique identifier (UID).
Definition: Descriptor.h:122
Definition: Descriptor.h:324
Definition: Descriptor.h:41
Definition: Descriptor.h:141
Definition: Descriptor.h:103
Represents an IPv4 Address.
Definition: Descriptor.h:160
Definition: Descriptor.h:403
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
Represents a MAC Address.
Definition: Descriptor.h:190