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 #define HH_ParseVec_ 1
27 #include <boost/iterator/iterator_facade.hpp>
28 #include <boost/utility.hpp>
29 #include <boost/range.hpp>
30 #include <boost/type_traits.hpp>
31 #include "PacketParser.hh"
32 #include "ParseArray.hh" // for Parse_Array_iterator
34 //#include "ParseVec.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
39 template <class ElementParser, class Sizer> class Parse_Vector_Container;
41 /** \brief Collection of fixed-size elements
43 A Vector is a collection of fixed-size elements of which the size of the collection can be
44 determined directly (that is without traversing the collection). This allows very efficient
45 random access to the elements of the collection.
47 A vector is a model of an STL random-access sequence. The parser only provides a reduced
48 interface, the container wrapper however completes this interface.
50 Parse_Vector makes use of a policy template argument, \a Sizer to customize the way the
51 containers size is obtained. You will normally not instantiate Parser_Vector directly, you
52 will use one of the 'template typedefs' (which are templated structures since C++ does not
53 provide real template typedefs) provided with the policy implementations.
55 \todo Make the sizer a private base-class to profit from the empty-base-class optimization
57 \see ExampleVectorPolicy
58 \ingroup parsecollection
60 template <class ElementParser, class Sizer>
61 struct Parse_Vector : public PacketParserBase
63 Parse_Vector(data_iterator i, state_type s);
64 Parse_Vector(Sizer sizer, data_iterator i, state_type s);
65 ///< Additional sizer specific constructor
66 /**< This constructor may be used, if the sizer needs
67 additional parameters. */
69 size_type bytes() const;
72 static const size_type init_bytes = Sizer::init_bytes;
74 ///////////////////////////////////////////////////////////////////////////
75 // Container interface
77 typedef ElementParser value_type;
78 typedef detail::Parse_Array_iterator<value_type> iterator;
79 typedef iterator const_iterator;
80 typedef Parse_Vector_Container<ElementParser,Sizer> container;
82 size_type size() const;
85 iterator begin() const;
88 value_type operator[](difference_type i) const;
89 value_type front() const;
90 value_type back() const;
94 // The mutators provided here are those which don't take an iterator argument.
95 // If you need to pass an iterator it is much simpler and cleaner to use the
96 // 'container' wrapper
98 template <class Value> void push_back (Value value, size_type n=1) const;
99 void push_back_space (size_type n=1) const;
100 template <class Value> void push_front (Value value, size_type n=1) const;
101 void push_front_space (size_type n=1) const;
102 void resize (size_type n) const;
103 template <class Value> void resize (size_type n, Value value) const;
108 friend class Parse_Vector_Container<ElementParser,Sizer>;
111 namespace detail { template <class SizeParser> class Parse_VectorN_Sizer; }
113 /** \brief Vector with prefix sizing
115 This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
116 field holding the number of vector elements. The size field is considered part of the
119 // Define MyVector as a vector of 16bit unsigned elements with a directly preceding
120 // 8bit unsigned size field
121 typedef senf::Parse_VectorN<senf::Parse_UInt16, senf::Parse_UInt8>::parser MyVector;
124 \param ElementParser \e fixed-size parser for parsing the vector elements
125 \param SizeParser parser for parsing the vector size (number of elements)
128 \ingroup parsecollection
130 template <class ElementParser, class SizeParser>
133 typedef Parse_Vector< ElementParser,
134 detail::Parse_VectorN_Sizer<SizeParser> > parser;
137 /** \brief Example vector sizer. ONLY FOR EXPOSITION
139 This class shows the interface which must be implemented by a vector sizer policy. It is not
140 a vector sizer, it is only a declaration of the interface:
142 struct ExampleVectorPolicy
144 // optional typedefs used to simplify all other declarations
145 typedef PacketParserBase::size_type size_type;
146 typedef PacketParserBase::data_iterator iterator;
147 typedef PacketParserBase::state_type state_type;
150 static const size_type init_bytes = 0;
151 size_type size (iterator i, state_type s) const;
152 void size (iterator i, state_type s, size_type v) const;
153 iterator begin (iterator i, state_type s) const;
154 size_type bytes (iterator i, state_type s) const;
155 void init (iterator i, state_type s) const;
159 A sizer may if needed define additional data members.
161 struct ExampleVectorPolicy
163 typedef PacketParserBase::size_type size_type;
164 typedef PacketParserBase::data_iterator iterator;
165 typedef PacketParserBase::state_type state_type;
167 static const size_type init_bytes = 0; ///< Size of a new vector of this size
168 /**< Initial size which needs to be allocated to this type
171 size_type size (iterator i, state_type s) const; ///< Get current vector size
172 /**< Return the current number of elements in the
174 void size (iterator i, state_type s, size_type v) const; ///< Change vector size
175 /**< Set the size of the vector to \a v. */
176 iterator begin (iterator i, state_type s) const;
177 ///< Return data_iterator to first element
178 /**< The returned data_iterator must point to the beginning
179 of the first vector element. The last iterator can than
180 automatically be calculated from the fixed element size
181 and the number of vector elements. */
182 size_type bytes (iterator i, state_type s) const; ///< Size of vector parser
183 /**< Return the size of the complete vector in bytes. This
184 is not necessarily the same as \c size() * \e
185 fixed_element_bytes. */
186 void init (iterator i, state_type s) const; ///< Initialize new vector
187 /** Called to initialize a new vector after allocating
188 init_bytes number of bytes for the vector. */
191 /** \brief Parse_Vector container wrapper
193 This is the container wrapper used for vector parsers. The container wrapper will stay valid
194 after changing the collection. However the container still depends on the packet and will be
195 invalidated if the Packet is deallocated or if the packet size is changed from without the
196 container wrapper (more precisely, it is invalided if the insertion/deletion happens before
197 the vector in the packet data).
199 The vector container wrapper provides a complete STL random-access sequence interface.
203 SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
204 c.insert(c.begin(), ... );
207 template <class ElementParser, class Sizer>
208 class Parse_Vector_Container
211 ///////////////////////////////////////////////////////////////////////////
214 typedef Parse_Vector<ElementParser,Sizer> parser_type;
215 typedef PacketParserBase::data_iterator data_iterator;
216 typedef PacketParserBase::size_type size_type;
217 typedef PacketParserBase::difference_type difference_type;
218 typedef ElementParser value_type;
219 typedef detail::Parse_Array_iterator<value_type> iterator;
220 typedef iterator const_iterator;
221 typedef PacketParserBase::state_type state_type;
223 ///////////////////////////////////////////////////////////////////////////
224 ///\name Structors and default members
227 // no default constructor
229 // default destructor
230 // conversion constructors
232 Parse_Vector_Container(parser_type const & vector);
235 ///////////////////////////////////////////////////////////////////////////
240 size_type size() const;
243 iterator begin() const;
244 iterator end() const;
246 value_type operator[](difference_type i) const;
247 value_type front() const;
248 value_type back() const;
254 iterator shift(iterator pos, size_type n=1);
255 template <class Value>
256 void insert(iterator pos, Value const & t);
257 template <class Value>
258 void insert(iterator pos, size_type n, Value const & t);
259 template <class ForwardIterator>
260 void insert(iterator pos, ForwardIterator f, ForwardIterator l,
261 typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
263 void erase(iterator pos, size_type n=1);
264 void erase(iterator f, iterator l);
267 template <class Value> void push_back (Value value, size_type n=1);
268 void push_back_space (size_type n=1);
269 template <class Value> void push_front (Value value, size_type n=1);
270 void push_front_space (size_type n=1);
271 void resize (size_type n);
272 template <class Value> void resize (size_type n, Value value);
276 ///\name Parser interface
279 parser_type parser() const;
280 data_iterator i() const;
281 state_type state() const;
282 PacketData & data() const;
284 size_type bytes() const;
292 void setSize(size_type value);
301 ///////////////////////////////hh.e////////////////////////////////////////
303 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseVec_i_)
304 #define HH_ParseVec_i_
305 //#include "ParseVec.cci"
306 #include "ParseVec.ct"
307 #include "ParseVec.cti"
314 // c-file-style: "senf"
315 // indent-tabs-mode: nil
316 // ispell-local-dictionary: "american"
317 // compile-command: "scons -u test"
318 // comment-column: 40