Open Lighting Architecture
 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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>
25 #include <map>
26 #include <string>
27 #include <vector>
28 #include <utility>
29 
30 using std::string;
31 using std::vector;
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 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 string &name)
69  : m_name(name) {
70  }
71  virtual ~FieldDescriptor() {}
72 
73  // Returns the name of this field
74  const string& Name() const { return m_name; }
75 
76  private:
77  string m_name;
78 };
79 
80 
85  public:
86  explicit BoolFieldDescriptor(const 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 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 4; }
112 
113  void Accept(FieldDescriptorVisitor *visitor) const {
114  visitor->Visit(this);
115  }
116 };
117 
118 
123  public:
124  explicit UIDFieldDescriptor(const 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 6; }
131 
132  void Accept(FieldDescriptorVisitor *visitor) const {
133  visitor->Visit(this);
134  }
135 };
136 
137 
142  public:
143  StringFieldDescriptor(const string &name,
144  uint8_t min_size,
145  uint8_t max_size)
146  : FieldDescriptor(name),
147  m_min_size(min_size),
148  m_max_size(max_size) {
149  }
150 
151  bool FixedSize() const { return m_min_size == m_max_size; }
152  bool LimitedSize() const { return true; }
153  unsigned int MinSize() const { return m_min_size; }
154  unsigned int MaxSize() const { return m_max_size; }
155 
156  void Accept(FieldDescriptorVisitor *visitor) const {
157  visitor->Visit(this);
158  }
159 
160  private:
161  uint8_t m_min_size, m_max_size;
162 };
163 
164 
170 template <typename type>
172  public:
173  typedef std::pair<type, type> Interval;
174  typedef vector<std::pair<type, type> > IntervalVector;
175  typedef std::map<string, type> LabeledValues;
176 
177  IntegerFieldDescriptor(const string &name,
178  bool little_endian = false,
179  int8_t multiplier = 0)
180  : FieldDescriptor(name),
181  m_little_endian(little_endian),
182  m_multipler(multiplier) {
183  }
184 
185  IntegerFieldDescriptor(const string &name,
186  const IntervalVector &intervals,
187  const LabeledValues &labels,
188  bool little_endian = false,
189  int8_t multiplier = 0)
190  : FieldDescriptor(name),
191  m_little_endian(little_endian),
192  m_multipler(multiplier),
193  m_intervals(intervals),
194  m_labels(labels) {
195  }
196 
197  bool FixedSize() const { return true; }
198  bool LimitedSize() const { return true; }
199  unsigned int MaxSize() const { return sizeof(type); }
200  int8_t Multiplier() const { return m_multipler; }
201  bool IsLittleEndian() const { return m_little_endian; }
202 
203  const IntervalVector &Intervals() const { return m_intervals; }
204 
205  bool IsValid(type value) const {
206  if (m_intervals.empty())
207  return true;
208 
209  typename IntervalVector::const_iterator iter = m_intervals.begin();
210  for (; iter != m_intervals.end(); ++iter) {
211  if (value >= iter->first && value <= iter->second)
212  return true;
213  }
214  return false;
215  }
216 
217  const LabeledValues &Labels() const { return m_labels; }
218 
219  bool LookupLabel(const string &label, type *value) const {
220  typename LabeledValues::const_iterator iter = m_labels.find(label);
221  if (iter == m_labels.end())
222  return false;
223  *value = iter->second;
224  return true;
225  }
226 
227  const string LookupValue(type value) const {
228  typename LabeledValues::const_iterator iter = m_labels.begin();
229  for (; iter != m_labels.end(); ++iter) {
230  if (iter->second == value)
231  return iter->first;
232  }
233  return "";
234  }
235 
236  void Accept(FieldDescriptorVisitor *visitor) const {
237  visitor->Visit(this);
238  }
239 
240  private:
241  bool m_little_endian;
242  int8_t m_multipler;
243  IntervalVector m_intervals;
244  LabeledValues m_labels;
245 };
246 
247 
254 
255 
302  public:
303  static const int16_t UNLIMITED_BLOCKS;
304 
305  FieldDescriptorGroup(const string &name,
306  const vector<const FieldDescriptor*> &fields,
307  uint16_t min_blocks,
308  int16_t max_blocks)
309  : FieldDescriptor(name),
310  m_fields(fields),
311  m_min_blocks(min_blocks),
312  m_max_blocks(max_blocks),
313  m_populated(false),
314  m_fixed_size(true),
315  m_limited_size(true),
316  m_block_size(0),
317  m_max_block_size(0) {
318  }
319  virtual ~FieldDescriptorGroup();
320 
321  // This is true iff all fields in a group are of a fixed size and the
322  // number of blocks is fixed
323  bool FixedSize() const { return FixedBlockSize() && FixedBlockCount(); }
324 
325  // True if the number of blocks has some bound, and all fields also have
326  // some bound.
327  bool LimitedSize() const;
328 
329  // This is the max size of the group, which is only valid if LimitedSize()
330  // is true, otherwise it returns 0.
331  unsigned int MaxSize() const;
332 
333  // Field information
334  // the number of fields in this group
335  unsigned int FieldCount() const { return m_fields.size(); }
336  // True if all the fields in this group are a fixed size. This is then a
337  // type 2 group as described above.
338  bool FixedBlockSize() const;
339  // If this block size is fixed, this returns the size of a single block,
340  // otherwise it returns 0;
341  unsigned int BlockSize() const;
342  // If this block size is bounded, this returns the size of the block.
343  unsigned int MaxBlockSize() const;
344 
345  // Blocks
346  // The minimum number of blocks, usually 0 or 1.
347  uint16_t MinBlocks() const { return m_min_blocks; }
348  // A max size of UNLIMITED_BLOCKS means no restrictions on the number of
349  // blocks
350  int16_t MaxBlocks() const { return m_max_blocks; }
351  // True if the block count is fixed.
352  bool FixedBlockCount() const { return m_min_blocks == m_max_blocks; }
353 
354 
355  const class FieldDescriptor *GetField(unsigned int index) const {
356  if (index < m_fields.size())
357  return m_fields[index];
358  return NULL;
359  }
360 
361  virtual void Accept(FieldDescriptorVisitor *visitor) const;
362 
363  protected:
364  vector<const class FieldDescriptor *> m_fields;
365 
366  private:
367  uint16_t m_min_blocks;
368  int16_t m_max_blocks;
369  mutable bool m_populated;
370  mutable bool m_fixed_size, m_limited_size;
371  mutable unsigned int m_block_size, m_max_block_size;
372 
373  void PopulateIfRequired() const;
374 };
375 
376 
381  public:
382  Descriptor(const string &name,
383  const vector<const FieldDescriptor*> &fields)
384  : FieldDescriptorGroup(name, fields, 1, 1) {}
385 
386  void Accept(FieldDescriptorVisitor *visitor) const;
387 };
388 } // namespace messaging
389 } // namespace ola
390 
391 #endif // INCLUDE_OLA_MESSAGING_DESCRIPTOR_H_