4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief ParseVec public header */
27 #define HH_ParseVec_ 1
30 #include <boost/iterator/iterator_facade.hpp>
31 #include <boost/utility.hpp>
32 #include <boost/range.hpp>
33 #include <boost/type_traits.hpp>
34 #include "PacketParser.hh"
35 #include "ParseArray.hh" // for Parse_Array_iterator
37 //#include "ParseVec.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
42 template <class ElementParser, class Sizer> class Parse_Vector_Container;
44 /** \brief Collection of fixed-size elements
46 A Vector is a collection of fixed-size elements of which the size of the collection can be
47 determined directly (that is without traversing the collection). This allows very efficient
48 random access to the elements of the collection.
50 A vector is a model of an STL random-access sequence. The parser only provides a reduced
51 interface, the container wrapper however completes this interface.
53 Parse_Vector makes use of a policy template argument, \a Sizer, to customize the way the
54 containers size is obtained. You will normally not instantiate Parser_Vector directly, you
55 will use one of the 'template typedefs' (which are templated structures since C++ does not
56 provide real template typedefs) provided with the policy implementations.
58 \todo Make the sizer a private base-class to profit from the empty-base-class optimization
60 \see ExampleVectorPolicy
61 \ingroup parsecollection
63 template <class ElementParser, class Sizer>
64 struct Parse_Vector : public PacketParserBase
66 Parse_Vector(data_iterator i, state_type s);
67 Parse_Vector(Sizer sizer, data_iterator i, state_type s);
68 ///< Additional sizer specific constructor
69 /**< This constructor may be used, if the sizer needs
70 additional parameters. */
72 size_type bytes() const;
75 static const size_type init_bytes = Sizer::init_bytes;
77 ///////////////////////////////////////////////////////////////////////////
78 // Container interface
80 typedef ElementParser value_type;
81 typedef detail::Parse_Array_iterator<value_type> iterator;
82 typedef iterator const_iterator;
83 typedef Parse_Vector_Container<ElementParser,Sizer> container;
85 size_type size() const;
88 iterator begin() const;
91 value_type operator[](difference_type i) const;
92 value_type front() const;
93 value_type back() const;
97 // The mutators provided here are those which don't take an iterator argument.
98 // If you need to pass an iterator it is much simpler and cleaner to use the
99 // 'container' wrapper
101 template <class Value> void push_back (Value value, size_type n=1) const;
102 void push_back_space (size_type n=1) const;
103 template <class Value> void push_front (Value value, size_type n=1) const;
104 void push_front_space (size_type n=1) const;
105 void resize (size_type n) const;
106 template <class Value> void resize (size_type n, Value value) const;
111 friend class Parse_Vector_Container<ElementParser,Sizer>;
114 namespace detail { template <class SizeParser> class Parse_VectorN_Sizer; }
116 /** \brief Vector with prefix sizing
118 This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
119 field holding the number of vector elements. The size field is considered part of the
122 // Define MyVector as a vector of 16bit unsigned elements with a directly preceding
123 // 8bit unsigned size field
124 typedef senf::Parse_VectorN<senf::Parse_UInt16, senf::Parse_UInt8>::parser MyVector;
127 \param ElementParser \e fixed-size parser for parsing the vector elements
128 \param SizeParser parser for parsing the vector size (number of elements)
131 \ingroup parsecollection
133 template <class ElementParser, class SizeParser>
136 typedef Parse_Vector< ElementParser,
137 detail::Parse_VectorN_Sizer<SizeParser> > parser;
140 /** \brief Example vector sizer. ONLY FOR EXPOSITION
142 This class shows the interface which must be implemented by a vector sizer policy. It is not
143 a vector sizer, it is only a declaration of the interface:
145 struct ExampleVectorPolicy
147 // optional typedefs used to simplify all other declarations
148 typedef PacketParserBase::size_type size_type;
149 typedef PacketParserBase::data_iterator iterator;
150 typedef PacketParserBase::state_type state_type;
153 static const size_type init_bytes = 0;
154 size_type size (iterator i, state_type s) const;
155 void size (iterator i, state_type s, size_type v) const;
156 iterator begin (iterator i, state_type s) const;
157 size_type bytes (iterator i, state_type s) const;
158 void init (iterator i, state_type s) const;
162 A sizer may if needed define additional data members.
164 struct ExampleVectorPolicy
166 typedef PacketParserBase::size_type size_type;
167 typedef PacketParserBase::data_iterator iterator;
168 typedef PacketParserBase::state_type state_type;
170 static const size_type init_bytes = 0; ///< Size of a new vector of this size
171 /**< Initial size which needs to be allocated to this type
174 size_type size (iterator i, state_type s) const; ///< Get current vector size
175 /**< Return the current number of elements in the
177 void size (iterator i, state_type s, size_type v) const; ///< Change vector size
178 /**< Set the size of the vector to \a v. */
179 iterator begin (iterator i, state_type s) const;
180 ///< Return data_iterator to first element
181 /**< The returned data_iterator must point to the beginning
182 of the first vector element. The last iterator can than
183 automatically be calculated from the fixed element size
184 and the number of vector elements. */
185 size_type bytes (iterator i, state_type s) const; ///< Size of vector parser
186 /**< Return the size of the complete vector in bytes. This
187 is not necessarily the same as \c size() * \e
188 fixed_element_bytes. */
189 void init (iterator i, state_type s) const; ///< Initialize new vector
190 /** Called to initialize a new vector after allocating
191 init_bytes number of bytes for the vector. */
194 /** \brief Parse_Vector container wrapper
196 This is the container wrapper used for vector parsers. The container wrapper will stay valid
197 after changing the collection. However the container still depends on the packet and will be
198 invalidated if the Packet is deallocated or if the packet size is changed from without the
199 container wrapper (more precisely, it is invalided if the insertion/deletion happens before
200 the vector in the packet data).
202 The vector container wrapper provides a complete STL random-access sequence interface.
206 SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
207 c.insert(c.begin(), ... );
212 template <class ElementParser, class Sizer>
213 class Parse_Vector_Container
216 ///////////////////////////////////////////////////////////////////////////
219 typedef Parse_Vector<ElementParser,Sizer> parser_type;
220 typedef PacketParserBase::data_iterator data_iterator;
221 typedef PacketParserBase::size_type size_type;
222 typedef PacketParserBase::difference_type difference_type;
223 typedef ElementParser value_type;
224 typedef detail::Parse_Array_iterator<value_type> iterator;
225 typedef iterator const_iterator;
226 typedef PacketParserBase::state_type state_type;
228 ///////////////////////////////////////////////////////////////////////////
229 ///\name Structors and default members
232 // no default constructor
234 // default destructor
235 // conversion constructors
237 Parse_Vector_Container(parser_type const & vector);
240 ///////////////////////////////////////////////////////////////////////////
245 size_type size() const;
248 iterator begin() const;
249 iterator end() const;
251 value_type operator[](difference_type i) const;
252 value_type front() const;
253 value_type back() const;
259 iterator shift(iterator pos, size_type n=1);
260 template <class Value>
261 void insert(iterator pos, Value const & t);
262 template <class Value>
263 void insert(iterator pos, size_type n, Value const & t);
265 template <class ForwardIterator>
266 void insert(iterator pos, ForwardIterator f, ForwardIterator l,
267 typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
269 template <class ForwardIterator>
270 void insert(iterator pos, ForwardIterator f, ForwardIterator l);
273 void erase(iterator pos, size_type n=1);
274 void erase(iterator f, iterator l);
277 template <class Value> void push_back (Value value, size_type n=1);
278 void push_back_space (size_type n=1);
279 template <class Value> void push_front (Value value, size_type n=1);
280 void push_front_space (size_type n=1);
281 void resize (size_type n);
282 template <class Value> void resize (size_type n, Value value);
286 ///\name Parser interface
289 parser_type parser() const;
290 data_iterator i() const;
291 state_type state() const;
292 PacketData & data() const;
294 size_type bytes() const;
302 void setSize(size_type value);
311 ///////////////////////////////hh.e////////////////////////////////////////
313 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseVec_i_)
314 #define HH_ParseVec_i_
315 //#include "ParseVec.cci"
316 #include "ParseVec.ct"
317 #include "ParseVec.cti"
324 // c-file-style: "senf"
325 // indent-tabs-mode: nil
326 // ispell-local-dictionary: "american"
327 // compile-command: "scons -u test"
328 // comment-column: 40