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 {
31 TAG_INT32,
32 TAG_INT64,
33 TAG_UINT32,
34 TAG_UINT64,
35 TAG_SINT32,
36 TAG_SINT64,
37 TAG_BOOL,
38 TAG_ENUM,
39 TAG_FIXED64,
40 TAG_SFIXED64,
41 TAG_DOUBLE,
42 TAG_STRING,
43 TAG_BYTES,
44 TAG_MESSAGE,
45 TAG_FIXED32,
46 TAG_SFIXED32,
47 TAG_FLOAT
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 IWAFieldImpl()
86 : IWAField()
87 , m_values()
88 {
89 }
90 // classification
91
92 IWAField::Tag tag() const override
93 {
94 return TagV;
95 }
96
97 // optional interface
98
99 bool is() const override
100 {
101 return !m_values.empty();
102 }
103
104 const_reference_type get() const
105 {
106 if (m_values.empty())
107 throw std::logic_error("the field is unset");
108 return m_values[0];
109 }
110
111 // container interface
112
113 bool empty() const override
114 {
115 return m_values.empty();
116 }
117
118 std::size_t size() const override
119 {
120 return m_values.size();
121 }
122
123 const_reference_type operator[](const std::size_t index) const
124 {
125 if (index >= m_values.size())
126 throw std::out_of_range("index is out of range");
127 return m_values[index];
128 }
129
130 const_iterator begin() const
131 {
132 return m_values.begin();
133 }
134
135 const_iterator end() const
136 {
137 return m_values.end();
138 }
139
140 const_reverse_iterator rbegin() const
141 {
142 return m_values.rbegin();
143 }
144
145 const_reverse_iterator rend() const
146 {
147 return m_values.rend();
148 }
149
150 // conversions
151
152 // TODO: remove this or replace direct use of std::deque by a typedef
153 const std::deque<value_type> repeated() const
154 {
155 const std::deque<value_type> values(m_values.begin(), m_values.end());
156 return values;
157 }
158
159 const boost::optional<value_type> optional() const
160 {
161 return m_values.empty() ? boost::none : boost::make_optional(m_values.front());
162 }
163
164 // initialization
165
166 void parse(const RVNGInputStreamPtr_t &input, const unsigned long length, const bool allowEmpty) override
167 {
168 if (length != 0)
169 {
170 const long start = input->tell();
171 while (!input->isEnd() && (length > static_cast<unsigned long>(input->tell() - start)))
172 {
173 const value_type value(Reader::read(input, length));
174 m_values.push_back(value);
175 }
176 }
177 else if (allowEmpty)
178 {
179 m_values.push_back(value_type());
180 }
181 }
182
183 private:
184 container_type m_values;
185};
186
187}
188
189 template<IWAField::Tag TagV, typename ValueT, typename Reader>
190 const ValueT &get(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field)
191{
192 return field.get();
193}
194
195 template<IWAField::Tag TagV, typename ValueT, typename Reader>
196 const ValueT &get_optional_value_or(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field, const ValueT &value)
197{
198 return bool(field) ? field.get() : value;
199}
200
201 template<IWAField::Tag TagV, typename ValueT, typename Reader, typename DefaultValueT>
202 const ValueT get_optional_value_or(const detail::IWAFieldImpl<TagV, ValueT, Reader> &field, const DefaultValueT &value)
203{
204 return bool(field) ? field.get() : ValueT(value);
205}
206
207 typedef detail::IWAFieldImpl<IWAField::TAG_UINT32, uint32_t, IWAReader::UInt32> IWAUInt32Field;
208 typedef detail::IWAFieldImpl<IWAField::TAG_UINT64, uint64_t, IWAReader::UInt64> IWAUInt64Field;
209 typedef detail::IWAFieldImpl<IWAField::TAG_SINT32, int32_t, IWAReader::SInt32> IWASInt32Field;
210 typedef detail::IWAFieldImpl<IWAField::TAG_SINT64, int64_t, IWAReader::SInt64> IWASInt64Field;
211 typedef detail::IWAFieldImpl<IWAField::TAG_BOOL, bool, IWAReader::Bool> IWABoolField;
212
213 typedef detail::IWAFieldImpl<IWAField::TAG_FIXED64, uint64_t, IWAReader::Fixed64> IWAFixed64Field;
214 typedef detail::IWAFieldImpl<IWAField::TAG_DOUBLE, double, IWAReader::Double> IWADoubleField;
215
216 typedef detail::IWAFieldImpl<IWAField::TAG_STRING, std::string, IWAReader::String> IWAStringField;
217 typedef detail::IWAFieldImpl<IWAField::TAG_BYTES, RVNGInputStreamPtr_t, IWAReader::Bytes> IWABytesField;
218
219 typedef detail::IWAFieldImpl<IWAField::TAG_FIXED32, uint32_t, IWAReader::Fixed32> IWAFixed32Field;
220 typedef detail::IWAFieldImpl<IWAField::TAG_FLOAT, float, IWAReader::Float> IWAFloatField;
221
222 class IWAMessageField : public detail::IWAFieldImpl<IWAField::TAG_MESSAGE, IWAMessage, IWAReader::Message>
223{
224 public:
225 const IWAUInt32Field &uint32(std::size_t field) const;
226 const IWAUInt64Field &uint64(std::size_t field) const;
227 const IWASInt32Field &sint32(std::size_t field) const;
228 const IWASInt64Field &sint64(std::size_t field) const;
229 const IWABoolField &bool_(std::size_t field) const;
230
231 const IWAFixed64Field &fixed64(std::size_t field) const;
232 const IWADoubleField &double_(std::size_t field) const;
233
234 const IWAStringField &string(std::size_t field) const;
235 const IWABytesField &bytes(std::size_t field) const;
236 const IWAMessageField &message(std::size_t field) const;
237
238 const IWAFixed32Field &fixed32(std::size_t field) const;
239 const IWAFloatField &float_(std::size_t field) const;
240};
241
242}
243
244#endif
245
246/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
IWAReader.h
libetonyek::IWAField
Definition IWAField.h:27
libetonyek::IWAField::tag
virtual Tag tag() const =0
libetonyek::IWAField::Tag
Tag
Definition IWAField.h:30
libetonyek::IWAField::TAG_INT32
@ TAG_INT32
Definition IWAField.h:31
libetonyek::IWAField::TAG_SFIXED64
@ TAG_SFIXED64
Definition IWAField.h:40
libetonyek::IWAField::TAG_BYTES
@ TAG_BYTES
Definition IWAField.h:43
libetonyek::IWAField::TAG_SINT64
@ TAG_SINT64
Definition IWAField.h:36
libetonyek::IWAField::TAG_UINT64
@ TAG_UINT64
Definition IWAField.h:34
libetonyek::IWAField::TAG_BOOL
@ TAG_BOOL
Definition IWAField.h:37
libetonyek::IWAField::TAG_MESSAGE
@ TAG_MESSAGE
Definition IWAField.h:44
libetonyek::IWAField::TAG_SFIXED32
@ TAG_SFIXED32
Definition IWAField.h:46
libetonyek::IWAField::TAG_DOUBLE
@ TAG_DOUBLE
Definition IWAField.h:41
libetonyek::IWAField::TAG_INT64
@ TAG_INT64
Definition IWAField.h:32
libetonyek::IWAField::TAG_FIXED32
@ TAG_FIXED32
Definition IWAField.h:45
libetonyek::IWAField::TAG_SINT32
@ TAG_SINT32
Definition IWAField.h:35
libetonyek::IWAField::TAG_UINT32
@ TAG_UINT32
Definition IWAField.h:33
libetonyek::IWAField::TAG_STRING
@ TAG_STRING
Definition IWAField.h:42
libetonyek::IWAField::TAG_FLOAT
@ TAG_FLOAT
Definition IWAField.h:47
libetonyek::IWAField::TAG_FIXED64
@ TAG_FIXED64
Definition IWAField.h:39
libetonyek::IWAField::TAG_ENUM
@ TAG_ENUM
Definition IWAField.h:38
libetonyek::IWAField::is
virtual bool is() const =0
libetonyek::IWAField::size
virtual std::size_t size() const =0
libetonyek::IWAField::~IWAField
virtual ~IWAField()=0
Definition IWAField.cpp:16
libetonyek::IWAField::operator!
bool operator!() const
Definition IWAField.cpp:25
libetonyek::IWAField::parse
virtual void parse(const RVNGInputStreamPtr_t &input, unsigned long length, bool allowEmpty)=0
libetonyek::IWAField::empty
virtual bool empty() const =0
libetonyek::IWAMessageField
Definition IWAField.h:223
libetonyek::IWAMessageField::float_
const IWAFloatField & float_(std::size_t field) const
Definition IWAField.cpp:80
libetonyek::IWAMessageField::sint64
const IWASInt64Field & sint64(std::size_t field) const
Definition IWAField.cpp:45
libetonyek::IWAMessageField::fixed32
const IWAFixed32Field & fixed32(std::size_t field) const
Definition IWAField.cpp:75
libetonyek::IWAMessageField::fixed64
const IWAFixed64Field & fixed64(std::size_t field) const
Definition IWAField.cpp:55
libetonyek::IWAMessageField::uint64
const IWAUInt64Field & uint64(std::size_t field) const
Definition IWAField.cpp:35
libetonyek::IWAMessageField::bytes
const IWABytesField & bytes(std::size_t field) const
libetonyek::IWAMessageField::uint32
const IWAUInt32Field & uint32(std::size_t field) const
Definition IWAField.cpp:30
libetonyek::IWAMessageField::bool_
const IWABoolField & bool_(std::size_t field) const
Definition IWAField.cpp:50
libetonyek::IWAMessageField::sint32
const IWASInt32Field & sint32(std::size_t field) const
Definition IWAField.cpp:40
libetonyek::IWAMessageField::message
const IWAMessageField & message(std::size_t field) const
Definition IWAField.cpp:70
libetonyek::detail::IWAFieldImpl
Definition IWAField.h:74
libetonyek::detail::IWAFieldImpl::repeated
const std::deque< value_type > repeated() const
Definition IWAField.h:153
libetonyek::detail::IWAFieldImpl::const_reverse_iterator
container_type::const_reverse_iterator const_reverse_iterator
Definition IWAField.h:82
libetonyek::detail::IWAFieldImpl< IWAField::TAG_UINT32, uint32_t, IWAReader::UInt32 >::m_values
container_type m_values
Definition IWAField.h:184
libetonyek::detail::IWAFieldImpl::rend
const_reverse_iterator rend() const
Definition IWAField.h:145
libetonyek::detail::IWAFieldImpl::container_type
boost::container::deque< ValueT > container_type
Definition IWAField.h:75
libetonyek::detail::IWAFieldImpl::empty
bool empty() const override
Definition IWAField.h:113
libetonyek::detail::IWAFieldImpl::begin
const_iterator begin() const
Definition IWAField.h:130
libetonyek::detail::IWAFieldImpl::tag
IWAField::Tag tag() const override
Definition IWAField.h:92
libetonyek::detail::IWAFieldImpl::reference_type
ValueT & reference_type
Definition IWAField.h:79
libetonyek::detail::IWAFieldImpl::rbegin
const_reverse_iterator rbegin() const
Definition IWAField.h:140
libetonyek::detail::IWAFieldImpl::is
bool is() const override
Definition IWAField.h:99
libetonyek::detail::IWAFieldImpl::const_iterator
container_type::const_iterator const_iterator
Definition IWAField.h:81
libetonyek::detail::IWAFieldImpl::operator[]
const_reference_type operator[](const std::size_t index) const
Definition IWAField.h:123
libetonyek::detail::IWAFieldImpl::const_reference_type
const ValueT & const_reference_type
Definition IWAField.h:80
libetonyek::detail::IWAFieldImpl::IWAFieldImpl
IWAFieldImpl()
Definition IWAField.h:85
libetonyek::detail::IWAFieldImpl::parse
void parse(const RVNGInputStreamPtr_t &input, const unsigned long length, const bool allowEmpty) override
Definition IWAField.h:166
libetonyek::detail::IWAFieldImpl::end
const_iterator end() const
Definition IWAField.h:135
libetonyek::detail::IWAFieldImpl::size
std::size_t size() const override
Definition IWAField.h:118
libetonyek::detail::IWAFieldImpl::value_type
ValueT value_type
Definition IWAField.h:78
libetonyek::detail::IWAFieldImpl::get
const_reference_type get() const
Definition IWAField.h:104
libetonyek::detail::IWAFieldImpl::optional
const boost::optional< value_type > optional() const
Definition IWAField.h:159
libetonyek_utils.h
libetonyek::IWORKToken::string
@ string
Definition IWORKToken.h:418
libetonyek::IWORKToken::value
@ value
Definition IWORKToken.h:631
libetonyek::IWORKToken::double_
@ double_
Definition IWORKToken.h:663
libetonyek::IWORKToken::index
@ index
Definition IWORKToken.h:571
libetonyek::IWORKToken::start
@ start
Definition IWORKToken.h:412
libetonyek::detail
Definition IWAField.h:70
libetonyek
Definition IWORKBezierElement.cpp:21
libetonyek::IWAFieldPtr_t
std::shared_ptr< IWAField > IWAFieldPtr_t
Definition IWAField.h:67
libetonyek::IWASInt32Field
detail::IWAFieldImpl< IWAField::TAG_SINT32, int32_t, IWAReader::SInt32 > IWASInt32Field
Definition IWAField.h:209
libetonyek::IWAUInt32Field
detail::IWAFieldImpl< IWAField::TAG_UINT32, uint32_t, IWAReader::UInt32 > IWAUInt32Field
Definition IWAField.h:207
libetonyek::RVNGInputStreamPtr_t
std::shared_ptr< librevenge::RVNGInputStream > RVNGInputStreamPtr_t
Definition libetonyek_utils.h:82
libetonyek::IWASInt64Field
detail::IWAFieldImpl< IWAField::TAG_SINT64, int64_t, IWAReader::SInt64 > IWASInt64Field
Definition IWAField.h:210
libetonyek::IWAUInt64Field
detail::IWAFieldImpl< IWAField::TAG_UINT64, uint64_t, IWAReader::UInt64 > IWAUInt64Field
Definition IWAField.h:208
libetonyek::IWADoubleField
detail::IWAFieldImpl< IWAField::TAG_DOUBLE, double, IWAReader::Double > IWADoubleField
Definition IWAField.h:214
libetonyek::IWABoolField
detail::IWAFieldImpl< IWAField::TAG_BOOL, bool, IWAReader::Bool > IWABoolField
Definition IWAField.h:211
libetonyek::get_optional_value_or
const ValueT & get_optional_value_or(const detail::IWAFieldImpl< TagV, ValueT, Reader > &field, const ValueT &value)
Definition IWAField.h:196
libetonyek::IWAFixed64Field
detail::IWAFieldImpl< IWAField::TAG_FIXED64, uint64_t, IWAReader::Fixed64 > IWAFixed64Field
Definition IWAField.h:213
libetonyek::IWAStringField
detail::IWAFieldImpl< IWAField::TAG_STRING, std::string, IWAReader::String > IWAStringField
Definition IWAField.h:216
libetonyek::IWAFixed32Field
detail::IWAFieldImpl< IWAField::TAG_FIXED32, uint32_t, IWAReader::Fixed32 > IWAFixed32Field
Definition IWAField.h:219
libetonyek::IWAFloatField
detail::IWAFieldImpl< IWAField::TAG_FLOAT, float, IWAReader::Float > IWAFloatField
Definition IWAField.h:220
libetonyek::get
const ValueT & get(const detail::IWAFieldImpl< TagV, ValueT, Reader > &field)
Definition IWAField.h:190
libetonyek::IWABytesField
detail::IWAFieldImpl< IWAField::TAG_BYTES, RVNGInputStreamPtr_t, IWAReader::Bytes > IWABytesField
Definition IWAField.h:217