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 Packet public header */
26 #ifndef HH_SENF_Packets_Packet_
27 #define HH_SENF_Packets_Packet_ 1
30 #include <boost/operators.hpp>
31 #include <boost/utility.hpp>
32 #include <boost/type_traits/is_integral.hpp>
33 #include <senf/Utils/Tags.hh>
34 #include <senf/Utils/safe_bool.hh>
35 #include "PacketInterpreter.hh"
37 //#include "Packet.mpp"
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 /** \defgroup packet_module Packet Handling
44 The basic groundwork of the %Packet library is the packet handling:
46 \li The packet classes provide access to a chain of packet headers (more generically called
48 \li They automatically manage the required memory resources and the shared packet data.
50 \section packet_module_chain The Interpreter Chain
52 The central data structure for a packet is the interpreter chain
54 \image html structure.png The Interpreter Chain
56 This image depicts a packet with several headers. Each interpreter is responsible for a
57 specific sub-range of the complete packet. This range always \e includes the packets payload
58 (This is, why we call the data structure interpreter and not header: The interpreter is
59 responsible for interpreting a range of the packet according to a specific protocol), the
60 packet interpreters are nested inside each other.
62 For each interpreter, this structure automatically divides the packet into three areas (each
63 of which are optional): The header, the payload and the trailer. Every packet will have
64 either a header or a payload section while most don't have a trailer.
66 As user of the library you always interact with the chain through one (or more) of the
67 interpreters. The interpreter provides methods to traverse to the following or preceding
68 header (interpreter) and provides two levels of access to the packet data: Generic low-level
69 access in the form of an STL compatible sequence and access to the parsed fields which are
70 provided by the parser associated with the concrete packet type.
72 \section packet_module_management Resource Management
74 The interface to the packet library is provided using a handle class (\ref Packet for
75 generic, protocol agnostic access and \ref ConcretePacket derived from \ref Packet to access
76 a specific protocol). This handle automatically manages the resources associated with the
77 packet (the interpreter chain and the data storage holding the packet data). The resources
78 are automatically released when the last packet handle referencing a specific packet is
81 \implementation The packet chain is provided on two levels: The internal representation \ref
82 PacketInterpreterBase and \ref PacketInterpreter which are referenced by the Handle
83 classes \ref Packet and \ref ConcretePacket. \n
84 The internal representation classes are pertinent in the sense, that they exist
85 regardless of the existence of a handle referencing them (as long as the packet
86 exists). Still the interpreter chain is lazy and packet interpreters beside the first
87 are only created dynamically when accessed (this is implemented in the handle not in the
88 internal representation). \n
89 The packet interpreters make use of a pool allocator. This provides extremely efficient
90 creation and destruction of packet interpreter's and removes the dynamic memory
91 management overhead from the packet interpreter management. The packet implementation
92 class (\ref PacketImpl which holds the packet data itself) however is still dynamically
93 managed (however there is only a single instance for each packet).
96 template <class PackeType> class ConcretePacket;
98 ///\addtogroup packet_module
101 /** \brief Main %Packet class
103 %Packet is the main externally visible class of the packet library. %Packet is a handle into
104 the internal packet representation. From %Packet you may access the data of that specific
105 sub-packet/header/interpreter and navigate to the neighboring
106 sub-packets/headers/interpreters.
108 %Packet is protocol agnostic. This class only provides non-protocol dependent members. To
109 access the protocol specific features of a packet (like header fields) the ConcretePacket
110 class extending %Packet is provided.
112 \section packet_semantics Semantics
114 All operations accessing the data of \c this packet in some way will ignore any preceding
115 packets/headers/interpreters in the chain. It does not matter, whether a given packet is
116 taken from the middle or the beginning of the chain, all operations (except those explicitly
117 accessing the chain of course) should work the same.
119 This especially includes members like clone() or append(): clone() will clone \e only from
120 \c this packet until the end of the chain, append() will append the given packet \e ignoring
121 any possibly preceding packets/headers/interpreters.
123 In the same way, the data() member provides an STL-sequence compatible view of the packet
124 data. This only includes the data which is part of \c this packet including header, trailer
125 \e and payload but \e not the headers or trailers of packets \e before \c this packet in the
126 packet/header/interpreter chain (nonetheless, this data overlaps with the data of other
129 Several members are member templates taking an \a OtherPacket template parameter. This
130 parameter must be the ConcretePacket instantiation associated with some concrete packet type
131 (protocol). For each implemented protocol, typedefs should be provided for these
132 instantiations (Example: \ref EthernetPacket is a typedef for
133 \ref ConcretePacket < \ref EthernetPacketType >).
136 \ref ConcretePacket for the %type specific interface\n
137 \ref PacketData for the sequence interface\n
138 \ref packetparser for a specification of the parser interface
141 : public safe_bool<Packet>,
142 public boost::equality_comparable<Packet>
145 //-////////////////////////////////////////////////////////////////////////
148 typedef void type; ///< Type of the packet.
149 typedef senf::detail::packet::size_type size_type;
150 ///< Unsigned type to represent packet size
151 typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
153 //-////////////////////////////////////////////////////////////////////////
154 ///\name Structors and default members
157 // default copy constructor
158 // default copy assignment
159 // default destructor
161 Packet(); ///< Create uninitialized packet handle
162 /**< An uninitialized handle is in - valid(). It does not
163 allow any operation except assignment and checking for
165 Packet clone() const; ///< Create copy packet
166 /**< clone() will create a complete copy of \c this
167 packet. The returned packet will have the same data,
168 annotations and packet chain. It does however not
169 share any data with the original packet. */
171 // conversion constructors
173 template <class PacketType>
174 Packet(ConcretePacket<PacketType> const & packet);
175 ///< Copy-construct Packet from ConcretePacket
176 /**< This constructor allows to convert an arbitrary
177 ConcretePacket into a general Packet, loosing the
178 protocol specific interface. */
181 //-////////////////////////////////////////////////////////////////////////
183 ///\name Interpreter chain access
186 Packet next() const; ///< Get next packet in chain
187 /**< \throws InvalidPacketChainException if no next packet
189 Packet next(NoThrow_t) const; ///< Get next packet in chain
190 /**< \returns in - valid() packet if no next packet
192 template <class OtherPacket> OtherPacket next() const;
193 ///< Get next packet in chain and cast to \a OtherPacket
194 /**< \throws std::bad_cast if the next() packet is not of
196 \throws InvalidPacketChainException if no next packet
198 template <class OtherPacket> OtherPacket next(NoThrow_t) const;
199 ///< Get next packet in chain and cast to \a OtherPacket
200 /**< \returns in - valid() packet if no next packet
201 exists or if next() packet is not of
202 type \a OtherPacket */
203 template <class OtherPacket> OtherPacket find() const;
204 ///< Search chain forward for packet of type \a OtherPacket
205 /**< The search will start with the current packet.
206 \throws InvalidPacketChainException if no packet of
207 type \a OtherPacket can be found. */
208 template <class OtherPacket> OtherPacket find(NoThrow_t) const;
209 ///< Search chain forward for packet of type \a OtherPacket
210 /**< The search will start with the current packet.
211 \returns in - valid() packet if no packet of type \a
212 OtherPacket can be found. */
214 Packet prev() const; ///< Get previous packet in chain
215 /**< \throws InvalidPacketChainException if no previous
217 Packet prev(NoThrow_t) const; ///< Get previous packet in chain
218 /**< \returns in - valid() packet if no previous packet
220 template <class OtherPacket> OtherPacket prev() const;
221 ///< Get previous packet in chain and cast to \a OtherPacket
222 /**< \throws std::bad_cast, if the previous packet is not of
224 \throws InvalidPacketChainException if no previous
226 template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
227 ///< Get previous packet in chain and cast to \a OtherPacket
228 /**< \returns in - valid() packet if no previous packet
229 exists or if the previous packet is not of
230 type \a OtherPacket */
231 template <class OtherPacket> OtherPacket rfind() const;
232 ///< Search chain backwards for packet of type \a OtherPacket
233 /**< The search will start with the current packet.
234 \throws InvalidPacketChainException if no packet of
235 type \a OtherPacket can be found. */
236 template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
237 ///< Search chain backwards for packet of type \a OtherPacket
238 /**< The search will start with the current packet.
239 \returns in - valid() packet if no packet of type \a
240 OtherPacket can be found. */
243 Packet first() const; ///< Return first packet in chain
244 template <class OtherPacket> OtherPacket first() const;
245 ///< Return first packet in chain and cast
246 /**< \throws std::bad_cast if the first() packet is not of
247 type \a OtherPacket */
249 Packet last() const; ///< Return last packet in chain
250 template <class OtherPacket> OtherPacket last() const;
251 ///< Return last packet in chain and cast
252 /**< \throws std::bad_cast if the last() packet is not of
253 type \a OtherPacket */
256 template <class OtherPacket> OtherPacket parseNextAs() const;
257 ///< Interpret payload of \c this as \a OtherPacket
258 /**< parseNextAs() will throw away the packet chain after
259 the current packet if necessary. It will then parse the
260 payload section of \c this packet as given by \a
261 OtherPacket. The new packet is added to the chain after
263 \returns new packet instance sharing the same data and
264 placed after \c this packet in the chain.
265 \throws InvalidPacketChainException if no next packet
266 header is allowed (viz. nextPacketRange() of the
267 the current PacketType returns no_range() ) */
268 Packet parseNextAs(factory_t factory) const;
269 ///< Interpret payload of \c this as \a factory type packet
270 /**< parseNextAs() will throw away the packet chain after
271 the current packet if necessary. It will then parse the
272 payload section of \c this packet as given by \a
273 factory. The new packet is added to the chain after
275 \returns new packet instance sharing the same data and
276 placed after \c this packet in the chain.
277 \throws InvalidPacketChainException if no next packet
278 header is allowed (viz. nextPacketRange() of the
279 the current PacketType returns no_range() ) */
281 template <class OtherPacket> bool is() const;
282 ///< Check, whether \c this packet is of the given type
283 template <class OtherPacket> OtherPacket as() const;
284 ///< Cast current packet to the given type
285 /**< This operations returns a handle to the same packet
286 header/interpreter however upcast to the given
287 ConcretePacket type which have been instantiated
289 \throws std::bad_cast if the current packet is not of
290 type \a OtherPacket */
291 template <class OtherPacket> OtherPacket as(NoThrow_t) const;
292 ///< Cast current packet to the given type
293 /**< This operations returns a handle to the same packet
294 header/interpreter however upcast to the given
295 ConcretePacket type which have been instantiated
297 \warning You must make absolutely sure that the packet
298 is of the given type. If not, calling this member
299 crashes your program in a unkindly way. */
301 Packet append(Packet const & packet) const; ///< Append the given packet to \c this packet
302 /**< This operation will replace the payload section of \c
303 this packet with \a packet. This operation will replace
304 the packet chain after \c this packet with a clone of
305 \a packet and will replace the raw data of the payload
306 of \c this with the raw data of \a packet. \c this
307 packet will not share any data with \a packet.
308 \returns Packet handle to the cloned \a packet, placed
309 after \c this in the packet/header/interpreter
312 void reparse() const; ///< Reparse the payload the packet
313 /**< This member will throw away the packet chain after the
314 current packet. The payload will be reparsed
315 automatically when calling next() */
321 PacketData & data() const; ///< Access the packets raw data container
322 size_type size() const; ///< Return size of packet in bytes
323 /**< This size does \e not include the size of any preceding
324 headers/packets/interpreters. It does however include
325 \c this packets payload. */
331 template <class Annotation>
332 Annotation & annotation(); ///< Get packet annotation
333 /**< This member will retrieve an arbitrary packet
334 annotation. Every annotation is identified by a unique
335 \a Annotation type. This type should \e always be a \c
339 struct MyAnnotation {
343 senf::Packet p (...);
345 p.annotation<MyAnnotation>().value = 1;
348 Annotations are shared by all headers / interpreters
349 within a single packet chain.
351 If an annotation is \e not a POD type (more
352 specifically, if it's constructor or destructor is not
353 trivial including base classes and members), the \a
354 Annotation type \e must inherit from
355 senf::ComplexAnnotation. Failing to follow this rule
356 will result in undefined behavior and will probably
357 lead to a program crash.
360 struct MyStringAnnotation : senf::ComplexAnnotation {
364 (This type is not POD since \c std::string is not POD)
366 \see \ref packet_usage_annotation
368 \implementation The annotation system is implemented
369 quite efficiently since annotations are stored
370 within a packet embedded vector of fixed size (the
371 size is determined automatically at runtime by the
372 number of different annotations
373 used). Additionally, non-complex small annotations
374 require no additional memory management (\c new /
377 \idea Pool the annotation vectors: In the destructor
378 swap the vector into a vector graveyard (swapping
379 two vectors is an O(1) no allocation operation). In
380 the constructor, if there is a vector in the
381 graveyard, swap it in from there. Of course, it
382 would be better to do away with the vector and just
383 allocate the space together with the packet but
384 that looks quite complicated to do ... especially
385 considering that the packetimpl itself uses a pool.
388 template <class Annotation>
389 Annotation const & annotation() const; ///< Get packet annotation
390 /**< \see annotation() */
392 void clearAnnotations(); ///< Clear all packet annotations
393 /**< All packet annotations will be cleared. Afterwards
394 the annotations equates to a new created %packet.
395 \warning all references to existing complex
396 annotations become invalid. */
399 ///\name Other methods
402 bool operator==(Packet const & other) const; ///< Check for packet identity
403 /**< Two packet handles compare equal if they really are the
404 same packet header in the same packet chain. */
405 bool boolean_test() const; ///< Check, whether the packet is valid()
407 bool valid() const; ///< Check, whether the packet is valid()
408 /**< An in - valid() packet does not allow any operation
409 except checking for validity and assignment. in -
410 valid() packets serve the same role as 0-pointers.
412 This is an alias for boolean_test() which is called
413 when using a packet in a boolean context. */
415 void finalizeThis(); ///< Update calculated fields
416 /**< The finalize() family of members will update
417 calculated packet fields: checksums, size fields and so
418 on. This includes any field, which can be set from
419 other information in the packet. Each concrete packet
420 type should document, which fields are set by
423 finalizeThis() will \e only process the current
424 header. Even if only changing fields in this protocol,
425 depending on the protocol it may not be enough to
426 finalize this header only. See the packet type
429 template <class Other>
430 void finalizeTo(); ///< Update calculated fields
431 /**< The finalize() family of members will update
432 calculated packet fields: checksums, size fields and so
433 on. This includes any field, which can be set from
434 other information in the packet. Each concrete packet
435 type should document, which fields are set by
438 finalizeTo() will automatically process all
439 packets/headers/interpreters from the \e first
440 occurrence of packet type \a Other (beginning at \c
441 this packet searching forward towards deeper nested
442 packets) backwards up to \c this.
444 This call is equivalent to
446 p.finalizeTo(p.next<Other>())
449 void finalizeTo(Packet const & other); ///< Update calculated fields
450 /**< The finalize() family of members will update
451 calculated packet fields: checksums, size fields and so
452 on. This includes any field, which can be set from
453 other information in the packet. Each concrete packet
454 type should document, which fields are set by
457 finalizeTo(other) will automatically process all
458 packets/headers/interpreters beginning at \a other
459 backwards towards outer packets up to \c this. */
461 void finalizeAll(); ///< Update calculated fields
462 /**< The finalize() family of members will update
463 calculated packet fields: checksums, size fields and so
464 on. This includes any field, which can be set from
465 other information in the packet. Each concrete packet
466 type should document, which fields are set by
469 finalizeAll() will automatically process all
470 packets/headers/interpreters from the end of the chain
471 (the most inner packet) backwards up to \c this.
473 This call is equivalent to
475 p.finalizeTo(p.last())
478 Beware, that finalizeAll() will \e not finalize any
479 headers before \c this, it will \e only process inner
482 void dump(std::ostream & os) const; ///< Write out a printable packet representation
483 /**< This method is provided mostly to help debugging packet
484 problems. Each concrete packet should implement a dump
485 method writing out all fields of the packet in a
486 readable representation. dump() will call this member
487 for each packet/header/interpreter in the chain from \c
488 this packet up to the end of the chain. */
490 TypeIdValue typeId() const; ///< Get type of \c this packet
491 /**< This value is used e.g. in the packet registry to
492 associate packet types with other information.
493 \returns A type holding the same information as a
494 type_info object, albeit assignable */
495 factory_t factory() const; ///< Return factory instance of \c this packet
496 /**< The returned factory instance can be used to create new
497 packets of the given type without knowing the concrete
498 type of the packet. The value may be stored away for
499 later use if needed. */
501 unsigned long id() const; ///< Unique packet id
502 /**< Get a unique packet id. If two packets have the same
503 id, they share the internal data representation. */
505 bool is_shared() const; ///< check if this packet shares data with any another packet handle.
506 /**< This method returns true if there is any other packet
507 handle pointing to any header in the packet chain. */
512 explicit Packet(PacketInterpreterBase::ptr const & packet);
514 PacketInterpreterBase::ptr const & ptr() const;
517 Packet getNext() const;
518 Packet getLast() const;
520 PacketInterpreterBase::ptr packet_;
522 template <class PacketType>
523 friend class ConcretePacket;
524 friend class PacketParserBase;
527 /** \brief Protocol specific packet handle
529 The ConcretePacket template class extends Packet to provide protocol/packet type specific
530 aspects. These are packet constructors and access to the parsed packet fields.
532 The \c PacketType template argument to ConcretePacket is a protocol specific and internal
533 policy class which defines the protocol specific behavior. To access a specific type of
534 packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
535 (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
537 The new members provided by ConcretePacket over packet are mostly comprised of the packet
538 constructors. These come in three major flavors:
540 \li The create() family of constructors will create completely new packets.
541 \li The createAfter() family of constructors will create new packets (with new data for the
542 packet) \e after a given existing packet <em>thereby destroying and overwriting any
543 possibly existing packets and data after the given packet</em>.
544 \li The createBefore() family of constructors will create new packets (again with new data)
545 \e before a given existing packet <em>thereby destroying and overwriting any possibly
546 existing packets and data before the given packet</em>.
547 \li The createInsertBefore() family of constructors will create new packets \e before a
548 given packet \e inserting them into the packet chain after any existing packets before
551 Whereas create() will create a completely new packet with it's own chain and data storage,
552 createAfter(), createBefore() and createInsertBefore() extend a packet with additional
553 headers/interpreters. createAfter() will set the payload of the given packet to the new
554 packet whereas createBefore() and createInsertBefore() will create a new packet with the
555 existing packet as it's payload.
557 createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
558 replacing any possibly existing data whereas the latter will interpret the already \e
559 existing data as given by the type argument.
561 \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
562 PacketType policy class.
564 template <class PacketType>
569 //-////////////////////////////////////////////////////////////////////////
572 typedef PacketType type;
573 typedef typename PacketType::parser Parser;
575 //-////////////////////////////////////////////////////////////////////////
576 ///\name Structors and default members
579 // default copy constructor
580 // default copy assignment
581 // default destructor
582 // no conversion constructors
584 ConcretePacket(); ///< Create uninitialized packet handle
585 /**< An uninitialized handle is not valid(). It does not
586 allow any operation except assignment and checking for
589 static factory_t factory(); ///< Return factory for packets of specific type
590 /**< This \e static member is like Packet::factory() for a
591 specific packet of type \a PacketType */
593 // Create completely new packet
595 static ConcretePacket create(); ///< Create default initialized packet
596 /**< The packet will be initialized to it's default empty
598 static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
599 /**< This will create a completely empty and uninitialized
600 packet with <tt>size() == 0</tt>.
601 \param[in] senf::noinit This parameter must always have
602 the value \c senf::noinit. */
603 static ConcretePacket create(size_type size); ///< Create default initialized packet
604 /**< This member will create a default initialized packet
605 with the given size. If the size parameter is smaller
606 than the minimum allowed packet size an exception will
608 \param[in] size Size of the packet to create in bytes.
609 \throws TruncatedPacketException if \a size is smaller
610 than the smallest permissible size for this type of
612 static ConcretePacket create(size_type size, senf::NoInit_t);
613 ///< Create uninitialized packet
614 /**< Creates an uninitialized (all-zero) packet of the exact
616 \param[in] size Size of the packet to create in bytes
617 \param[in] senf::noinit This parameter must always have
618 the value \c senf::noinit. */
620 template <class ForwardReadableRange>
621 static ConcretePacket create(
622 ForwardReadableRange const & range,
623 typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
625 template <class ForwardReadableRange>
626 static ConcretePacket create(ForwardReadableRange const & range);
627 ///< Create packet from given data
628 /**< The packet will be created from a copy of the given
629 data. The data from the range will be copied directly
630 into the packet representation. The data will \e not be
631 validated in any way.
633 \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
634 of data to construct packet from. */
637 // Create packet as new packet after a given packet
639 static ConcretePacket createAfter(Packet const & packet);
640 ///< Create default initialized packet after \a packet
641 /**< The packet will be initialized to it's default empty
642 state. It will be appended as next header/interpreter
643 after \a packet in that packets interpreter chain.
644 \param[in] packet Packet to append new packet to. */
645 static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t);
646 ///< Create uninitialized empty packet after\a packet
647 /**< This will create a completely empty and uninitialized
648 packet with <tt>size() == 0</tt>. It will be appended
649 as next header/interpreter after \a packet in that
650 packets interpreter chain.
651 \param[in] packet Packet to append new packet to.
652 \param[in] senf::noinit This parameter must always have
653 the value \c senf::noinit. */
654 static ConcretePacket createAfter(Packet const & packet, size_type size);
655 ///< Create default initialized packet after \a packet
656 /**< This member will create a default initialized packet
657 with the given size. If the size parameter is smaller
658 than the minimum allowed packet size an exception will
659 be thrown. It will be appended as next
660 header/interpreter after \a packet in that packets
662 \param[in] packet Packet to append new packet to.
663 \param[in] size Size of the packet to create in bytes.
664 \throws TruncatedPacketException if \a size is smaller
665 than the smallest permissible size for this type of
667 static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t);
668 ///< Create uninitialized packet after \a packet
669 /**< Creates an uninitialized (all-zero) packet of the exact
670 given size. It will be appended as next
671 header/interpreter after \a packet in that packets
673 \param[in] packet Packet to append new packet to.
674 \param[in] size Size of the packet to create in bytes
675 \param[in] senf::noinit This parameter must always have
676 the value \c senf::noinit. */
678 template <class ForwardReadableRange>
679 static ConcretePacket createAfter(
680 Packet const & packet,
681 ForwardReadableRange const & range,
682 typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
684 template <class ForwardReadableRange>
685 static ConcretePacket createAfter(Packet const & packet,
686 ForwardReadableRange const & range);
687 ///< Create packet from given data after \a packet
688 /**< The packet will be created from a copy of the given
689 data. The data from the range will be copied directly
690 into the packet representation. The data will \e not be
691 validated in any way. It will be appended as next
692 header/interpreter after \a packet in that packets
694 \param[in] packet Packet to append new packet to.
695 \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
696 of data to construct packet from. */
699 // Create packet as new packet (header) before a given packet
701 static ConcretePacket createBefore(Packet const & packet);
702 ///< Create default initialized packet before \a packet
703 /**< The packet will be initialized to it's default empty
704 state. It will be prepended as previous
705 header/interpreter before \a packet in that packets
707 \warning This constructor will destroy any existing
708 headers before \a packet and replace them with the
710 \param[in] packet Packet to prepend new packet to. */
711 static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t);
712 ///< Create uninitialized empty packet before \a packet
713 /**< Creates a completely empty and uninitialized packet. It
714 will be prepended as previous header/interpreter before
715 \a packet in that packets interpreter chain.
716 \warning This constructor will destroy any existing
717 headers before \a packet and replace them with the
719 \param[in] packet Packet to prepend new packet to. */
721 static ConcretePacket createInsertBefore(Packet const & packet);
722 ///< Insert default initialized packet before \a packet
723 /**< The new packet header will be initialized to it' s
724 default empty state. It will be inserted into the
725 packet chain before \a packet.
726 \param[in] packet Packet before which to insert the new
728 static ConcretePacket createInsertBefore(Packet const & packet, senf::NoInit_t);
729 ///< Insert uninitialized empty packet before \a packet
730 /**< Inserts a completely empty and uninitialized packet
731 before \a packet into the header/interpreter chain.
732 \param[in] packet Packet before which to insert the new
735 // Create a clone of the current packet
737 ConcretePacket clone() const;
740 //-////////////////////////////////////////////////////////////////////////
746 ParserProxy(Parser const & p) : p_ (p) {}
747 Parser * operator->() { return &p_; }
751 ParserProxy operator->() const; ///< Access packet fields
752 /**< This operator allows to access the parsed fields of the
753 packet using the notation <tt>packet->field()</tt>. The
754 fields of the packet are specified by the PacketType's
757 The members are not strictly restricted to simple field
758 access. The parser class may have any member which is
759 needed for full packet access (e.g. checksum validation
761 \see \ref packetparser for the %parser interface. */
763 Parser parser() const; ///< Access packet field parser directly
764 /**< Access the parser of the packet. This is the same
765 object returned by the operator->() operator. The
766 operator however does not allow to access this object
767 itself, only it's members.
768 \see \ref packetparser for the %parser interface */
773 typedef PacketInterpreter<PacketType> interpreter;
775 ConcretePacket(typename interpreter::ptr const & packet_);
777 interpreter * ptr() const;
780 friend class PacketInterpreter<PacketType>;
783 /** \brief Generic parser copying
785 This operator allows to copy the value of identical parsers. This operation does \e not
786 depend on the parsers detailed implementation, it will just replace the data bytes of the
787 target parser with those from the source packet.
789 template <class PacketType, class Parser>
790 Parser operator<<(Parser target, ConcretePacket<PacketType> const & packet);
796 //-/////////////////////////////////////////////////////////////////////////////////////////////////
798 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_Packet_i_)
799 #define HH_SENF_Packets_Packet_i_
800 #include "Packet.cci"
802 #include "Packet.cti"
809 // c-file-style: "senf"
810 // indent-tabs-mode: nil
811 // ispell-local-dictionary: "american"
812 // compile-command: "scons -u test"
813 // comment-column: 40