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 Some basic list access methods are defined as parser members. To access the complete list
62 API however you will need to instantiate a container wrapper for the list. See \ref
63 packet_usage_fields_collection.
66 How to access \ref packet_usage_fields_collection \n
67 SENF_PARSER_LIST() macro used to define list fields \n
68 ListParser_Container list container wrapper API \n
71 \ingroup parsecollection
73 template <class ListPolicy>
75 : public PacketParserBase,
79 typedef ListPolicy policy;
81 ListParser(data_iterator i, state_type s);
82 ListParser(ListPolicy policy, data_iterator i, state_type s);
83 ///< Additional policy specific constructor
84 /**< This constructor may be used, if the policy needs
85 additional parameters. */
87 size_type bytes() const;
90 static const size_type init_bytes = ListPolicy::init_bytes;
92 ///////////////////////////////////////////////////////////////////////////
93 // Container interface
95 typedef typename ListPolicy::element_type value_type;
96 typedef typename ListPolicy::container_type container;
98 size_type size() const;
101 value_type front() const;
102 value_type back() const;
104 template <class Value> void push_back (Value const & value, size_type n=1) const;
105 value_type push_back_space (size_type n=1) const;
106 template <class Value> void push_front (Value const & value, size_type n=1) const;
107 value_type push_front_space (size_type n=1) const;
108 void resize (size_type n) const;
109 template <class Value> void resize (size_type n, Value value) const;
111 static ListParser & get(ListPolicy & p);
112 static ListParser const & get(ListPolicy const & p);
115 template <class Policy> friend class ListParser_Container;
118 /** \brief ListParser container wrapper
120 This is the container wrapper used for list parsers. The container wrapper will stay valid
121 after changing the collection. However the container still depends on the packet and will be
122 invalidated if the Packet is deallocated or if the packet size is changed from without the
123 container wrapper (more precisely, it is invalided if the insertion/deletion happens before
124 the vector in the packet data).
126 The vector container wrapper provides a complete STL random-access sequence interface.
130 SomePacket::aListCollection_t::container c (p->aListCollection());
131 c.insert(c.begin(), ... );
136 template <class ListPolicy>
137 class ListParser_Container
141 ///////////////////////////////////////////////////////////////////////////
144 typedef ListPolicy policy;
145 typedef typename ListPolicy::parser_type parser_type;
146 typedef PacketParserBase::data_iterator data_iterator;
147 typedef PacketParserBase::size_type size_type;
148 typedef PacketParserBase::difference_type difference_type;
149 typedef typename ListPolicy::element_type value_type;
150 typedef detail::ListParser_Iterator<ListParser_Container> iterator;
151 typedef iterator const_iterator;
152 typedef PacketParserBase::state_type state_type;
154 ///////////////////////////////////////////////////////////////////////////
155 ///\name Structors and default members
158 // no default constructor
160 // default destructor
161 // conversion constructors
163 ListParser_Container(parser_type const & list);
164 ~ListParser_Container();
167 ///////////////////////////////////////////////////////////////////////////
172 size_type size() const;
175 iterator begin() const;
176 iterator end() const;
178 value_type front() const;
179 value_type back() const;
185 // All these operations can be quite inefficient depending on the list type
186 value_type shift(iterator pos, size_type n=1);
187 template <class Value>
188 void insert(iterator pos, Value const & t);
189 template <class Value>
190 void insert(iterator pos, size_type n, Value const & t);
191 template <class ForwardIterator>
193 void insert(iterator pos, ForwardIterator f, ForwardIterator l,
194 typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
196 void insert(iterator pos, ForwardIterator f, ForwardIterator l);
199 void erase(iterator pos, size_type n=1);
200 void erase(iterator f, iterator l);
203 template <class Value> void push_back (Value const & value, size_type n=1);
204 value_type push_back_space (size_type n=1);
205 template <class Value> void push_front (Value const & value, size_type n=1);
206 value_type push_front_space (size_type n=1);
207 void resize (size_type n);
208 template <class Value> void resize (size_type n, Value value);
212 ///\name Parser interface
215 parser_type parser() const;
216 data_iterator i() const;
217 state_type state() const;
218 PacketData & data() const;
220 size_type bytes() const;
226 friend class detail::ListParser_Iterator<ListParser_Container>;
232 /** \brief Define ListParser field
234 This macro is a special helper to define a senf::ListParser type field, a list of elements
235 of type \a elt_type (a parser) which size is determined by \a size.
238 // The size field should be declared private or read-only (size is accessible via the list)
239 SENF_PARSER_PRIVATE_FIELD ( list_size_, senf::UInt16Parser );
241 SENF_PARSER_LIST ( list, list_size_, EltParser );
244 Here \c EltParser can be an arbitrary parser and need not have a fixed size.
246 \warning Realize, that the \a size field is controlled by the list parser. This field
247 should therefore be declared either read-only or private and must be changed only via
250 Further additional tags are supported which modify the type of list created:
252 <table class="senf fixedcolumn">
253 <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the list in bytes not the
254 number of contained elements</td></tr>
256 <tr><td>\c packetSize()</td><td>Use the size of the packet to get the list size. The
257 list will occupy all space up to the end of the packet.</td></tr>
259 <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
260 size value, the value is not used directly</td>
262 <tr><td>\c transform(\a transform, \c bytes(\a size))</td><td>The \a transform is applied to
263 the \a size value. The value is then interpreted containing the list size in bytes not
264 number of elements</td>
267 The optional \a transform is a class with the following layout
271 typedef ... value_type;
272 static value_type get(other_type v);
273 static other_type set(value_type v);
277 \c other_type is \a size ::\c value_type, the type of the value returned by the \a size
278 field, whereas the \c value_type typedef is the arbitrary return type of the transform.
280 The tags are applied to the \a size parameter:
282 SENF_PARSER_LIST ( list, transform(MyTransform, list_size_), EltParser );
285 \warning There are some caveats when working with \c bytes() type lists:
286 \li You may <b>only change the size of a contained element from a container wrapper</b>.
287 \li While you hold a container wrapper, <b>only access the packet through this wrapper</b>
288 or a nested wrapper either for reading or writing.
290 \warning If lists are nested, you need to allocate a container wrapper for each level and
291 may only access the packet through the lowest-level active container wrapper.
293 \implementation These restrictions are necessary to ensure correct recalculation of the
294 <tt>bytes</tt> field. For more info, see the comments in \ref ListBParser.ih
296 \param[in] name field name
297 \param[in] size name of field giving the list size
298 \param[in] elt_type list element type
301 How to use \ref packet_usage_fields_collection \n
302 senf::ListParser the list parser API for list field access
303 senf::ListParser_Container the list parser container API for list field access
306 \ingroup packetparsermacros
308 # define SENF_PARSER_LIST(name, size, elt_type) \
309 SENF_PARSER_LIST_I(public, name, size, elt_type)
311 /** \brief Define private ListParser field
313 \see \ref SENF_PARSER_LIST()
316 \ingroup packetparsermacros
318 # define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
319 SENF_PARSER_LIST_I(protected, name, size, elt_type)
323 ///////////////////////////////hh.e////////////////////////////////////////
325 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_ListParser_i_)
326 #define HH_SENF_Packets_ListParser_i_
327 //#include "ListParser.cci"
328 #include "ListParser.ct"
329 #include "ListParser.cti"
336 // c-file-style: "senf"
337 // indent-tabs-mode: nil
338 // ispell-local-dictionary: "american"
339 // compile-command: "scons -u test"
340 // comment-column: 40