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