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