623e18f567fec095468c36d8d3bfd46e9a200048
[senf.git] / Packets / VectorParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief VectorParser public header */
25
26 #ifndef HH_SENF_Packets_VectorParser_
27 #define HH_SENF_Packets_VectorParser_ 1
28
29 // Custom includes
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 "ArrayParser.hh" // for ArrayParser_iterator
36 #include "AuxParser.hh" // for the AuxPolicies
37
38 //#include "VectorParser.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     template <class ElementParser, class AuxPolicy> class VectorParser_Container;
44
45     /** \brief Collection of fixed-size elements
46
47         A Vector is a collection of fixed-size elements of which the size of the collection can be
48         determined directly (that is without traversing the collection). This allows very efficient
49         random access to the elements of the collection.
50         
51         A vector is a model of an STL random-access sequence. The parser only provides a reduced
52         interface, the container wrapper however completes this interface.
53
54         VectorParser makes use of a policy template argument, \a AuxPolicy, to customize the way the
55         containers size is obtained. You will normally not instantiate VectorParser directly, you
56         will use the \ref SENF_PARSER_VECTOR() helper macro.
57         
58         \ingroup parsecollection
59      */
60     template <class ElementParser, class AuxPolicy>
61     struct VectorParser 
62         : public PacketParserBase, 
63           private AuxPolicy
64     {
65         VectorParser(data_iterator i, state_type s);
66         VectorParser(AuxPolicy policy, data_iterator i, state_type s);
67                                         ///< Additional sizer specific constructor
68                                         /**< This constructor may be used, if the sizer needs
69                                              additional parameters. */
70
71         size_type bytes() const;
72         void init() const;
73
74         static const size_type init_bytes = AuxPolicy::aux_bytes;
75
76         ///////////////////////////////////////////////////////////////////////////
77         // Container interface
78
79         typedef ElementParser value_type;
80         typedef detail::ArrayParser_iterator<value_type> iterator;
81         typedef iterator const_iterator;
82         typedef VectorParser_Container<ElementParser,AuxPolicy> container;
83
84         size_type size() const;
85         bool empty() const;
86
87         iterator begin() const;
88         iterator end() const;
89
90         value_type operator[](difference_type i) const;
91         value_type front() const;
92         value_type back() const;
93
94         // Mutators
95         
96         // The mutators provided here are those which don't take an iterator argument.
97         // If you need to pass an iterator it is much simpler and cleaner to use the
98         // 'container' wrapper
99                    
100         template <class Value> void push_back        (Value value, size_type n=1) const;
101                                void push_back_space  (size_type n=1) const;
102         template <class Value> void push_front       (Value value, size_type n=1) const;
103                                void push_front_space (size_type n=1) const;
104                                void resize           (size_type n) const;
105         template <class Value> void resize           (size_type n, Value value) const;
106
107      private:
108
109         friend class VectorParser_Container<ElementParser,AuxPolicy>;
110     };
111
112     /** \brief VectorParser container wrapper
113
114         This is the container wrapper used for vector parsers. The container wrapper will stay valid
115         after changing the collection. However the container still depends on the packet and will be
116         invalidated if the Packet is deallocated or if the packet size is changed from without the
117         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
118         the vector in the packet data).
119
120         The vector container wrapper provides a complete STL random-access sequence interface.
121         
122         \code
123         SomePacket p (...);
124         SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
125         c.insert(c.begin(), ... );
126         \endcode
127
128         \see VectorParser
129       */
130     template <class ElementParser, class AuxPolicy>
131     class VectorParser_Container
132         : private AuxPolicy::WrapperPolicy
133     {
134     public:
135         ///////////////////////////////////////////////////////////////////////////
136         // Types
137
138         typedef VectorParser<ElementParser,AuxPolicy> parser_type;
139         typedef PacketParserBase::data_iterator data_iterator;
140         typedef PacketParserBase::size_type size_type;
141         typedef PacketParserBase::difference_type difference_type;
142         typedef ElementParser value_type;
143         typedef detail::ArrayParser_iterator<value_type> iterator;
144         typedef iterator const_iterator;
145         typedef PacketParserBase::state_type state_type;
146
147         ///////////////////////////////////////////////////////////////////////////
148         ///\name Structors and default members
149         ///@{
150
151         // no default constructor
152         // default copy
153         // default destructor
154         // conversion constructors
155
156         VectorParser_Container(parser_type const & vector);
157
158         ///@}
159         ///////////////////////////////////////////////////////////////////////////
160
161         ///\name Accessors
162         ///@{
163
164         size_type size() const;
165         bool empty() const;
166
167         iterator begin() const;
168         iterator end() const;
169
170         value_type operator[](difference_type i) const;
171         value_type front() const;
172         value_type back() const;
173
174         ///@}
175         ///\name Mutators
176         ///@{
177
178         iterator shift(iterator pos, size_type n=1);
179         template <class Value>
180         void insert(iterator pos, Value const & t);
181         template <class Value>
182         void insert(iterator pos, size_type n, Value const & t);
183 #       ifndef DOXYGEN
184         template <class ForwardIterator>
185         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
186                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
187 #       else
188         template <class ForwardIterator>
189         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
190 #       endif
191
192         void erase(iterator pos, size_type n=1);
193         void erase(iterator f, iterator l);
194         void clear();
195
196         template <class Value> void push_back        (Value value, size_type n=1);
197                                void push_back_space  (size_type n=1);
198         template <class Value> void push_front       (Value value, size_type n=1);
199                                void push_front_space (size_type n=1);
200                                void resize           (size_type n);
201         template <class Value> void resize           (size_type n, Value value);
202
203         ///@}
204
205         ///\name Parser interface
206         ///@{
207
208         parser_type parser() const;
209         data_iterator i() const;
210         state_type state() const;
211         PacketData & data() const;
212
213         size_type bytes() const;
214         void init() const;
215         
216         ///@}
217
218     protected:
219
220     private:
221         void setSize(size_type value);
222
223         state_type state_;
224         size_type i_;
225     };
226
227     /** \brief Define VectorParser field
228         
229         This macro is a special helper to define a senf::VectorParser type field, a vector of
230         elements of type \a elt_type (a parser) which size is given by the \a size field.
231
232         \code
233         // The size field should be declared private (size is accessible via the vector)
234         SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
235         // Define the vector, here it has 32bit unsigned integer elements
236         SENF_PARSER_VECTOR        ( vec,       vec_size_, senf::UInt32Parser );
237         \endcode
238
239         \warning Realize, that the \a size field is controlled by the vector parser. This field
240             should therefore be declared either read-only or private and must be changed only via
241             the vector parser.
242
243         Further additional tags are supported which modify the way, the \a size field is
244         interpreted:
245
246         <table class="senf fixedcolumn">
247         <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the vector in bytes not the
248         number of contained elements</td></tr>
249         
250         <tr><td>\c packetSize()</td><td>Use the size of the packet to get the vector size. The
251         vector will occupy all space up to the end of the packet.</td></tr>
252
253         <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
254         size value, the value is not used directly</td>
255         </table>
256
257         The optional \a transform is a class with the following layout
258
259         \code
260         struct MyTransform
261         {
262             typedef ... value_type;
263             static value_type get(other_type v);
264             static other_type set(value_type v);
265         };
266         \endcode \c other_type is the \a size ::\c value_type where as the \c value_type typedef is
267         the arbitrary return type of the transform.
268
269         The tags are applied to the \a size parameter:
270         \code
271         SENF_PARSER_VECTOR ( vec, transform(MyTransform, vec_size_), senf::UInt32Parser );
272         SENF_PARSER_VECTOR ( vec, packetSize(), senf::UInt32Parser );
273         \endcode
274         
275         \param[in] name field name
276         \param[in] size name of field giving the vector size
277         \param[in] elt_type vector element type
278
279         \hideinitializer
280         \ingroup packetparsermacros
281      */
282 #   define SENF_PARSER_VECTOR(name, size, elt_type) \
283         SENF_PARSER_VECTOR_I(public, name, size, elt_type)
284
285     /** \brief Define private VectorParser field
286
287         \see \ref SENF_PARSER_VECTOR()
288
289         \hideinitializer
290         \ingroup packetparsermacros
291      */
292 #   define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
293         SENF_PARSER_VECTOR_I(private, name, size, elt_type)
294 }
295
296 ///////////////////////////////hh.e////////////////////////////////////////
297 #endif
298 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_VectorParser_i_)
299 #define HH_SENF_Packets_VectorParser_i_
300 //#include "VectorParser.cci"
301 #include "VectorParser.ct"
302 #include "VectorParser.cti"
303 #endif
304
305 \f
306 // Local Variables:
307 // mode: c++
308 // fill-column: 100
309 // c-file-style: "senf"
310 // indent-tabs-mode: nil
311 // ispell-local-dictionary: "american"
312 // compile-command: "scons -u test"
313 // comment-column: 40
314 // End: