4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief Packet public header */
31 #ifndef HH_SENF_Packets_Packet_
32 #define HH_SENF_Packets_Packet_ 1
35 #include <boost/operators.hpp>
36 #include <boost/utility.hpp>
37 #include <boost/type_traits/is_integral.hpp>
38 #include <senf/Utils/Tags.hh>
39 #include <senf/Utils/safe_bool.hh>
40 #include "PacketInterpreter.hh"
42 //#include "Packet.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 /** \defgroup packet_module Packet Handling
49 The basic groundwork of the %Packet library is the packet handling:
51 \li The packet classes provide access to a chain of packet headers (more generically called
53 \li They automatically manage the required memory resources and the shared packet data.
55 \section packet_module_chain The Interpreter Chain
57 The central data structure for a packet is the interpreter chain
59 \image html structure.png The Interpreter Chain
61 This image depicts a packet with several headers. Each interpreter is responsible for a
62 specific sub-range of the complete packet. This range always \e includes the packets payload
63 (This is, why we call the data structure interpreter and not header: The interpreter is
64 responsible for interpreting a range of the packet according to a specific protocol), the
65 packet interpreters are nested inside each other.
67 For each interpreter, this structure automatically divides the packet into three areas (each
68 of which are optional): The header, the payload and the trailer. Every packet will have
69 either a header or a payload section while most don't have a trailer.
71 As user of the library you always interact with the chain through one (or more) of the
72 interpreters. The interpreter provides methods to traverse to the following or preceding
73 header (interpreter) and provides two levels of access to the packet data: Generic low-level
74 access in the form of an STL compatible sequence and access to the parsed fields which are
75 provided by the parser associated with the concrete packet type.
77 \section packet_module_management Resource Management
79 The interface to the packet library is provided using a handle class (\ref Packet for
80 generic, protocol agnostic access and \ref ConcretePacket derived from \ref Packet to access
81 a specific protocol). This handle automatically manages the resources associated with the
82 packet (the interpreter chain and the data storage holding the packet data). The resources
83 are automatically released when the last packet handle referencing a specific packet is
86 \implementation The packet chain is provided on two levels: The internal representation \ref
87 PacketInterpreterBase and \ref PacketInterpreter which are referenced by the Handle
88 classes \ref Packet and \ref ConcretePacket. \n
89 The internal representation classes are pertinent in the sense, that they exist
90 regardless of the existence of a handle referencing them (as long as the packet
91 exists). Still the interpreter chain is lazy and packet interpreters beside the first
92 are only created dynamically when accessed (this is implemented in the handle not in the
93 internal representation). \n
94 The packet interpreters make use of a pool allocator. This provides extremely efficient
95 creation and destruction of packet interpreter's and removes the dynamic memory
96 management overhead from the packet interpreter management. The packet implementation
97 class (\ref PacketImpl which holds the packet data itself) however is still dynamically
98 managed (however there is only a single instance for each packet).
101 template <class PackeType> class ConcretePacket;
103 ///\addtogroup packet_module
106 /** \brief Main %Packet class
108 %Packet is the main externally visible class of the packet library. %Packet is a handle into
109 the internal packet representation. From %Packet you may access the data of that specific
110 sub-packet/header/interpreter and navigate to the neighboring
111 sub-packets/headers/interpreters.
113 %Packet is protocol agnostic. This class only provides non-protocol dependent members. To
114 access the protocol specific features of a packet (like header fields) the ConcretePacket
115 class extending %Packet is provided.
117 \section packet_semantics Semantics
119 All operations accessing the data of \c this packet in some way will ignore any preceding
120 packets/headers/interpreters in the chain. It does not matter, whether a given packet is
121 taken from the middle or the beginning of the chain, all operations (except those explicitly
122 accessing the chain of course) should work the same.
124 This especially includes members like clone() or append(): clone() will clone \e only from
125 \c this packet until the end of the chain, append() will append the given packet \e ignoring
126 any possibly preceding packets/headers/interpreters.
128 In the same way, the data() member provides an STL-sequence compatible view of the packet
129 data. This only includes the data which is part of \c this packet including header, trailer
130 \e and payload but \e not the headers or trailers of packets \e before \c this packet in the
131 packet/header/interpreter chain (nonetheless, this data overlaps with the data of other
134 Several members are member templates taking an \a OtherPacket template parameter. This
135 parameter must be the ConcretePacket instantiation associated with some concrete packet type
136 (protocol). For each implemented protocol, typedefs should be provided for these
137 instantiations (Example: \ref EthernetPacket is a typedef for
138 \ref ConcretePacket < \ref EthernetPacketType >).
141 \ref ConcretePacket for the %type specific interface\n
142 \ref PacketData for the sequence interface\n
143 \ref packetparser for a specification of the parser interface
146 : public safe_bool<Packet>,
147 public boost::equality_comparable<Packet>
150 //-////////////////////////////////////////////////////////////////////////
153 typedef void type; ///< Type of the packet.
154 typedef senf::detail::packet::size_type size_type;
155 ///< Unsigned type to represent packet size
156 typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
158 //-////////////////////////////////////////////////////////////////////////
159 ///\name Structors and default members
162 // default copy constructor
163 // default copy assignment
164 // default destructor
166 Packet(); ///< Create uninitialized packet handle
167 /**< An uninitialized handle is in - valid(). It does not
168 allow any operation except assignment and checking for
170 Packet clone() const; ///< Create copy packet
171 /**< clone() will create a complete copy of \c this
172 packet. The returned packet will have the same data,
173 annotations and packet chain. It does however not
174 share any data with the original packet. */
176 // conversion constructors
178 template <class PacketType>
179 Packet(ConcretePacket<PacketType> const & packet);
180 ///< Copy-construct Packet from ConcretePacket
181 /**< This constructor allows to convert an arbitrary
182 ConcretePacket into a general Packet, loosing the
183 protocol specific interface. */
186 //-////////////////////////////////////////////////////////////////////////
188 ///\name Interpreter chain access
191 Packet next() const; ///< Get next packet in chain
192 /**< \throws InvalidPacketChainException if no next packet
194 Packet next(NoThrow_t) const; ///< Get next packet in chain
195 /**< \returns in - valid() packet if no next packet
197 template <class OtherPacket> OtherPacket next() const;
198 ///< Get next packet in chain and cast to \a OtherPacket
199 /**< \throws std::bad_cast if the next() packet is not of
201 \throws InvalidPacketChainException if no next packet
203 template <class OtherPacket> OtherPacket next(NoThrow_t) const;
204 ///< Get next packet in chain and cast to \a OtherPacket
205 /**< \returns in - valid() packet if no next packet
206 exists or if next() packet is not of
207 type \a OtherPacket */
208 template <class OtherPacket> OtherPacket find() const;
209 ///< Search chain forward for packet of type \a OtherPacket
210 /**< The search will start with the current packet.
211 \throws InvalidPacketChainException if no packet of
212 type \a OtherPacket can be found. */
213 template <class OtherPacket> OtherPacket find(NoThrow_t) const;
214 ///< Search chain forward for packet of type \a OtherPacket
215 /**< The search will start with the current packet.
216 \returns in - valid() packet if no packet of type \a
217 OtherPacket can be found. */
219 Packet prev() const; ///< Get previous packet in chain
220 /**< \throws InvalidPacketChainException if no previous
222 Packet prev(NoThrow_t) const; ///< Get previous packet in chain
223 /**< \returns in - valid() packet if no previous packet
225 template <class OtherPacket> OtherPacket prev() const;
226 ///< Get previous packet in chain and cast to \a OtherPacket
227 /**< \throws std::bad_cast, if the previous packet is not of
229 \throws InvalidPacketChainException if no previous
231 template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
232 ///< Get previous packet in chain and cast to \a OtherPacket
233 /**< \returns in - valid() packet if no previous packet
234 exists or if the previous packet is not of
235 type \a OtherPacket */
236 template <class OtherPacket> OtherPacket rfind() const;
237 ///< Search chain backwards for packet of type \a OtherPacket
238 /**< The search will start with the current packet.
239 \throws InvalidPacketChainException if no packet of
240 type \a OtherPacket can be found. */
241 template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
242 ///< Search chain backwards for packet of type \a OtherPacket
243 /**< The search will start with the current packet.
244 \returns in - valid() packet if no packet of type \a
245 OtherPacket can be found. */
248 Packet first() const; ///< Return first packet in chain
249 template <class OtherPacket> OtherPacket first() const;
250 ///< Return first packet in chain and cast
251 /**< \throws std::bad_cast if the first() packet is not of
252 type \a OtherPacket */
254 Packet last() const; ///< Return last packet in chain
255 template <class OtherPacket> OtherPacket last() const;
256 ///< Return last packet in chain and cast
257 /**< \throws std::bad_cast if the last() packet is not of
258 type \a OtherPacket */
261 template <class OtherPacket> OtherPacket parseNextAs() const;
262 ///< Interpret payload of \c this as \a OtherPacket
263 /**< parseNextAs() will throw away the packet chain after
264 the current packet if necessary. It will then parse the
265 payload section of \c this packet as given by \a
266 OtherPacket. The new packet is added to the chain after
268 \returns new packet instance sharing the same data and
269 placed after \c this packet in the chain.
270 \throws InvalidPacketChainException if no next packet
271 header is allowed (viz. nextPacketRange() of the
272 the current PacketType returns no_range() ) */
273 Packet parseNextAs(factory_t factory) const;
274 ///< Interpret payload of \c this as \a factory type packet
275 /**< parseNextAs() will throw away the packet chain after
276 the current packet if necessary. It will then parse the
277 payload section of \c this packet as given by \a
278 factory. The new packet is added to the chain after
280 \returns new packet instance sharing the same data and
281 placed after \c this packet in the chain.
282 \throws InvalidPacketChainException if no next packet
283 header is allowed (viz. nextPacketRange() of the
284 the current PacketType returns no_range() ) */
286 template <class OtherPacket> bool is() const;
287 ///< Check, whether \c this packet is of the given type
288 template <class OtherPacket> OtherPacket as() const;
289 ///< Cast current packet to the given type
290 /**< This operations returns a handle to the same packet
291 header/interpreter however upcast to the given
292 ConcretePacket type which have been instantiated
294 \throws std::bad_cast if the current packet is not of
295 type \a OtherPacket */
296 template <class OtherPacket> OtherPacket as(NoThrow_t) const;
297 ///< Cast current packet to the given type
298 /**< This operations returns a handle to the same packet
299 header/interpreter however upcast to the given
300 ConcretePacket type which have been instantiated
302 \warning You must make absolutely sure that the packet
303 is of the given type. If not, calling this member
304 crashes your program in a unkindly way. */
306 Packet append(Packet const & packet) const; ///< Append the given packet to \c this packet
307 /**< This operation will replace the payload section of \c
308 this packet with \a packet. This operation will replace
309 the packet chain after \c this packet with a clone of
310 \a packet and will replace the raw data of the payload
311 of \c this with the raw data of \a packet. \c this
312 packet will not share any data with \a packet.
313 \returns Packet handle to the cloned \a packet, placed
314 after \c this in the packet/header/interpreter
317 void reparse() const; ///< Reparse the payload the packet
318 /**< This member will throw away the packet chain after the
319 current packet. The payload will be reparsed
320 automatically when calling next() */
326 PacketData & data() const; ///< Access the packets raw data container
327 size_type size() const; ///< Return size of packet in bytes
328 /**< This size does \e not include the size of any preceding
329 headers/packets/interpreters. It does however include
330 \c this packets payload. */
336 template <class Annotation>
337 Annotation & annotation(); ///< Get packet annotation
338 /**< This member will retrieve an arbitrary packet
339 annotation. Every annotation is identified by a unique
340 \a Annotation type. This type should \e always be a \c
344 struct MyAnnotation {
348 senf::Packet p (...);
350 p.annotation<MyAnnotation>().value = 1;
353 Annotations are shared by all headers / interpreters
354 within a single packet chain.
356 If an annotation is \e not a POD type (more
357 specifically, if it's constructor or destructor is not
358 trivial including base classes and members), the \a
359 Annotation type \e must inherit from
360 senf::ComplexAnnotation. Failing to follow this rule
361 will result in undefined behavior and will probably
362 lead to a program crash.
365 struct MyStringAnnotation : senf::ComplexAnnotation {
369 (This type is not POD since \c std::string is not POD)
371 \see \ref packet_usage_annotation
373 \implementation The annotation system is implemented
374 quite efficiently since annotations are stored
375 within a packet embedded vector of fixed size (the
376 size is determined automatically at runtime by the
377 number of different annotations
378 used). Additionally, non-complex small annotations
379 require no additional memory management (\c new /
382 \idea Pool the annotation vectors: In the destructor
383 swap the vector into a vector graveyard (swapping
384 two vectors is an O(1) no allocation operation). In
385 the constructor, if there is a vector in the
386 graveyard, swap it in from there. Of course, it
387 would be better to do away with the vector and just
388 allocate the space together with the packet but
389 that looks quite complicated to do ... especially
390 considering that the packetimpl itself uses a pool.
393 template <class Annotation>
394 Annotation const & annotation() const; ///< Get packet annotation
395 /**< \see annotation() */
397 void clearAnnotations(); ///< Clear all packet annotations
398 /**< All packet annotations will be cleared. Afterwards
399 the annotations equates to a new created %packet.
400 \warning all references to existing complex
401 annotations become invalid. */
404 ///\name Other methods
407 bool operator==(Packet const & other) const; ///< Check for packet identity
408 /**< Two packet handles compare equal if they really are the
409 same packet header in the same packet chain. */
410 bool boolean_test() const; ///< Check, whether the packet is valid()
412 bool valid() const; ///< Check, whether the packet is valid()
413 /**< An in - valid() packet does not allow any operation
414 except checking for validity and assignment. in -
415 valid() packets serve the same role as 0-pointers.
417 This is an alias for boolean_test() which is called
418 when using a packet in a boolean context. */
420 void finalizeThis(); ///< Update calculated fields
421 /**< The finalize() family of members will update
422 calculated packet fields: checksums, size fields and so
423 on. This includes any field, which can be set from
424 other information in the packet. Each concrete packet
425 type should document, which fields are set by
428 finalizeThis() will \e only process the current
429 header. Even if only changing fields in this protocol,
430 depending on the protocol it may not be enough to
431 finalize this header only. See the packet type
434 template <class Other>
435 void finalizeTo(); ///< Update calculated fields
436 /**< The finalize() family of members will update
437 calculated packet fields: checksums, size fields and so
438 on. This includes any field, which can be set from
439 other information in the packet. Each concrete packet
440 type should document, which fields are set by
443 finalizeTo() will automatically process all
444 packets/headers/interpreters from the \e first
445 occurrence of packet type \a Other (beginning at \c
446 this packet searching forward towards deeper nested
447 packets) backwards up to \c this.
449 This call is equivalent to
451 p.finalizeTo(p.next<Other>())
454 void finalizeTo(Packet const & other); ///< Update calculated fields
455 /**< The finalize() family of members will update
456 calculated packet fields: checksums, size fields and so
457 on. This includes any field, which can be set from
458 other information in the packet. Each concrete packet
459 type should document, which fields are set by
462 finalizeTo(other) will automatically process all
463 packets/headers/interpreters beginning at \a other
464 backwards towards outer packets up to \c this. */
466 void finalizeAll(); ///< Update calculated fields
467 /**< The finalize() family of members will update
468 calculated packet fields: checksums, size fields and so
469 on. This includes any field, which can be set from
470 other information in the packet. Each concrete packet
471 type should document, which fields are set by
474 finalizeAll() will automatically process all
475 packets/headers/interpreters from the end of the chain
476 (the most inner packet) backwards up to \c this.
478 This call is equivalent to
480 p.finalizeTo(p.last())
483 Beware, that finalizeAll() will \e not finalize any
484 headers before \c this, it will \e only process inner
487 void dump(std::ostream & os) const; ///< Write out a printable packet representation
488 /**< This method is provided mostly to help debugging packet
489 problems. Each concrete packet should implement a dump
490 method writing out all fields of the packet in a
491 readable representation. dump() will call this member
492 for each packet/header/interpreter in the chain from \c
493 this packet up to the end of the chain. */
495 TypeIdValue typeId() const; ///< Get type of \c this packet
496 /**< This value is used e.g. in the packet registry to
497 associate packet types with other information.
498 \returns A type holding the same information as a
499 type_info object, albeit assignable */
500 factory_t factory() const; ///< Return factory instance of \c this packet
501 /**< The returned factory instance can be used to create new
502 packets of the given type without knowing the concrete
503 type of the packet. The value may be stored away for
504 later use if needed. */
506 unsigned long id() const; ///< Unique packet id
507 /**< Get a unique packet id. If two packets have the same
508 id, they share the internal data representation. */
510 bool is_shared() const; ///< check if this packet shares data with any another packet handle.
511 /**< This method returns true if there is any other packet
512 handle pointing to any header in the packet chain. */
517 explicit Packet(PacketInterpreterBase::ptr const & packet);
519 PacketInterpreterBase::ptr const & ptr() const;
521 PacketInterpreterBase::ptr parseNextAs(factory_t factory, PacketInterpreterBase::optional_range const & range) const;
522 PacketInterpreterBase::ptr getNext(PacketInterpreterBase::optional_range const & range) const;
523 Packet getLast() const;
526 PacketInterpreterBase::ptr packet_;
528 template <class PacketType>
529 friend class ConcretePacket;
530 friend class PacketParserBase;
533 /** \brief Protocol specific packet handle
535 The ConcretePacket template class extends Packet to provide protocol/packet type specific
536 aspects. These are packet constructors and access to the parsed packet fields.
538 The \c PacketType template argument to ConcretePacket is a protocol specific and internal
539 policy class which defines the protocol specific behavior. To access a specific type of
540 packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
541 (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
543 The new members provided by ConcretePacket over packet are mostly comprised of the packet
544 constructors. These come in three major flavors:
546 \li The create() family of constructors will create completely new packets.
547 \li The createAfter() family of constructors will create new packets (with new data for the
548 packet) \e after a given existing packet <em>thereby destroying and overwriting any
549 possibly existing packets and data after the given packet</em>.
550 \li The createBefore() family of constructors will create new packets (again with new data)
551 \e before a given existing packet <em>thereby destroying and overwriting any possibly
552 existing packets and data before the given packet</em>.
553 \li The createInsertBefore() family of constructors will create new packets \e before a
554 given packet \e inserting them into the packet chain after any existing packets before
557 Whereas create() will create a completely new packet with it's own chain and data storage,
558 createAfter(), createBefore() and createInsertBefore() extend a packet with additional
559 headers/interpreters. createAfter() will set the payload of the given packet to the new
560 packet whereas createBefore() and createInsertBefore() will create a new packet with the
561 existing packet as it's payload.
563 createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
564 replacing any possibly existing data whereas the latter will interpret the already \e
565 existing data as given by the type argument.
567 \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
568 PacketType policy class.
570 template <class PacketType>
575 //-////////////////////////////////////////////////////////////////////////
578 typedef PacketType type;
579 typedef typename PacketType::parser Parser;
581 //-////////////////////////////////////////////////////////////////////////
582 ///\name Structors and default members
585 // default copy constructor
586 // default copy assignment
587 // default destructor
588 // no conversion constructors
590 ConcretePacket(); ///< Create uninitialized packet handle
591 /**< An uninitialized handle is not valid(). It does not
592 allow any operation except assignment and checking for
595 static factory_t factory(); ///< Return factory for packets of specific type
596 /**< This \e static member is like Packet::factory() for a
597 specific packet of type \a PacketType */
599 // Create completely new packet
601 static ConcretePacket create(); ///< Create default initialized packet
602 /**< The packet will be initialized to it's default empty
604 static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
605 /**< This will create a completely empty and uninitialized
606 packet with <tt>size() == 0</tt>.
607 \param[in] senf::noinit This parameter must always have
608 the value \c senf::noinit. */
609 static ConcretePacket create(size_type size); ///< Create default initialized packet
610 /**< This member will create a default initialized packet
611 with the given size. If the size parameter is smaller
612 than the minimum allowed packet size an exception will
614 \param[in] size Size of the packet to create in bytes.
615 \throws TruncatedPacketException if \a size is smaller
616 than the smallest permissible size for this type of
618 static ConcretePacket create(size_type size, senf::NoInit_t);
619 ///< Create uninitialized packet
620 /**< Creates an uninitialized (all-zero) packet of the exact
622 \param[in] size Size of the packet to create in bytes
623 \param[in] senf::noinit This parameter must always have
624 the value \c senf::noinit. */
626 template <class ForwardReadableRange>
627 static ConcretePacket create(
628 ForwardReadableRange const & range,
629 typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
631 template <class ForwardReadableRange>
632 static ConcretePacket create(ForwardReadableRange const & range);
633 ///< Create packet from given data
634 /**< The packet will be created from a copy of the given
635 data. The data from the range will be copied directly
636 into the packet representation. The data will \e not be
637 validated in any way.
639 \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
640 of data to construct packet from. */
643 // Create packet as new packet after a given packet
645 static ConcretePacket createAfter(Packet const & packet);
646 ///< Create default initialized packet after \a packet
647 /**< The packet will be initialized to it's default empty
648 state. It will be appended as next header/interpreter
649 after \a packet in that packets interpreter chain.
650 \param[in] packet Packet to append new packet to. */
651 static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t);
652 ///< Create uninitialized empty packet after\a packet
653 /**< This will create a completely empty and uninitialized
654 packet with <tt>size() == 0</tt>. It will be appended
655 as next header/interpreter after \a packet in that
656 packets interpreter chain.
657 \param[in] packet Packet to append new packet to.
658 \param[in] senf::noinit This parameter must always have
659 the value \c senf::noinit. */
660 static ConcretePacket createAfter(Packet const & packet, size_type size);
661 ///< Create default initialized packet after \a packet
662 /**< This member will create a default initialized packet
663 with the given size. If the size parameter is smaller
664 than the minimum allowed packet size an exception will
665 be thrown. It will be appended as next
666 header/interpreter after \a packet in that packets
668 \param[in] packet Packet to append new packet to.
669 \param[in] size Size of the packet to create in bytes.
670 \throws TruncatedPacketException if \a size is smaller
671 than the smallest permissible size for this type of
673 static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t);
674 ///< Create uninitialized packet after \a packet
675 /**< Creates an uninitialized (all-zero) packet of the exact
676 given size. It will be appended as next
677 header/interpreter after \a packet in that packets
679 \param[in] packet Packet to append new packet to.
680 \param[in] size Size of the packet to create in bytes
681 \param[in] senf::noinit This parameter must always have
682 the value \c senf::noinit. */
684 template <class ForwardReadableRange>
685 static ConcretePacket createAfter(
686 Packet const & packet,
687 ForwardReadableRange const & range,
688 typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
690 template <class ForwardReadableRange>
691 static ConcretePacket createAfter(Packet const & packet,
692 ForwardReadableRange const & range);
693 ///< Create packet from given data after \a packet
694 /**< The packet will be created from a copy of the given
695 data. The data from the range will be copied directly
696 into the packet representation. The data will \e not be
697 validated in any way. It will be appended as next
698 header/interpreter after \a packet in that packets
700 \param[in] packet Packet to append new packet to.
701 \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
702 of data to construct packet from. */
705 // Create packet as new packet (header) before a given packet
707 static ConcretePacket createBefore(Packet const & packet);
708 ///< Create default initialized packet before \a packet
709 /**< The packet will be initialized to it's default empty
710 state. It will be prepended as previous
711 header/interpreter before \a packet in that packets
713 \warning This constructor will destroy any existing
714 headers before \a packet and replace them with the
716 \param[in] packet Packet to prepend new packet to. */
717 static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t);
718 ///< Create uninitialized empty packet before \a packet
719 /**< Creates a completely empty and uninitialized packet. It
720 will be prepended as previous header/interpreter before
721 \a packet in that packets interpreter chain.
722 \warning This constructor will destroy any existing
723 headers before \a packet and replace them with the
725 \param[in] packet Packet to prepend new packet to. */
727 static ConcretePacket createInsertBefore(Packet const & packet);
728 ///< Insert default initialized packet before \a packet
729 /**< The new packet header will be initialized to it' s
730 default empty state. It will be inserted into the
731 packet chain before \a packet.
732 \param[in] packet Packet before which to insert the new
734 static ConcretePacket createInsertBefore(Packet const & packet, senf::NoInit_t);
735 ///< Insert uninitialized empty packet before \a packet
736 /**< Inserts a completely empty and uninitialized packet
737 before \a packet into the header/interpreter chain.
738 \param[in] packet Packet before which to insert the new
741 // Create a clone of the current packet
743 ConcretePacket clone() const;
746 //-////////////////////////////////////////////////////////////////////////
752 ParserProxy(Parser const & p) : p_ (p) {}
753 Parser * operator->() { return &p_; }
757 ParserProxy operator->() const; ///< Access packet fields
758 /**< This operator allows to access the parsed fields of the
759 packet using the notation <tt>packet->field()</tt>. The
760 fields of the packet are specified by the PacketType's
763 The members are not strictly restricted to simple field
764 access. The parser class may have any member which is
765 needed for full packet access (e.g. checksum validation
767 \see \ref packetparser for the %parser interface. */
769 Parser parser() const; ///< Access packet field parser directly
770 /**< Access the parser of the packet. This is the same
771 object returned by the operator->() operator. The
772 operator however does not allow to access this object
773 itself, only it's members.
774 \see \ref packetparser for the %parser interface */
779 Packet next(NoThrow_t) const;
780 template <class OtherPacket>
781 OtherPacket next(NoThrow_t) const;
785 typedef PacketInterpreter<PacketType> interpreter;
787 ConcretePacket(typename interpreter::ptr const & packet_);
789 interpreter * ptr() const;
792 friend class PacketInterpreter<PacketType>;
793 template<class PType> friend class ConcretePacket;
796 /** \brief Generic parser copying
798 This operator allows to copy the value of identical parsers. This operation does \e not
799 depend on the parsers detailed implementation, it will just replace the data bytes of the
800 target parser with those from the source packet.
802 template <class PacketType, class Parser>
803 Parser operator<<(Parser target, ConcretePacket<PacketType> const & packet);
809 //-/////////////////////////////////////////////////////////////////////////////////////////////////
811 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_Packet_i_)
812 #define HH_SENF_Packets_Packet_i_
813 #include "Packet.cci"
815 #include "Packet.cti"
822 // c-file-style: "senf"
823 // indent-tabs-mode: nil
824 // ispell-local-dictionary: "american"
825 // compile-command: "scons -u test"
826 // comment-column: 40