removed some useless spaces; not very important, I know :)
[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_VectorParser_
27 #define HH_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
37 //#include "VectorParser.mpp"
38 #include "VectorParser.ih"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     template <class ElementParser, class Sizer> 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 Sizer, to customize the way the
55         containers size is obtained. You will normally not instantiate Parser_Vector directly, you
56         will use one of the 'template typedefs' (which are templated structures since C++ does not
57         provide real template typedefs) provided with the policy implementations.
58         
59         \todo Make the sizer a private base-class to profit from the empty-base-class optimization
60
61         \see ExampleVectorPolicy
62         \ingroup parsecollection
63      */
64     template <class ElementParser, class Sizer>
65     struct VectorParser : public PacketParserBase
66     {
67         VectorParser(data_iterator i, state_type s);
68         VectorParser(Sizer sizer, data_iterator i, state_type s);
69                                         ///< Additional sizer specific constructor
70                                         /**< This constructor may be used, if the sizer needs
71                                              additional parameters. */
72
73         size_type bytes() const;
74         void init() const;
75
76         static const size_type init_bytes = Sizer::init_bytes;
77
78         ///////////////////////////////////////////////////////////////////////////
79         // Container interface
80
81         typedef ElementParser value_type;
82         typedef detail::ArrayParser_iterator<value_type> iterator;
83         typedef iterator const_iterator;
84         typedef VectorParser_Container<ElementParser,Sizer> container;
85
86         size_type size() const;
87         bool empty() const;
88
89         iterator begin() const;
90         iterator end() const;
91
92         value_type operator[](difference_type i) const;
93         value_type front() const;
94         value_type back() const;
95
96         // Mutators
97         
98         // The mutators provided here are those which don't take an iterator argument.
99         // If you need to pass an iterator it is much simpler and cleaner to use the
100         // 'container' wrapper
101                    
102         template <class Value> void push_back        (Value value, size_type n=1) const;
103                                void push_back_space  (size_type n=1) const;
104         template <class Value> void push_front       (Value value, size_type n=1) const;
105                                void push_front_space (size_type n=1) const;
106                                void resize           (size_type n) const;
107         template <class Value> void resize           (size_type n, Value value) const;
108
109      private:
110         Sizer sizer_;
111
112         friend class VectorParser_Container<ElementParser,Sizer>;
113     };
114
115     /** \brief Vector with prefix sizing
116         
117         This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
118         field holding the number of vector elements. The size field is considered part of the
119         vector.
120         \code
121         // Define MyVector as a vector of 16bit unsigned elements with a directly preceding
122         // 8bit unsigned size field
123         typedef senf::VectorNParser<senf::UInt16Parser, senf::UInt8Parser>::parser MyVector;
124         \endcode
125
126         \param ElementParser \e fixed-size parser for parsing the vector elements
127         \param SizeParser parser for parsing the vector size (number of elements)
128
129         \see VectorParser
130         \ingroup parsecollection
131      */
132     template <class ElementParser, class SizeParser, unsigned Distance>
133     struct VectorNParser
134     {
135         typedef VectorParser< ElementParser,
136                               detail::VectorNParser_Sizer<SizeParser, Distance> > parser;
137     };
138
139     /** \brief Define VectorNParser field
140         
141         This macro is a special helper to define a senf::VectorNParser type field, a vector of
142         elements of type \a elt_type (a parser) which size is given by the \a size field.
143
144         \code
145         // The size field should be declared private (size is accessible via the vector)
146         SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
147         // Define the vector, here it has 32bit unsigned integer elements
148         SENF_PARSER_VEC_N         ( vec,       _vec_size, senf::UInt32Parser );
149         \endcode
150         
151         \param[in] name field name
152         \param[in] size name of field giving the vector size
153         \param[in] elt_type vector element type
154         \hideinitializer
155         \ingroup packetparsermacros
156      */
157 #   define SENF_PARSER_VEC_N(name, size, elt_type)                                                \
158         SENF_PARSER_VEC_N_I(SENF_PARSER_FIELD, name, size, elt_type)
159
160     /** \brief Define VectorNParser field
161
162         \see \ref SENF_PARSER_VEC_N()
163         \hideinitializer
164         \ingroup packetparsermacros
165      */
166 #   define SENF_PARSER_PRIVATE_VEC_N(name, size, elt_type)                                        \
167         SENF_PARSER_VEC_N_I(SENF_PARSER_PRIVATE_FIELD, name, size, elt_type)
168
169     /** \brief VectorParser container wrapper
170
171         This is the container wrapper used for vector parsers. The container wrapper will stay valid
172         after changing the collection. However the container still depends on the packet and will be
173         invalidated if the Packet is deallocated or if the packet size is changed from without the
174         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
175         the vector in the packet data).
176
177         The vector container wrapper provides a complete STL random-access sequence interface.
178         
179         \code
180         SomePacket p (...);
181         SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
182         c.insert(c.begin(), ... );
183         \endcode
184
185         \see VectorParser
186       */
187     template <class ElementParser, class Sizer>
188     class VectorParser_Container
189     {
190     public:
191         ///////////////////////////////////////////////////////////////////////////
192         // Types
193
194         typedef VectorParser<ElementParser,Sizer> parser_type;
195         typedef PacketParserBase::data_iterator data_iterator;
196         typedef PacketParserBase::size_type size_type;
197         typedef PacketParserBase::difference_type difference_type;
198         typedef ElementParser value_type;
199         typedef detail::ArrayParser_iterator<value_type> iterator;
200         typedef iterator const_iterator;
201         typedef PacketParserBase::state_type state_type;
202
203         ///////////////////////////////////////////////////////////////////////////
204         ///\name Structors and default members
205         ///@{
206
207         // no default constructor
208         // default copy
209         // default destructor
210         // conversion constructors
211
212         VectorParser_Container(parser_type const & vector);
213
214         ///@}
215         ///////////////////////////////////////////////////////////////////////////
216
217         ///\name Accessors
218         ///@{
219
220         size_type size() const;
221         bool empty() const;
222
223         iterator begin() const;
224         iterator end() const;
225
226         value_type operator[](difference_type i) const;
227         value_type front() const;
228         value_type back() const;
229
230         ///@}
231         ///\name Mutators
232         ///@{
233
234         iterator shift(iterator pos, size_type n=1);
235         template <class Value>
236         void insert(iterator pos, Value const & t);
237         template <class Value>
238         void insert(iterator pos, size_type n, Value const & t);
239 #       ifndef DOXYGEN
240         template <class ForwardIterator>
241         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
242                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
243 #       else
244         template <class ForwardIterator>
245         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
246 #       endif
247
248         void erase(iterator pos, size_type n=1);
249         void erase(iterator f, iterator l);
250         void clear();
251
252         template <class Value> void push_back        (Value value, size_type n=1);
253                                void push_back_space  (size_type n=1);
254         template <class Value> void push_front       (Value value, size_type n=1);
255                                void push_front_space (size_type n=1);
256                                void resize           (size_type n);
257         template <class Value> void resize           (size_type n, Value value);
258
259         ///@}
260
261         ///\name Parser interface
262         ///@{
263
264         parser_type parser() const;
265         data_iterator i() const;
266         state_type state() const;
267         PacketData & data() const;
268
269         size_type bytes() const;
270         void init() const;
271         
272         ///@}
273
274     protected:
275
276     private:
277         void setSize(size_type value);
278
279         Sizer sizer_;
280         state_type state_;
281         size_type i_;
282     };
283
284 }
285
286 ///////////////////////////////hh.e////////////////////////////////////////
287 #endif
288 #if !defined(HH_Packets__decls_) && !defined(HH_VectorParser_i_)
289 #define HH_VectorParser_i_
290 //#include "VectorParser.cci"
291 #include "VectorParser.ct"
292 #include "VectorParser.cti"
293 #endif
294
295 \f
296 // Local Variables:
297 // mode: c++
298 // fill-column: 100
299 // c-file-style: "senf"
300 // indent-tabs-mode: nil
301 // ispell-local-dictionary: "american"
302 // compile-command: "scons -u test"
303 // comment-column: 40
304 // End: