Socket: BUGFIX: Explicitly copy image
[senf.git] / Packets / ParseList.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief ParseList public header */
23
24 #ifndef HH_ParseList_
25 #define HH_ParseList_ 1
26
27 // Custom includes
28 #include <boost/utility.hpp>
29 #include "PacketParser.hh"
30
31 //#include "ParseList.mpp"
32 ///////////////////////////////hh.p////////////////////////////////////////
33
34 namespace senf {
35
36     namespace detail { template <class ElementParser, class IteratorPolicy> 
37                        class Parse_List_Iterator; }
38
39     template <class ListPolicy>
40     class Parse_List_Container;
41
42     /** \brief
43       */
44     template <class ListPolicy>
45     class Parse_List 
46         : public PacketParserBase,
47           private ListPolicy
48     {
49     public:
50         Parse_List(data_iterator i, state_type s);
51         Parse_List(ListPolicy policy, data_iterator i, state_type s);
52
53         size_type bytes() const;
54         void init() const;
55
56         static const size_type init_bytes = ListPolicy::init_bytes;
57
58         ///////////////////////////////////////////////////////////////////////////
59         // Container interface
60
61         typedef typename ListPolicy::element_type value_type;
62         typedef detail::Parse_List_Iterator< 
63             value_type, typename ListPolicy::iterator_policy > iterator;
64         typedef iterator const_iterator;
65         typedef typename ListPolicy::container_type container;
66
67         size_type size() const;
68         bool empty() const;
69         
70         iterator begin() const;
71         iterator end() const;
72
73         value_type front() const;
74         value_type back() const;
75         
76         template <class Value> void push_back        (Value value, size_type n=1) const;
77                                void push_back_space  (size_type n=1) const;
78         template <class Value> void push_front       (Value value, size_type n=1) const;
79                                void push_front_space (size_type n=1) const;
80                                void resize           (size_type n) const;
81         template <class Value> void resize           (size_type n, Value value) const;
82
83     private:
84         template <class Policy> friend class Parse_List_Container;
85     };
86
87     /** \brief Exmaple of a list policy. ONLY FOR EXPOSITION.
88         
89         This class shows the interface which must be implemented by a list policy. It is not a list
90         policy only a declaration of the interface:
91         \code
92         struct ExampleListPolicy
93         {
94             // optional typedefs used to simplify all other declarations
95             typedef PacketParserBase::data_iterator data_iterator;
96             typedef PacketParserBase::state_type state_type;
97             typedef PacketParserBase::size_type size_type;
98
99             // mandatory typedefs in the parser and container policy
100             typedef ElementParser element_type;
101             typedef Parse_List< ExampleListPolicy > parser_type;
102             typedef Parse_List_Container< ExampleListPolicy > container_type;
103
104             // mandatory constant in parser and container policy
105             static const size_type init_bytes = 0;
106
107             // Members needed in the parser and the container policy
108             size_type bytes  (data_iterator i, state_type s) const;
109             size_type size   (data_iterator i, state_type s) const;
110             void      init   (data_iterator i, state_type s) const;
111         
112             // Members needed only in the container policy
113             void      erase  (data_iterator i, state_type s, iterator p) const;
114             void      insert (data_iterator i, state_type s, iterator p) const;
115
116             struct iterator_policy
117             {
118                 iterator setBegin        (data_iterator i, state_type s);
119                 iterator setEnd          (data_iterator i, state_type s);
120                 void     setFromPosition (data_iterator i, state_type s, iterator p);
121                 iterator next            (data_iterator i, state_type s);
122                 iterator raw             (data_iterator i, state_type s) const;
123             };
124         };
125         \endcode
126
127         If necessary, you may use a different policy in the container_type. The ListPolicy must
128         define the elements bytes(), size() and init(), the container policy needs all theese and
129         additionally needs erase() and insert(). The container policy will also need the
130         element_type, parser_type and container_type typedefs.
131         
132         \see \ref Parse_List
133      */
134     struct ExampleListPolicy
135     {
136         typedef PacketParserBase::data_iterator iterator;
137         typedef PacketParserBase::state_type state_type;
138         typedef PacketParserBase::size_type size_type;
139
140         typedef void element_type;      ///< Type of list elements
141                                         /**< This is the parser used to parse the list elements. */
142         typedef void parser_type;       ///< List parser type
143                                         /**< parser_type is the list parser used to parse a list of
144                                              this type,
145                                              e.g. <tt>senf::Parse_List<ExampleListPolicy></tt>. */
146         typedef void container_type;    ///< Type of container wrapper
147                                         /**< This is the container wrapper of the list, e.g.
148                                              <tt>Parse_List_Container<ExampleListPolicy></tt>. The
149                                              container may however use a \e different policy, as
150                                              long as that policy is constructible from the parser
151                                              policy. */
152
153         static const size_type init_bytes = 0; ///< Size of a new list of this type
154                                         /**< Initial size which needs to be allocated to this type
155                                              of list */
156
157         size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes
158                                         /**< Return the complete size of the list in
159                                              bytes. Depending on the type of list, thie call may
160                                              need to completely traverse the list ... */
161
162         size_type size(iterator i, state_type s) const; ///< Number of elements in list
163                                         /**< Return the number of elements in the list. This
164                                              operation may be quite inefficient for some lists (the
165                                              list must be traversed to find that number. */
166
167         void init(iterator i, state_type s) const; ///< Initialize new list
168                                         /**< Called after init_size bytes have been allocated to
169                                              initialize the list. After init() is called, the list
170                                              is traversed to initialize any members (probably
171                                              none) */
172
173         void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list
174                                         /**< Delete the list element at p from the List (i,s). When
175                                              this operation is called, the element is still part of
176                                              the list. This call must update the metadata as
177                                              needed. The data will be removed after this call
178                                              returns. */
179
180         void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list
181                                         /**< This is called after an element has been inserted at p
182                                              into the List (i,s) to update the metadata. */
183
184         /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
185
186             \see \ref ExampleListPolicy \n
187                 \ref Parse_List
188          */
189         struct iterator_policy 
190         {
191             iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
192                                         /**< Initialize the policy from the given List (i,s). Set
193                                              the iterator to the beginning iterator. Return
194                                              data_iterator to the first element.
195
196                                              \warning if the list is empty, the returned iterator
197                                              \e must be the same as the one returned by setEnd. */
198
199             iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
200                                         /**< Initialize the policy from the given List (i,s). Set
201                                              the iterator to the end iterator. Return data_iterator
202                                              used to mark the end of the range. This may be a
203                                              special sentinel value (e.g. data().end()) if
204                                              needed. */
205
206             void setFromPosition(iterator i, state_type s, iterator p); 
207                                         ///< Initialize iterator from the given raw position
208                                         /**< Set the iterator to the Element at raw position p. This
209                                              operation can potentially be very inefficient if the
210                                              list needs to be traversed from the beginning until the
211                                              iterator is found. */
212             
213             iterator next(iterator i, state_type s); ///< Advance to next element
214                                         /**< given an iterator to an element, go to the next
215                                              element. */
216
217             iterator raw(iterator i, state_type s); ///< Return raw position of element
218                                         /**< Given the iterator state (i,s), return the raw iterator
219                                              to the datum. This will be i in almost all cases EXCEPT
220                                              if a special sentinel value is used as end() value. In
221                                              this case, this member must return the real position
222                                              after the last element. */
223         };
224
225         /** \brief Example of a list container policy. ONLY FOR EXPOSITION
226             
227             \see \ref ExampleListPolicy \n
228                 \ref Parse_List
229          */
230         struct container_policy
231         {
232             void init(iterator i, state_type s); ///< Initialize new container
233             void update(iterator i, state_type s); ///< Called before every container access
234         };
235     };
236
237     template <class ListPolicy>
238     class Parse_List_Container
239         : private ListPolicy
240     {
241     public:
242         ///////////////////////////////////////////////////////////////////////////
243         // Types
244
245         typedef typename ListPolicy::parser_type parser_type;
246         typedef PacketParserBase::data_iterator data_iterator;
247         typedef PacketParserBase::size_type size_type;
248         typedef PacketParserBase::difference_type difference_type;
249         typedef typename ListPolicy::element_type value_type;
250         typedef detail::Parse_List_Iterator<
251             value_type, typename ListPolicy::iterator_policy> iterator;
252         typedef iterator const_iterator;
253         typedef PacketParserBase::state_type state_type;
254         
255         ///////////////////////////////////////////////////////////////////////////
256         ///\name Structors and default members
257         ///@{
258
259         // no default constructor
260         // default copy
261         // default destructor
262         // conversion constructors
263
264         Parse_List_Container(parser_type const & list);
265         ~Parse_List_Container();
266         
267         ///@}
268         ///////////////////////////////////////////////////////////////////////////
269
270         ///\name Accessors
271         ///@{
272
273         size_type size() const;
274         bool empty() const;
275
276         iterator begin() const;
277         iterator end() const;
278
279         value_type front() const;
280         value_type back() const;
281
282         ///@}
283         ///\name Mutators
284         ///@{
285
286         // All these operations can be quite inefficient depending on the list type
287         void shift(iterator pos, size_type n=1);
288         template <class Value>
289         void insert(iterator pos, Value const & t);
290         template <class Value>
291         void insert(iterator pos, size_type n, Value const & t);
292         template <class ForwardIterator>
293         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
294                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
295
296         void erase(iterator pos, size_type n=1);
297         void erase(iterator f, iterator l);
298         void clear();
299
300         template <class Value> void push_back        (Value value, size_type n=1);
301                                void push_back_space  (size_type n=1);
302         template <class Value> void push_front       (Value value, size_type n=1);
303                                void push_front_space (size_type n=1);
304                                void resize           (size_type n);
305         template <class Value> void resize           (size_type n, Value value);
306
307         ///@}
308
309         ///\name Parser interface
310         ///@{
311
312         parser_type parser() const;
313         data_iterator i() const;
314         state_type state() const;
315         PacketData & data() const;
316
317         size_type bytes() const;
318         void init() const;
319         
320         ///@}
321
322     private:
323         state_type state_;
324         size_type i_;
325     };
326
327         
328 }
329
330 ///////////////////////////////hh.e////////////////////////////////////////
331 #endif
332 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseList_i_)
333 #define HH_ParseList_i_
334 //#include "ParseList.cci"
335 #include "ParseList.ct"
336 #include "ParseList.cti"
337 #endif
338
339 \f
340 // Local Variables:
341 // mode: c++
342 // fill-column: 100
343 // c-file-style: "senf"
344 // indent-tabs-mode: nil
345 // ispell-local-dictionary: "american"
346 // compile-command: "scons -u test"
347 // comment-column: 40
348 // End: