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