Packets: Update AuxParser interface
[senf.git] / Packets / ListParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
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 ListParser public header */
25
26 #ifndef HH_ListParser_
27 #define HH_ListParser_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include "PacketParser.hh"
32
33 //#include "ListParser.mpp"
34 ///////////////////////////////hh.p////////////////////////////////////////
35
36 namespace senf {
37
38     namespace detail { template <class Container> class ListParser_Iterator; }
39
40     template <class ListPolicy>
41     class ListParser_Container;
42
43     /** \brief Arbitrary sequential element collection
44
45         A List is a sequential collection of elements. The element type is given as an arbitrary
46         parser. The list is more flexible than a vector: It is not limited to fixed-size elements
47         and it might not have direct access to the size of the collection.
48
49         The cost is however, that a List is only a model of an STL forward sequence. The parser
50         provides a reduced interface to this sequence, the container wrapper provides the complete
51         interface.
52
53         Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the
54         list is laid out. This policy is given quite some freedom in the list
55         implementation. It is however important, that list elements <em>always follow each other
56         without padding</em> (if padding is needed, it needs to be part of the element parser).
57
58         \see ExampleListPolicy
59         \ingroup parsecollection
60       */
61     template <class ListPolicy>
62     class ListParser
63         : public PacketParserBase,
64           private ListPolicy
65     {
66     public:
67         typedef ListPolicy policy;
68
69         ListParser(data_iterator i, state_type s);
70         ListParser(ListPolicy policy, data_iterator i, state_type s);
71                                         ///< Additional policy specific constructor
72                                         /**< This constructor may be used, if the policy needs
73                                              additional parameters. */
74
75         size_type bytes() const;
76         void init() const;
77
78         static const size_type init_bytes = ListPolicy::init_bytes;
79
80         ///////////////////////////////////////////////////////////////////////////
81         // Container interface
82
83         typedef typename ListPolicy::element_type value_type;
84         typedef typename ListPolicy::container_type container;
85
86         size_type size() const;
87         bool empty() const;
88
89         value_type front() const;
90         value_type back() const;
91
92         template <class Value> void push_back        (Value value, size_type n=1) const;
93                                void push_back_space  (size_type n=1) const;
94         template <class Value> void push_front       (Value value, size_type n=1) const;
95                                void push_front_space (size_type n=1) const;
96                                void resize           (size_type n) const;
97         template <class Value> void resize           (size_type n, Value value) const;
98
99         static ListParser & get(ListPolicy & p);
100         static ListParser const & get(ListPolicy const & p);
101
102     private:
103         template <class Policy> friend class ListParser_Container;
104     };
105
106     /** \brief ListParser container wrapper
107
108         This is the container wrapper used for list parsers. The container wrapper will stay valid
109         after changing the collection. However the container still depends on the packet and will be
110         invalidated if the Packet is deallocated or if the packet size is changed from without the
111         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
112         the vector in the packet data).
113
114         The vector container wrapper provides a complete STL random-access sequence interface.
115
116         \code
117         SomePacket p (...);
118         SomePacket::aListCollection_t::container c (p->aListCollection());
119         c.insert(c.begin(), ... );
120         \endcode
121
122         \see ListParser
123       */
124     template <class ListPolicy>
125     class ListParser_Container
126         : private ListPolicy
127     {
128     public:
129         ///////////////////////////////////////////////////////////////////////////
130         // Types
131
132         typedef ListPolicy policy;
133         typedef typename ListPolicy::parser_type parser_type;
134         typedef PacketParserBase::data_iterator data_iterator;
135         typedef PacketParserBase::size_type size_type;
136         typedef PacketParserBase::difference_type difference_type;
137         typedef typename ListPolicy::element_type value_type;
138         typedef detail::ListParser_Iterator<ListParser_Container> iterator;
139         typedef iterator const_iterator;
140         typedef PacketParserBase::state_type state_type;
141
142         ///////////////////////////////////////////////////////////////////////////
143         ///\name Structors and default members
144         ///@{
145
146         // no default constructor
147         // default copy
148         // default destructor
149         // conversion constructors
150
151         ListParser_Container(parser_type const & list);
152         ~ListParser_Container();
153
154         ///@}
155         ///////////////////////////////////////////////////////////////////////////
156
157         ///\name Accessors
158         ///@{
159
160         size_type size() const;
161         bool empty() const;
162
163         iterator begin() const;
164         iterator end() const;
165
166         value_type front() const;
167         value_type back() const;
168
169         ///@}
170         ///\name Mutators
171         ///@{
172
173         // All these operations can be quite inefficient depending on the list type
174         void shift(iterator pos, size_type n=1);
175         template <class Value>
176         void insert(iterator pos, Value const & t);
177         template <class Value>
178         void insert(iterator pos, size_type n, Value const & t);
179         template <class ForwardIterator>
180 #       ifndef DOXYGEN
181         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
182                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
183 #       else
184         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
185 #       endif
186
187         void erase(iterator pos, size_type n=1);
188         void erase(iterator f, iterator l);
189         void clear();
190
191         template <class Value> void push_back        (Value value, size_type n=1);
192                                void push_back_space  (size_type n=1);
193         template <class Value> void push_front       (Value value, size_type n=1);
194                                void push_front_space (size_type n=1);
195                                void resize           (size_type n);
196         template <class Value> void resize           (size_type n, Value value);
197
198         ///@}
199
200         ///\name Parser interface
201         ///@{
202
203         parser_type parser() const;
204         data_iterator i() const;
205         state_type state() const;
206         PacketData & data() const;
207
208         size_type bytes() const;
209         void init() const;
210
211         ///@}
212
213     private:
214         friend class detail::ListParser_Iterator<ListParser_Container>;
215
216         state_type state_;
217         size_type i_;
218     };
219
220 #    define SENF_PARSER_LIST(name, size, elt_type) \
221          SENF_PARSER_LIST_I(public, name, size, elt_type)
222
223 #    define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
224         SENF_PARSER_LIST_I(private, name, size, elt_type)
225
226 }
227
228 ///////////////////////////////hh.e////////////////////////////////////////
229 #endif
230 #if !defined(HH_Packets__decls_) && !defined(HH_ListParser_i_)
231 #define HH_ListParser_i_
232 //#include "ListParser.cci"
233 #include "ListParser.ct"
234 #include "ListParser.cti"
235 #endif
236
237 \f
238 // Local Variables:
239 // mode: c++
240 // fill-column: 100
241 // c-file-style: "senf"
242 // indent-tabs-mode: nil
243 // ispell-local-dictionary: "american"
244 // compile-command: "scons -u test"
245 // comment-column: 40
246 // End: