4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief ListParser public header */
26 #ifndef HH_SENF_Packets_ListParser_
27 #define HH_SENF_Packets_ListParser_ 1
30 #include <boost/utility.hpp>
31 #include "PacketParser.hh"
33 //#include "ListParser.mpp"
34 ///////////////////////////////hh.p////////////////////////////////////////
38 namespace detail { template <class Container> class ListParser_Iterator; }
40 template <class ListPolicy>
41 class ListParser_Container;
43 /** \brief Arbitrary sequential element collection
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.
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
53 ListParser 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 implementation. It is
55 however important, that list elements <em>always follow each other without padding</em> (if
56 padding is needed, it needs to be part of the element parser).
58 You will normally not instantiate ListParser directly, you will use the \ref
59 SENF_PARSER_LIST() helper macro.
61 \see ExampleListPolicy
62 \ingroup parsecollection
64 template <class ListPolicy>
66 : public PacketParserBase,
70 typedef ListPolicy policy;
72 ListParser(data_iterator i, state_type s);
73 ListParser(ListPolicy policy, data_iterator i, state_type s);
74 ///< Additional policy specific constructor
75 /**< This constructor may be used, if the policy needs
76 additional parameters. */
78 size_type bytes() const;
81 static const size_type init_bytes = ListPolicy::init_bytes;
83 ///////////////////////////////////////////////////////////////////////////
84 // Container interface
86 typedef typename ListPolicy::element_type value_type;
87 typedef typename ListPolicy::container_type container;
89 size_type size() const;
92 value_type front() const;
93 value_type back() const;
95 template <class Value> void push_back (Value value, size_type n=1) const;
96 void push_back_space (size_type n=1) const;
97 template <class Value> void push_front (Value value, size_type n=1) const;
98 void push_front_space (size_type n=1) const;
99 void resize (size_type n) const;
100 template <class Value> void resize (size_type n, Value value) const;
102 static ListParser & get(ListPolicy & p);
103 static ListParser const & get(ListPolicy const & p);
106 template <class Policy> friend class ListParser_Container;
109 /** \brief ListParser container wrapper
111 This is the container wrapper used for list parsers. The container wrapper will stay valid
112 after changing the collection. However the container still depends on the packet and will be
113 invalidated if the Packet is deallocated or if the packet size is changed from without the
114 container wrapper (more precisely, it is invalided if the insertion/deletion happens before
115 the vector in the packet data).
117 The vector container wrapper provides a complete STL random-access sequence interface.
121 SomePacket::aListCollection_t::container c (p->aListCollection());
122 c.insert(c.begin(), ... );
127 template <class ListPolicy>
128 class ListParser_Container
132 ///////////////////////////////////////////////////////////////////////////
135 typedef ListPolicy policy;
136 typedef typename ListPolicy::parser_type parser_type;
137 typedef PacketParserBase::data_iterator data_iterator;
138 typedef PacketParserBase::size_type size_type;
139 typedef PacketParserBase::difference_type difference_type;
140 typedef typename ListPolicy::element_type value_type;
141 typedef detail::ListParser_Iterator<ListParser_Container> iterator;
142 typedef iterator const_iterator;
143 typedef PacketParserBase::state_type state_type;
145 ///////////////////////////////////////////////////////////////////////////
146 ///\name Structors and default members
149 // no default constructor
151 // default destructor
152 // conversion constructors
154 ListParser_Container(parser_type const & list);
155 ~ListParser_Container();
158 ///////////////////////////////////////////////////////////////////////////
163 size_type size() const;
166 iterator begin() const;
167 iterator end() const;
169 value_type front() const;
170 value_type back() const;
176 // All these operations can be quite inefficient depending on the list type
177 void shift(iterator pos, size_type n=1);
178 template <class Value>
179 void insert(iterator pos, Value const & t);
180 template <class Value>
181 void insert(iterator pos, size_type n, Value const & t);
182 template <class ForwardIterator>
184 void insert(iterator pos, ForwardIterator f, ForwardIterator l,
185 typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
187 void insert(iterator pos, ForwardIterator f, ForwardIterator l);
190 void erase(iterator pos, size_type n=1);
191 void erase(iterator f, iterator l);
194 template <class Value> void push_back (Value value, size_type n=1);
195 void push_back_space (size_type n=1);
196 template <class Value> void push_front (Value value, size_type n=1);
197 void push_front_space (size_type n=1);
198 void resize (size_type n);
199 template <class Value> void resize (size_type n, Value value);
203 ///\name Parser interface
206 parser_type parser() const;
207 data_iterator i() const;
208 state_type state() const;
209 PacketData & data() const;
211 size_type bytes() const;
217 friend class detail::ListParser_Iterator<ListParser_Container>;
223 /** \brief Define ListParser field
225 This macro is a special helper to define a senf::ListParser type field, a list of elements
226 of type \a elt_type (a parser) which size is determined by \a size.
229 // The size field should be declared private or read-only (size is accessible via the list)
230 SENF_PARSER_PRIVATE_FIELD ( list_size_, senf::UInt16Parser );
232 SENF_PARSER_LIST ( list, list_size_, EltParser );
235 Here \c EltParser can be an arbitrary parser and need not have a fixed size.
237 \warning Realize, that the \a size field is controlled by the list parser. This field
238 should therefore be declared either read-only or private and must be changed only via
241 Further additional tags are supported which modify the type of list created:
243 <table class="senf fixedcolumn">
244 <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the list in bytes not the
245 number of contained elements</td></tr>
247 <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
248 size value, the value is not used directly</td>
250 <tr><td>\c transform(\a transform, \c bytes(\a size))</td><td>The \a transform is applied to
251 the \a size value. The value is then interpreted containing the list size in bytes not
252 number of elements</td>
255 The optional \a transform is a class with the following layout
259 typedef ... value_type;
260 static value_type get(other_type v);
261 static other_type set(value_type v);
265 \c other_type is \a size ::\c value_type, the type of the value returned by the \a size
266 field, whereas the \c value_type typedef is the arbitrary return type of the transform.
268 The tags are applied to the \a size parameter:
270 SENF_PARSER_LIST ( list, transform(MyTransform, list_size_), EltParser );
273 \warning There are some caveats when working with \c bytes() type lists:
274 \li You may <b>only change the size of a contained element from a container wrapper</b>.
275 \li While you hold a container wrapper, <b>only access the packet through this wrapper</b>
276 or a nested wrapper either for reading or writing.
278 \warning If lists are nested, you need to allocate a container wrapper for each level and
279 may only access the packet through the lowest-level active container wrapper.
281 \implementation These restrictions are necessary to ensure correct recalculation of the
282 <tt>bytes</tt> field. For more info, see the comments in \ref ListBParser.ih
284 \param[in] name field name
285 \param[in] size name of field giving the list size
286 \param[in] elt_type list element type
289 \ingroup packetparsermacros
291 # define SENF_PARSER_LIST(name, size, elt_type) \
292 SENF_PARSER_LIST_I(public, name, size, elt_type)
294 /** \brief Define private ListParser field
296 \see \ref SENF_PARSER_LIST()
299 \ingroup packetparsermacros
301 # define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
302 SENF_PARSER_LIST_I(private, name, size, elt_type)
306 ///////////////////////////////hh.e////////////////////////////////////////
308 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_ListParser_i_)
309 #define HH_SENF_Packets_ListParser_i_
310 //#include "ListParser.cci"
311 #include "ListParser.ct"
312 #include "ListParser.cti"
319 // c-file-style: "senf"
320 // indent-tabs-mode: nil
321 // ispell-local-dictionary: "american"
322 // compile-command: "scons -u test"
323 // comment-column: 40