IWAField.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libetonyek project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #ifndef IWAFIELD_H_INCLUDED
11 #define IWAFIELD_H_INCLUDED
12 
13 #include <deque>
14 #include <memory>
15 #include <stdexcept>
16 
17 #include <boost/container/deque.hpp>
18 #include <boost/optional.hpp>
19 
20 #include "IWAReader.h"
21 #include "libetonyek_utils.h"
22 
23 namespace libetonyek
24 {
25 
26 class IWAField
27 {
28 public:
29  enum Tag
30  {
48  };
49 
50 public:
51  virtual ~IWAField() = 0;
52 
53  virtual Tag tag() const = 0;
54 
55  // repeated
56  virtual bool empty() const = 0;
57  virtual std::size_t size() const = 0;
58 
59  // optional
60  virtual bool is() const = 0;
61  operator bool() const;
62  bool operator!() const;
63 
64  virtual void parse(const RVNGInputStreamPtr_t &input, unsigned long length, bool allowEmpty) = 0;
65 };
66 
67 typedef std::shared_ptr<IWAField> IWAFieldPtr_t;
68 
69 namespace detail
70 {
71 
72 template<IWAField::Tag TagV, typename ValueT, typename Reader>
73 class IWAFieldImpl : public IWAField
74 {
75  typedef boost::container::deque<ValueT> container_type;
76 
77 public:
78  typedef ValueT value_type;
79  typedef ValueT &reference_type;
80  typedef const ValueT &const_reference_type;
81  typedef typename container_type::const_iterator const_iterator;
82  typedef typename container_type::const_reverse_iterator const_reverse_iterator;
83 
84 public:
85  // classification
86 
87  IWAField::Tag tag() const override
88  {
89  return TagV;
90  }
91 
92  // optional interface
93 
94  bool is() const override
95  {
96  return !m_values.empty();
97  }
98 
99  const_reference_type get() const
100  {
101  if (m_values.empty())
102  throw std::logic_error("the field is unset");
103  return m_values[0];
104  }
105 
106  // container interface
107 
108  bool empty() const override
109  {
110  return m_values.empty();
111  }
112 
113  std::size_t size() const override
114  {
115  return m_values.size();
116  }
117 
118  const_reference_type operator[](const std::size_t index) const
119  {
120  if (index >= m_values.size())
121  throw std::out_of_range("index is out of range");
122  return m_values[index];
123  }
124 
125  const_iterator begin() const
126  {
127  return m_values.begin();
128  }
129 
130  const_iterator end() const
131  {
132  return m_values.end();
133  }
134 
135  const_reverse_iterator rbegin() const
136  {
137  return m_values.rbegin();
138  }
139 
140  const_reverse_iterator rend() const
141  {
142  return m_values.rend();
143  }
144 
145  // conversions
146 
147  // TODO: remove this or replace direct use of std::deque by a typedef
148  const std::deque<value_type> repeated() const
149  {
150  const std::deque<value_type> values(m_values.begin(), m_values.end());
151  return values;
152  }
153 
154  const boost::optional<value_type> optional() const
155  {
156  return m_values.empty() ? boost::none : boost::make_optional(m_values.front());
157  }
158 
159  // initialization
160 
161  void parse(const RVNGInputStreamPtr_t &input, const unsigned long length, const bool allowEmpty) override
162  {
163  if (length != 0)
164  {
165  const long start = input->tell();
166  while (!input->isEnd() && (length > static_cast<unsigned long>(input->tell() - start)))
167  {
168  const value_type value(Reader::read(input, length));
169  m_values.push_back(value);
170  }
171  }
172  else if (allowEmpty)
173  {
174  m_values.push_back(value_type());
175  }
176  }
177 
178 private:
179  container_type m_values;
180 };
181 
182 }
183 
184 template<IWAField::Tag TagV, typename ValueT, typename Reader>
185 const ValueT &get(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field)
186 {
187  return field.get();
188 }
189 
190 template<IWAField::Tag TagV, typename ValueT, typename Reader>
191 const ValueT &get_optional_value_or(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field, const ValueT &value)
192 {
193  return bool(field) ? field.get() : value;
194 }
195 
196 template<IWAField::Tag TagV, typename ValueT, typename Reader, typename DefaultValueT>
197 const ValueT get_optional_value_or(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field, const DefaultValueT &value)
198 {
199  return bool(field) ? field.get() : ValueT(value);
200 }
201 
207 
210 
213 
216 
217 class IWAMessageField : public detail::IWAFieldImpl<IWAField::TAG_MESSAGE, IWAMessage, IWAReader::Message>
218 {
219 public:
220  const IWAUInt32Field &uint32(std::size_t field) const;
221  const IWAUInt64Field &uint64(std::size_t field) const;
222  const IWASInt32Field &sint32(std::size_t field) const;
223  const IWASInt64Field &sint64(std::size_t field) const;
224  const IWABoolField &bool_(std::size_t field) const;
225 
226  const IWAFixed64Field &fixed64(std::size_t field) const;
227  const IWADoubleField &double_(std::size_t field) const;
228 
229  const IWAStringField &string(std::size_t field) const;
230  const IWABytesField &bytes(std::size_t field) const;
231  const IWAMessageField &message(std::size_t field) const;
232 
233  const IWAFixed32Field &fixed32(std::size_t field) const;
234  const IWAFloatField &float_(std::size_t field) const;
235 };
236 
237 }
238 
239 #endif
240 
241 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
virtual bool empty() const =0
const std::deque< value_type > repeated() const
Definition: IWAField.h:148
Definition: IWORKBezierElement.cpp:18
std::size_t size() const override
Definition: IWAField.h:113
Definition: IWAField.h:44
detail::IWAFieldImpl< IWAField::TAG_FIXED64, uint64_t, IWAReader::Fixed64 > IWAFixed64Field
Definition: IWAField.h:208
Definition: IWAField.h:33
detail::IWAFieldImpl< IWAField::TAG_BOOL, bool, IWAReader::Bool > IWABoolField
Definition: IWAField.h:206
const_reference_type get() const
Definition: IWAField.h:99
detail::IWAFieldImpl< IWAField::TAG_STRING, std::string, IWAReader::String > IWAStringField
Definition: IWAField.h:211
detail::IWAFieldImpl< IWAField::TAG_UINT64, uint64_t, IWAReader::UInt64 > IWAUInt64Field
Definition: IWAField.h:203
boost::container::deque< ValueT > container_type
Definition: IWAField.h:75
Definition: IWAField.h:37
detail::IWAFieldImpl< IWAField::TAG_UINT32, uint32_t, IWAReader::UInt32 > IWAUInt32Field
Definition: IWAField.h:202
Definition: IWAField.h:34
virtual std::size_t size() const =0
const_iterator end() const
Definition: IWAField.h:130
virtual bool is() const =0
virtual ~IWAField()=0
Definition: IWAField.cpp:16
Definition: IWAField.h:32
ValueT value_type
Definition: IWAField.h:78
Definition: IWORKToken.h:399
const boost::optional< value_type > optional() const
Definition: IWAField.h:154
Definition: IWAField.h:46
virtual void parse(const RVNGInputStreamPtr_t &input, unsigned long length, bool allowEmpty)=0
detail::IWAFieldImpl< IWAField::TAG_FLOAT, float, IWAReader::Float > IWAFloatField
Definition: IWAField.h:215
Definition: IWAField.h:31
detail::IWAFieldImpl< IWAField::TAG_SINT32, int32_t, IWAReader::SInt32 > IWASInt32Field
Definition: IWAField.h:204
Tag
Definition: IWAField.h:29
const_reference_type operator[](const std::size_t index) const
Definition: IWAField.h:118
Definition: IWAField.h:41
Definition: IWAField.h:45
detail::IWAFieldImpl< IWAField::TAG_BYTES, RVNGInputStreamPtr_t, IWAReader::Bytes > IWABytesField
Definition: IWAField.h:212
container_type m_values
Definition: IWAField.h:179
IWAField::Tag tag() const override
Definition: IWAField.h:87
detail::IWAFieldImpl< IWAField::TAG_DOUBLE, double, IWAReader::Double > IWADoubleField
Definition: IWAField.h:209
Definition: IWAField.h:47
container_type::const_reverse_iterator const_reverse_iterator
Definition: IWAField.h:82
Definition: IWAField.h:43
const ValueT & get_optional_value_or(const detail::IWAFieldImpl< TagV, ValueT, Reader > &field, const ValueT &value)
Definition: IWAField.h:191
std::shared_ptr< librevenge::RVNGInputStream > RVNGInputStreamPtr_t
Definition: libetonyek_utils.h:82
const_reverse_iterator rend() const
Definition: IWAField.h:140
const_reverse_iterator rbegin() const
Definition: IWAField.h:135
Definition: IWAField.h:36
void parse(const RVNGInputStreamPtr_t &input, const unsigned long length, const bool allowEmpty) override
Definition: IWAField.h:161
const_iterator begin() const
Definition: IWAField.h:125
Definition: IWAField.h:73
bool empty() const override
Definition: IWAField.h:108
const ValueT & const_reference_type
Definition: IWAField.h:80
Definition: IWORKToken.h:390
Definition: IWAField.h:217
Definition: IWAField.h:40
Definition: IWORKToken.h:266
Definition: IWAField.h:26
ValueT & reference_type
Definition: IWAField.h:79
Definition: IWAField.h:35
bool is() const override
Definition: IWAField.h:94
detail::IWAFieldImpl< IWAField::TAG_SINT64, int64_t, IWAReader::SInt64 > IWASInt64Field
Definition: IWAField.h:205
bool operator!() const
Definition: IWAField.cpp:25
Definition: IWAField.h:42
Definition: IWAField.h:38
Definition: IWAField.h:39
container_type::const_iterator const_iterator
Definition: IWAField.h:81
std::shared_ptr< IWAField > IWAFieldPtr_t
Definition: IWAField.h:67
detail::IWAFieldImpl< IWAField::TAG_FIXED32, uint32_t, IWAReader::Fixed32 > IWAFixed32Field
Definition: IWAField.h:214
virtual Tag tag() const =0

Generated for libetonyek by doxygen 1.8.13