2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
22 \brief PacketType public header */
24 #ifndef HH_PacketType_
25 #define HH_PacketType_ 1
29 #include "PacketTypes.hh"
30 #include "PacketData.hh"
31 #include "PacketParser.hh"
34 //#include "PacketType.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
39 /** \brief Helper baseclass implementing the PacketType interface
41 This helper class maybe used when building a new PacketType. It provides a complete default
42 implementations of this interface. To define a new PacketType, derive from this class and
43 implement the members you want to change.
46 struct SomePacketType : public senf::PacketTypeBase
48 typedef senf::ConcretePacket<SomePacketType> packet;
49 typedef SomePacketParser parser;
51 static size_type initSize()
53 // This value can in most cases be taken from the parser
54 return senf::init_size<parser>::value;
57 static size_type initHeadSize()
59 // optional member. This is only needed, if the packet has header and trailer.
60 return constant_initial_size_of_header
63 static void init(packet p)
65 // Initialize a new packet by e.g. setting some fields. Should call
66 // the packet parsers init() member
71 static optional_range nextPacketRange(packet p)
74 // return iterator range delimiting the packet, e.g.:
75 return range(p.data()+begin_offset, p.data()+end_offset);
80 static factory_t nextPacketType(packet p)
82 if (have_next_packet && know_next_packet_type)
83 // \a NextPacket is the \c ConcretePacket instantiation of the next packet
84 return NextPacket::factory();
89 static void finalize(packet p)
91 // optionally complete the packet by generating autogenerated information
95 static void dump(packet p, std::ostream & os)
97 // Write out a readable representation of the packet for debug purposes
102 You may leave out any one of the members (you should however always define the \c
103 interpreter typedef member)
105 struct PacketTypeBase
107 typedef Packet packet;
109 typedef senf::detail::packet::iterator iterator;
110 typedef senf::detail::packet::const_iterator const_iterator;
111 typedef senf::detail::packet::size_type size_type;
112 typedef senf::detail::packet::difference_type difference_type;
113 typedef senf::detail::packet::byte byte;
115 typedef PacketInterpreterBase::range range;
116 typedef PacketInterpreterBase::optional_range optional_range;
117 typedef PacketInterpreterBase::factory_t factory_t;
119 static optional_range no_range();
120 static factory_t no_factory();
121 template <class PacketType> static factory_t factory();
123 typedef VoidPacketParser parser;
124 ///< Parser to parser packet fields
125 /**< This typedef has to be set to the parser of the packet
127 The default is a VoidPacketParser which does not parser
130 static size_type initSize();
131 ///< Get size of new (empty) packet
132 /**< The default implementation returns 0.
133 \returns size that needs to be allocated to a newly
134 constructed packet */
136 static size_type initHeadSize();
137 ///< Get size of new (empty) packet header
138 /**< This function gives the index within a newly created,
139 empty packet where a subpacket is to be placed.
141 The default implementation returns initSize().
143 \implementation Ok, it does not really return
144 initSize(), it returns size_type(-1) which is
145 interpreted to mean initSize(). It can't return
146 initSize since initSize() is not (and can't be
147 since it is static) virtual. */
149 static void init(packet p);
150 ///< Initialize new packet
151 /**< This member is called to initialize a just created new
152 packet. The new packet will have a size of at least
153 initSize() but the size may well be larger. It is also
154 possible for the packet to already have further
157 The default implementation does nothing. */
161 static optional_range nextPacketRange(packet p);
162 ///< Get next packet placement
163 /**< nextPacketRange returns the iterator range where the
164 next packet (header) is placed within the current
167 The default implementation always returns
170 \returns nextPacketRange must return
171 \li <tt>\ref interpreter::range(b,e)</tt> (where \a b
172 and \a e are the iterators delimiting the next
173 packet range) if the packet allows a next
174 header. The returned range is allowed to be empty.
175 \li <tt>\ref interpreter::no_range()</tt> (a
176 default constructed \c no_range instance) if
177 no next header is allowed */
179 static factory_t nextPacketType(packet p);
180 ///< Get type of next packet
181 /**< nextPacketType retrieves the type of the next packet
182 returning a factory to create that packet.
184 The default implementation always returns
185 <tt>no_factory()</tt>.
187 \returns factory to create next packet
188 \li <tt>interpreter::factory<OtherPacketType>()</tt> if
189 the type of the packet can be determined
190 \li <tt>interpreter::no_factory()</tt> if the type of
191 the packet cannot be determined or no next packet
194 static void finalize(packet p);
196 /**< finalize() will be called to complete a packet after it
197 has been modified. This function must calculate any
198 checksums, set size fields from the interpreter chain
201 The default implementation does nothing. */
203 static void dump(packet p, std::ostream & os);
204 ///< Dump packet data in readable form
205 /**< The dump() function writes out a complete
206 representation of the packet. This is used formost for
209 The default implementation does nothing. */
213 /** \brief Mixin to provide standard implementations for nextPacketRange and nextPacketType
215 This mixin class simplifies the definition of simple packets with fixed-size headers and/or
216 trailers. For this type of Packet, this mixin provides the nextPacketRange() and
217 nextPacketType() members:
219 struct SimplePacketType
220 : public senf::PacketTypeBase
221 pyblic senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
223 static interpreter::size_type initSize()
225 // This member is optional. If it is not defined, 'senf::init_size<parser>::value'
228 // The value returned is the length of the header if initHeadSize() is not defined.
229 // If initHeadSize is defined, this value is the combined size of the header
230 // and trailer while initHeadSize() will return the size of the header only.
234 static interpreter::size_type initHeadSize()
236 // This member is optional. It returns the header size if the packet has a
241 static registry_key_t nextPacketKey(packet p)
243 // Return the key in the registry under which the next packet
244 // header is to be found. This member must be given if a Registry argument is
245 // passed to the PacketTypeMixin template.
246 return i.fields().typeField();
251 template <class Self, class Registry=void>
252 class PacketTypeMixin
255 typedef typename Registry::key_t registry_key_t;
257 static PacketInterpreterBase::optional_range nextPacketRange (Packet p);
258 static PacketInterpreterBase::factory_t nextPacketType (Packet p);
259 static PacketInterpreterBase::size_type initSize ();
260 static void init (Packet p);
263 template <class Self>
264 class PacketTypeMixin<Self,void>
267 static PacketInterpreterBase::optional_range nextPacketRange (Packet p);
268 static PacketInterpreterBase::size_type initSize ();
269 static void init (Packet p);
274 ///////////////////////////////hh.e////////////////////////////////////////
275 #include "PacketType.cci"
276 //#include "PacketType.ct"
277 #include "PacketType.cti"
284 // c-file-style: "senf"
285 // indent-tabs-mode: nil
286 // ispell-local-dictionary: "american"
287 // compile-command: "scons -u test"
288 // comment-column: 40