945f72e8098782e78f3c831beca8691558f80574
[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         tempalte <class ElementParser>
93         struct ExampleListPolicy
94         {
95             // optional typedefs used to simplify all other declarations
96             typedef PacketParserBase::data_iterator data_iterator;
97             typedef PacketParserBase::state_type state_type;
98             typedef PacketParserBase::size_type size_type;
99
100             // mandatory typedefs in the parser and container policy
101             typedef ElementParser element_type;
102             typedef Parse_List< ExampleListPolicy > parser_type;
103             typedef Parse_List_Container< ExampleListPolicy > container_type;
104
105             // mandatory constant in parser and container policy
106             static const size_type init_bytes = 0;
107
108             // Members needed in the parser and the container policy
109             size_type bytes  (data_iterator i, state_type s) const;
110             size_type size   (data_iterator i, state_type s) const;
111             void      init   (data_iterator i, state_type s) const;
112         
113             // Members needed only in the container policy
114             void      erase  (data_iterator i, state_type s, iterator p) const;
115             void      insert (data_iterator i, state_type s, iterator p) const;
116
117             struct iterator_policy
118             {
119                 iterator setBegin        (data_iterator i, state_type s);
120                 iterator setEnd          (data_iterator i, state_type s);
121                 void     setFromPosition (data_iterator i, state_type s, iterator p);
122                 iterator next            (data_iterator i, state_type s);
123                 iterator raw             (data_iterator i, state_type s) const;
124             };
125         };
126         \endcode
127
128         If necessary, you may use a different policy in the container_type. The ListPolicy must
129         define the elements bytes(), size() and init(), the container policy needs all theese and
130         additionally needs erase() and insert(). The container policy will also need the
131         element_type, parser_type and container_type typedefs.
132         
133         \see \ref Parse_List
134      */
135     struct ExampleListPolicy
136     {
137         typedef PacketParserBase::data_iterator iterator;
138         typedef PacketParserBase::state_type state_type;
139         typedef PacketParserBase::size_type size_type;
140
141         static const size_type init_bytes = 0; ///< Size of a new list of this type
142                                         /**< Initial size which needs to be allocated to this type
143                                              of list */
144
145         size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes
146                                         /**< Return the complete size of the list in
147                                              bytes. Depending on the type of list, thie call may
148                                              need to completely traverse the list ... */
149
150         size_type size(iterator i, state_type s) const; ///< Number of elements in list
151                                         /**< Return the number of elements in the list. This
152                                              operation may be quite inefficient for some lists (the
153                                              list must be traversed to find that number. */
154
155         void init(iterator i, state_type s) const; ///< Initialize new list
156                                         /**< Called after init_size bytes have been allocated to
157                                              initialize the list. After init() is called, the list
158                                              is traversed to initialize any members (probably
159                                              none) */
160
161         void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list
162                                         /**< Delete the list element at p from the List (i,s). When
163                                              this operation is called, the element is still part of
164                                              the list. This call must update the metadata as
165                                              needed. The data will be removed after this call
166                                              returns. */
167
168         void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list
169                                         /**< This is called after an element has been inserted at p
170                                              into the List (i,s) to update the metadata. */
171
172         /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
173
174             \see \ref ExampleListPolicy \n
175                 \ref Parse_List
176          */
177         struct iterator_policy 
178         {
179             iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
180                                         /**< Initialize the policy from the given List (i,s). Set
181                                              the iterator to the beginning iterator. Return
182                                              data_iterator to the first element.
183
184                                              \warning if the list is empty, the returned iterator
185                                              \e must be the same as the one returned by setEnd. */
186
187             iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
188                                         /**< Initialize the policy from the given List (i,s). Set
189                                              the iterator to the end iterator. Return data_iterator
190                                              used to mark the end of the range. This may be a
191                                              special sentinel value (e.g. data().end()) if
192                                              needed. */
193
194             void setFromPosition(iterator i, state_type s, iterator p); 
195                                         ///< Initialize iterator from the given raw position
196                                         /**< Set the iterator to the Element at raw position p. This
197                                              operation can potentially be very inefficient if the
198                                              list needs to be traversed from the beginning until the
199                                              iterator is found. */
200             
201             iterator next(iterator i, state_type s); ///< Advance to next element
202                                         /**< given an iterator to an element, go to the next
203                                              element. */
204
205             iterator raw(iterator i, state_type s); ///< Return raw position of element
206                                         /**< Given the iterator state (i,s), return the raw iterator
207                                              to the datum. This will be i in almost all cases EXCEPT
208                                              if a special sentinel value is used as end() value. In
209                                              this case, this member must return the real position
210                                              after the last element. */
211         };
212
213         /** \brief Example of a list container policy. ONLY FOR EXPOSITION
214             
215             \see \ref ExampleListPolicy \n
216                 \ref Parse_List
217          */
218         struct container_policy
219         {
220             void init(iterator i, state_type s); ///< Initialize new container
221             void update(iterator i, state_type s); ///< Called before every container access
222         };
223     };
224
225     template <class ListPolicy>
226     class Parse_List_Container
227         : private ListPolicy
228     {
229     public:
230         ///////////////////////////////////////////////////////////////////////////
231         // Types
232
233         typedef typename ListPolicy::parser_type parser_type;
234         typedef PacketParserBase::data_iterator data_iterator;
235         typedef PacketParserBase::size_type size_type;
236         typedef PacketParserBase::difference_type difference_type;
237         typedef typename ListPolicy::element_type value_type;
238         typedef detail::Parse_List_Iterator<
239             value_type, typename ListPolicy::iterator_policy> iterator;
240         typedef iterator const_iterator;
241         typedef PacketParserBase::state_type state_type;
242         
243         ///////////////////////////////////////////////////////////////////////////
244         ///\name Structors and default members
245         ///@{
246
247         // no default constructor
248         // default copy
249         // default destructor
250         // conversion constructors
251
252         Parse_List_Container(parser_type const & list);
253         ~Parse_List_Container();
254         
255         ///@}
256         ///////////////////////////////////////////////////////////////////////////
257
258         ///\name Accessors
259         ///@{
260
261         size_type size() const;
262         bool empty() const;
263
264         iterator begin() const;
265         iterator end() const;
266
267         value_type front() const;
268         value_type back() const;
269
270         ///@}
271         ///\name Mutators
272         ///@{
273
274         // All these operations can be quite inefficient depending on the list type
275         void shift(iterator pos, size_type n=1);
276         template <class Value>
277         void insert(iterator pos, Value const & t);
278         template <class Value>
279         void insert(iterator pos, size_type n, Value const & t);
280         template <class ForwardIterator>
281         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
282                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
283
284         void erase(iterator pos, size_type n=1);
285         void erase(iterator f, iterator l);
286         void clear();
287
288         template <class Value> void push_back        (Value value, size_type n=1);
289                                void push_back_space  (size_type n=1);
290         template <class Value> void push_front       (Value value, size_type n=1);
291                                void push_front_space (size_type n=1);
292                                void resize           (size_type n);
293         template <class Value> void resize           (size_type n, Value value);
294
295         ///@}
296
297         ///\name Parser interface
298         ///@{
299
300         parser_type parser() const;
301         data_iterator i() const;
302         state_type state() const;
303         PacketData & data() const;
304
305         size_type bytes() const;
306         void init() const;
307         
308         ///@}
309
310     private:
311         state_type state_;
312         size_type i_;
313     };
314
315         
316 }
317
318 ///////////////////////////////hh.e////////////////////////////////////////
319 #endif
320 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseList_i_)
321 #define HH_ParseList_i_
322 //#include "ParseList.cci"
323 #include "ParseList.ct"
324 #include "ParseList.cti"
325 #endif
326
327 \f
328 // Local Variables:
329 // mode: c++
330 // fill-column: 100
331 // c-file-style: "senf"
332 // indent-tabs-mode: nil
333 // ispell-local-dictionary: "american"
334 // compile-command: "scons -u test"
335 // comment-column: 40
336 // End: