Socket: BUGFIX: Explicitly copy image
[senf.git] / Packets / ParseVec.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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 #ifndef HH_ParseVec_
24 #define HH_ParseVec_ 1
25
26 // Custom includes
27 #include <boost/iterator/iterator_facade.hpp>
28 #include <boost/utility.hpp>
29 #include <boost/range.hpp>
30 #include <boost/type_traits.hpp>
31 #include "PacketParser.hh"
32 #include "ParseArray.hh" // for Parse_Array_iterator
33
34 //#include "ParseVec.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
36
37 namespace senf {
38
39     template <class ElementParser, class Sizer> class Parse_Vector_Container;
40
41     /** \brief Collection of fixed-size elements
42
43         A Vector is a collection of fixed-size elements of which the size of the collection can be
44         determined directly (that is without traversing the collection). This allows very efficient
45         random access to the elements of the collection.
46         
47         A vector is a model of an STL random-access sequence. The parser only provides a reduced
48         interface, the container wrapper however completes this interface.
49
50         Parse_Vector makes use of a policy template argument, \a Sizer to customize the way the
51         containers size is obtained. You will normally not instantiate Parser_Vector directly, you
52         will use one of the 'template typedefs' (which are templated structures since C++ does not
53         provide real template typedefs) provided with the policy implementations.
54         
55         \todo Make the sizer a private base-class to profit from the empty-base-class optimization
56
57         \see ExampleVectorPolicy
58         \ingroup parsecollection
59      */
60     template <class ElementParser, class Sizer>
61     struct Parse_Vector : public PacketParserBase
62     {
63         Parse_Vector(data_iterator i, state_type s);
64         Parse_Vector(Sizer sizer, data_iterator i, state_type s);
65                                         ///< Additional sizer specific constructor
66                                         /**< This constructor may be used, if the sizer needs
67                                              additional parameters. */
68
69         size_type bytes() const;
70         void init() const;
71
72         static const size_type init_bytes = Sizer::init_bytes;
73
74         ///////////////////////////////////////////////////////////////////////////
75         // Container interface
76
77         typedef ElementParser value_type;
78         typedef detail::Parse_Array_iterator<value_type> iterator;
79         typedef iterator const_iterator;
80         typedef Parse_Vector_Container<ElementParser,Sizer> container;
81
82         size_type size() const;
83         bool empty() const;
84
85         iterator begin() const;
86         iterator end() const;
87
88         value_type operator[](difference_type i) const;
89         value_type front() const;
90         value_type back() const;
91
92         // Mutators
93         
94         // The mutators provided here are those which don't take an iterator argument.
95         // If you need to pass an iterator it is much simpler and cleaner to use the
96         // 'container' wrapper
97                    
98         template <class Value> void push_back        (Value value, size_type n=1) const;
99                                void push_back_space  (size_type n=1) const;
100         template <class Value> void push_front       (Value value, size_type n=1) const;
101                                void push_front_space (size_type n=1) const;
102                                void resize           (size_type n) const;
103         template <class Value> void resize           (size_type n, Value value) const;
104
105      private:
106         Sizer sizer_;
107
108         friend class Parse_Vector_Container<ElementParser,Sizer>;
109     };
110
111     namespace detail { template <class SizeParser> class Parse_VectorN_Sizer; }
112
113     /** \brief Vector with prefix sizing
114         
115         This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
116         field holding the number of vector elements. The size field is considered part of the
117         vector.
118         \code
119         // Define MyVector as a vector of 16bit unsigned elements with a directly preceding
120         // 8bit unsigned size field
121         typedef senf::Parse_VectorN<senf::Parse_UInt16, senf::Parse_UInt8>::parser MyVector;
122         \endcode
123
124         \param ElementParser \e fixed-size parser for parsing the vector elements
125         \param SizeParser parser for parsing the vector size (number of elements)
126
127         \see Parse_Vector
128         \ingroup parsecollection
129      */
130     template <class ElementParser, class SizeParser>
131     struct Parse_VectorN
132     {
133         typedef Parse_Vector< ElementParser,
134                               detail::Parse_VectorN_Sizer<SizeParser> > parser;
135     };
136
137     /** \brief Example vector sizer. ONLY FOR EXPOSITION
138
139         This class shows the interface which must be implemented by a vector sizer policy. It is not
140         a vector sizer, it is only a declaration of the interface:
141         \code
142         struct ExampleVectorPolicy
143         {
144             // optional typedefs used to simplify all other declarations
145             typedef PacketParserBase::size_type size_type;
146             typedef PacketParserBase::data_iterator iterator;
147             typedef PacketParserBase::state_type state_type;
148
149             // mandatory members
150             static const size_type init_bytes = 0;
151             size_type  size  (iterator i, state_type s) const;
152             void       size  (iterator i, state_type s, size_type v) const;
153             iterator   begin (iterator i, state_type s) const;
154             size_type  bytes (iterator i, state_type s) const;
155             void       init  (iterator i, state_type s) const;
156         };
157         \endcode
158
159         A sizer may if needed define additional data members.
160      */
161     struct ExampleVectorPolicy
162     {
163         typedef PacketParserBase::size_type size_type;
164         typedef PacketParserBase::data_iterator iterator;
165         typedef PacketParserBase::state_type state_type;
166
167         static const size_type init_bytes = 0; ///< Size of a new vector of this size
168                                         /**< Initial size which needs to be allocated to this type
169                                              of list */
170
171         size_type  size  (iterator i, state_type s) const; ///< Get current vector size
172                                         /**< Return the current number of elements in the 
173                                              vector. */
174         void       size  (iterator i, state_type s, size_type v) const; ///< Change vector size
175                                         /**< Set the size of the vector to \a v. */
176         iterator   begin (iterator i, state_type s) const; 
177                                         ///< Return data_iterator to first element
178                                         /**< The returned data_iterator must point to the beginning
179                                              of the first vector element. The last iterator can than
180                                              automatically be calculated from the fixed element size
181                                              and the number of vector elements. */
182         size_type  bytes (iterator i, state_type s) const; ///< Size of vector parser
183                                         /**< Return the size of the complete vector in bytes. This
184                                              is not necessarily the same as \c size() * \e
185                                              fixed_element_bytes. */
186         void       init  (iterator i, state_type s) const; ///< Initialize new vector
187                                         /** Called to initialize a new vector after allocating
188                                             init_bytes number of bytes for the vector. */
189     };
190
191     /** \brief Parse_Vector container wrapper
192
193         This is the container wrapper used for vector parsers. The container wrapper will stay valid
194         after changing the collection. However the container still depends on the packet and will be
195         invalidated if the Packet is deallocated or if the packet size is changed from without the
196         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
197         the vector in the packet data).
198
199         The vector container wrapper provides a complete STL random-access sequence interface.
200         
201         \code
202         SomePacket p (...);
203         SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
204         c.insert(c.begin(), ... );
205         \endcode
206       */
207     template <class ElementParser, class Sizer>
208     class Parse_Vector_Container
209     {
210     public:
211         ///////////////////////////////////////////////////////////////////////////
212         // Types
213
214         typedef Parse_Vector<ElementParser,Sizer> parser_type;
215         typedef PacketParserBase::data_iterator data_iterator;
216         typedef PacketParserBase::size_type size_type;
217         typedef PacketParserBase::difference_type difference_type;
218         typedef ElementParser value_type;
219         typedef detail::Parse_Array_iterator<value_type> iterator;
220         typedef iterator const_iterator;
221         typedef PacketParserBase::state_type state_type;
222
223         ///////////////////////////////////////////////////////////////////////////
224         ///\name Structors and default members
225         ///@{
226
227         // no default constructor
228         // default copy
229         // default destructor
230         // conversion constructors
231
232         Parse_Vector_Container(parser_type const & vector);
233
234         ///@}
235         ///////////////////////////////////////////////////////////////////////////
236
237         ///\name Accessors
238         ///@{
239
240         size_type size() const;
241         bool empty() const;
242
243         iterator begin() const;
244         iterator end() const;
245
246         value_type operator[](difference_type i) const;
247         value_type front() const;
248         value_type back() const;
249
250         ///@}
251         ///\name Mutators
252         ///@{
253
254         iterator shift(iterator pos, size_type n=1);
255         template <class Value>
256         void insert(iterator pos, Value const & t);
257         template <class Value>
258         void insert(iterator pos, size_type n, Value const & t);
259         template <class ForwardIterator>
260         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
261                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
262
263         void erase(iterator pos, size_type n=1);
264         void erase(iterator f, iterator l);
265         void clear();
266
267         template <class Value> void push_back        (Value value, size_type n=1);
268                                void push_back_space  (size_type n=1);
269         template <class Value> void push_front       (Value value, size_type n=1);
270                                void push_front_space (size_type n=1);
271                                void resize           (size_type n);
272         template <class Value> void resize           (size_type n, Value value);
273
274         ///@}
275
276         ///\name Parser interface
277         ///@{
278
279         parser_type parser() const;
280         data_iterator i() const;
281         state_type state() const;
282         PacketData & data() const;
283
284         size_type bytes() const;
285         void init() const;
286         
287         ///@}
288
289     protected:
290
291     private:
292         void setSize(size_type value);
293
294         Sizer sizer_;
295         state_type state_;
296         size_type i_;
297     };
298
299 }
300
301 ///////////////////////////////hh.e////////////////////////////////////////
302 #endif
303 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseVec_i_)
304 #define HH_ParseVec_i_
305 //#include "ParseVec.cci"
306 #include "ParseVec.ct"
307 #include "ParseVec.cti"
308 #endif
309
310 \f
311 // Local Variables:
312 // mode: c++
313 // fill-column: 100
314 // c-file-style: "senf"
315 // indent-tabs-mode: nil
316 // ispell-local-dictionary: "american"
317 // compile-command: "scons -u test"
318 // comment-column: 40
319 // End: