Fix SCons 1.2.0 build failure
[senf.git] / Packets / Packet.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief Packet public header */
25
26 #ifndef HH_SENF_Packets_Packet_
27 #define HH_SENF_Packets_Packet_ 1
28
29 // Custom includes
30 #include <boost/operators.hpp>
31 #include <boost/utility.hpp>
32 #include <boost/type_traits/is_integral.hpp>
33 #include "../Utils/Exception.hh"
34 #include "../Utils/Tags.hh"
35 #include "../Utils/safe_bool.hh"
36 #include "PacketInterpreter.hh"
37
38 //#include "Packet.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     /** \defgroup packet_module Packet Handling
44
45         The basic groundwork of the %Packet library is the packet handling:
46
47         \li The packet classes provide access to a chain of packet headers (more generically called
48             interpreters).
49         \li They automatically manage the required memory resources and the shared packet data.
50
51         \section packet_module_chain The Interpreter Chain
52
53         The central data structure for a packet is the interpreter chain
54
55         \image html structure.png The Interpreter Chain
56
57         This image depicts a packet with several headers. Each interpreter is responsible for a
58         specific sub-range of the complete packet. This range always \e includes the packets payload
59         (This is, why we call the data structure interpreter and not header: The interpreter is
60         responsible for interpreting a range of the packet according to a specific protocol), the
61         packet interpreters are nested inside each other.
62
63         For each interpreter, this structure automatically divides the packet into three areas (each
64         of which are optional): The header, the payload and the trailer. Every packet will have
65         either a header or a payload section while most don't have a trailer.
66
67         As user of the library you always interact with the chain through one (or more) of the
68         interpreters. The interpreter provides methods to traverse to the following or preceding
69         header (interpreter) and provides two levels of access to the packet data: Generic low-level
70         access in the form of an STL compatible sequence and access to the parsed fields which are
71         provided by the parser associated with the concrete packet type.
72
73         \section packet_module_management Resource Management
74
75         The interface to the packet library is provided using a handle class (\ref Packet for
76         generic, protocol agnostic access and \ref ConcretePacket derived from \ref Packet to access
77         a specific protocol). This handle automatically manages the resources associated with the
78         packet (the interpreter chain and the data storage holding the packet data). The resources
79         are automatically released when the last packet handle referencing a specific packet is
80         destroyed.
81
82         \implementation The packet chain is provided on two levels: The internal representation \ref
83             PacketInterpreterBase and \ref PacketInterpreter which are referenced by the Handle
84             classes \ref Packet and \ref ConcretePacket. \n
85             The internal representation classes are pertinent in the sense, that they exist
86             regardless of the existence of a handle referencing them (as long as the packet
87             exists). Still the interpreter chain is lazy and packet interpreters beside the first
88             are only created dynamically when accessed (this is implemented in the handle not in the
89             internal representation). \n
90             The packet interpreters make use of a pool allocator. This provides extremely efficient
91             creation and destruction of packet interpreter's and removes the dynamic memory
92             management overhead from the packet interpreter management. The packet implementation
93             class (\ref PacketImpl which holds the packet data itself) however is still dynamically
94             managed (however there is only a single instance for each packet).
95      */
96
97     template <class PackeType> class ConcretePacket;
98
99     ///\addtogroup packet_module
100     ///@{
101
102     /** \brief Main %Packet class
103
104         %Packet is the main externally visible class of the packet library. %Packet is a handle into
105         the internal packet representation. From %Packet you may access the data of that specific
106         sub-packet/header/interpreter and navigate to the neighboring
107         sub-packets/headers/interpreters.
108
109         %Packet is protocol agnostic. This class only provides non-protocol dependent members. To
110         access the protocol specific features of a packet (like header fields) the ConcretePacket
111         class extending %Packet is provided.
112
113         \section packet_semantics Semantics
114
115         All operations accessing the data of \c this packet in some way will ignore any preceding
116         packets/headers/interpreters in the chain. It does not matter, whether a given packet is
117         taken from the middle or the beginning of the chain, all operations (except those explicitly
118         accessing the chain of course) should work the same.
119
120         This especially includes members like clone() or append(): clone() will clone \e only from
121         \c this packet until the end of the chain, append() will append the given packet \e ignoring
122         any possibly preceding packets/headers/interpreters.
123
124         In the same way, the data() member provides an STL-sequence compatible view of the packet
125         data. This only includes the data which is part of \c this packet including header, trailer
126         \e and payload but \e not the headers or trailers of packets \e before \c this packet in the
127         packet/header/interpreter chain (nonetheless, this data overlaps with the data of other
128         packets).
129
130         Several members are member templates taking an \a OtherPacket template parameter. This
131         parameter must be the ConcretePacket instantiation associated with some concrete packet type
132         (protocol). For each implemented protocol, typedefs should be provided for these
133         instantiations (Example: \ref EthernetPacket is a typedef for
134         \ref ConcretePacket < \ref EthernetPacketType >).
135
136         \see
137             \ref ConcretePacket for the %type specific interface\n
138             \ref PacketData for the sequence interface\n
139             \ref packetparser for a specification of the parser interface
140      */
141     class Packet
142         : public safe_bool<Packet>,
143           public boost::equality_comparable<Packet>
144     {
145     public:
146         ///////////////////////////////////////////////////////////////////////////
147         // Types
148
149         typedef void type;              ///< Type of the packet.
150         typedef senf::detail::packet::size_type size_type;
151         ///< Unsigned type to represent packet size
152         typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
153
154         ///////////////////////////////////////////////////////////////////////////
155         ///\name Structors and default members
156         ///@{
157
158         // default copy constructor
159         // default copy assignment
160         // default destructor
161
162         Packet();                       ///< Create uninitialized packet handle
163                                         /**< An uninitialized handle is in - valid(). It does not
164                                              allow any operation except assignment and checking for
165                                              validity. */
166         Packet clone() const;           ///< Create copy packet
167                                         /**< clone() will create a complete copy of \c this
168                                              packet. The returned packet will have the same data and
169                                              packet chain. It does however not share any data with
170                                              the original packet. */
171
172         // conversion constructors
173
174         template <class PacketType>
175         Packet(ConcretePacket<PacketType> packet); ///< 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. */
179
180         ///@}
181         ///////////////////////////////////////////////////////////////////////////
182
183         ///\name Interpreter chain access
184         ///@{
185
186         Packet      next() const;
187         ///< Get next packet in chain
188         /**< \throws InvalidPacketChainException if no next packet
189              exists */
190         Packet      next(NoThrow_t) const;
191         ///< Get next packet in chain
192         /**< \returns in - valid() packet if no next packet
193              exists */
194         template <class OtherPacket> OtherPacket next() const;
195         ///< Get next packet in chain and cast to \a OtherPacket
196         /**< \throws std::bad_cast if the next() packet is not of
197              type \a OtherPacket
198              \throws InvalidPacketChainException if no next packet
199                  exists */
200         template <class OtherPacket> OtherPacket next(NoThrow_t) const;
201         ///< Get next packet in chain and cast to \a OtherPacket
202         /**< \throws std::bad_cast if the next() packet is not of
203              type \a OtherPacket
204              \returns in - valid() packet if no next packet
205                  exists */
206         template <class OtherPacket> OtherPacket find() const;
207         ///< Search chain forward for packet of type \a OtherPacket
208         /**< The search will start with the current packet.
209              \throws InvalidPacketChainException if no packet of
210                  type \a OtherPacket can be found. */
211         template <class OtherPacket> OtherPacket find(NoThrow_t) const;
212         ///< Search chain forward for packet of type \a OtherPacket
213         /**< The search will start with the current packet.
214              \returns in - valid() packet if no packet of type \a
215                  OtherPacket can be found. */
216
217         Packet      prev() const;
218         ///< Get previous packet in chain
219         /**< \throws InvalidPacketChainException if no previous
220              packet exists */
221         Packet      prev(NoThrow_t) const;
222         ///< Get previous packet in chain
223         /**< \returns in - valid() packet if no previous packet
224              exists */
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
228              type \a OtherPacket
229              \throws InvalidPacketChainException if no previous
230                  packet exists */
231         template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
232         ///< Get previous packet in chain and cast to \a OtherPacket
233         /**< \throws std::bad_cast, if the previous packet is not of
234              type \a OtherPacket
235              \returns in - valid() packet if no previous packet
236                  exists */
237         template <class OtherPacket> OtherPacket rfind() const;
238         ///< Search chain backwards for packet of type \a OtherPacket
239         /**< The search will start with the current packet.
240              \throws InvalidPacketChainException if no packet of
241                  type \a OtherPacket can be found. */
242         template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
243         ///< Search chain backwards for packet of type \a OtherPacket
244         /**< The search will start with the current packet.
245              \returns in - valid() packet if no packet of type \a
246                  OtherPacket can be found. */
247
248
249         Packet      first() const;
250         ///< Return first packet in chain
251         template <class OtherPacket> OtherPacket first() const;
252         ///< Return first packet in chain and cast
253         /**< \throws std::bad_cast if the first() packet is not of
254              type \a OtherPacket */
255
256         Packet      last() const;
257         ///< Return last packet in chain
258         template <class OtherPacket> OtherPacket last() const;
259         ///< Return last packet in chain and cast
260         /**< \throws std::bad_cast if the last() packet is not of
261              type \a OtherPacket  */
262
263
264         template <class OtherPacket> OtherPacket parseNextAs() const;
265         ///< Interpret payload of \c this as \a OtherPacket
266         /**< parseNextAs() will throw away the packet chain after
267              the current packet if necessary. It will then parse the
268              payload section of \c this packet as given by \a
269              OtherPacket. The new packet is added to the chain after
270              \c this.
271              \returns new packet instance sharing the same data and
272                  placed after \c this packet in the chain.
273              \throws InvalidPacketChainException if no next
274                  packet header is allowed (viz. nextPacketRange() of the the current
275                  PacketType returns no_range() ) */
276         Packet      parseNextAs(factory_t factory) const;
277         ///< Interpret payload of \c this as \a factory type packet
278         /**< parseNextAs() will throw away the packet chain after
279              the current packet if necessary. It will then parse the
280              payload section of \c this packet as given by \a
281              factory. The new packet is added to the chain after
282              \c this.
283              \returns new packet instance sharing the same data and
284                  placed after \c this packet in the chain.
285              \throws InvalidPacketChainException if no next
286                  packet header is allowed (viz. nextPacketRange() of the the current
287                  PacketType returns no_range() ) */
288
289         template <class OtherPacket> bool        is() const;
290         ///< Check, whether \c this packet is of the given type
291         template <class OtherPacket> OtherPacket as() 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 before.
296              \throws std::bad_cast if the current packet is not of
297                  type \a OtherPacket */
298
299         Packet append(Packet const & packet) const; ///< Append the given packet to \c this packet
300         /**< This operation will replace the payload section of \c
301              this packet with \a packet. This operation will replace
302              the packet chain after \c this packet with a clone of
303              \a packet and will replace the raw data of the payload
304              of \c this with the raw data of \a packet. \c this
305              packet will not share any date with \a packet.
306              \returns Packet handle to the cloned \a packet, placed
307                  after \c this in the packet/header/interpreter
308                  chain. */
309
310         ///@}
311
312         ///\name Data access
313         ///@{
314
315         PacketData & data() const;      ///< Access the packets raw data container
316         size_type size() const;         ///< Return size of packet in bytes
317                                         /**< This size does \e not include the size of any preceding
318                                              headers/packets/interpreters. It does however include
319                                              \c this packets payload. */
320
321         ///@}
322
323         ///\name Annotations
324         ///@{
325
326         template <class Annotation>
327         Annotation & annotation();      ///< Get packet annotation
328                                         /**< This member will retrieve an arbitrary packet
329                                              annotation. Every annotation is identified by a unique
330                                              \a Annotation type. This type should \e always be a \c
331                                              struct.
332
333                                              \code
334                                                  struct MyAnnotation {
335                                                  int value;
336                                                  };
337
338                                              senf::Packet p (...);
339
340                                              p.annotation<MyAnnotation>().value = 1;
341                                              \endcode
342
343                                              Annotations are shared by all headers / interpreters
344                                              within a single packet chain.
345
346                                              If an annotation is \e not a POD type (more
347                                              specifically, if it's constructor or destructor is not
348                                              trivial including base classes and members), the \a
349                                              Annotation type \e must inherit from
350                                              senf::ComplexAnnotation. Failing to follow this rule
351                                              will result in undefined behavior and will probably
352                                              lead to a program crash.
353
354                                              \code
355                                                  struct MyStringAnnotation : senf::ComplexAnnotation {
356                                                  std::string value;
357                                                  };
358                                              \endcode
359                                                  (This type is not POD since \c std::string is not POD)
360
361                                              \see \ref packet_usage_annotation
362
363                                              \implementation The annotation system is implemented
364                                                  quite efficiently since annotations are stored
365                                                  within a packet embedded vector of fixed size (the
366                                                  size is determined automatically at runtime by the
367                                                  number of different annotations
368                                                  used). Additionally, non-complex small annotations
369                                                  require no additional memory management (\c new /
370                                                  \c delete).
371
372                                              \idea Pool the annotation vectors: In the destructor
373                                                  swap the vector into a vector graveyard (swapping
374                                                  two vectors is an O(1) no allocation operation). In
375                                                  the constructor, if there is a vector in the
376                                                  graveyard, swap it in from there. Of course, it
377                                                  would be better to do away with the vector and just
378                                                  allocate the space together with the packet but
379                                                  that looks quite complicated to do ... especially
380                                                  considering that the packetimpl itself uses a pool.
381                                           */
382
383         ///@}
384
385         template <class Annotation>
386         Annotation const & annotation() const; ///< Get packet annotation
387                                         /**< \see annotation() */
388
389         ///\name Other methods
390         ///@{
391
392         bool operator==(Packet const & other) const; ///< Check for packet identity
393                                         /**< Two packet handles compare equal if they really are the
394                                              same packet header in the same packet chain. */
395         bool boolean_test() const;      ///< Check, whether the packet is valid()
396                                         /**< \see valid() */
397         bool valid() const;             ///< Check, whether the packet is valid()
398                                         /**< An in - valid() packet does not allow any operation
399                                              except checking for validity and assignment. in -
400                                              valid() packets serve the same role as 0-pointers.
401
402                                              This is an alias for boolean_test() which is called
403                                              when using a packet in a boolean context. */
404
405         void finalizeThis();            ///< Update calculated fields
406                                         /**< The finalize() fammily of members will update
407                                              calculated packet fields: checksums, size fields and so
408                                              on. This includes any field, which can be set from
409                                              other information in the packet. Each concrete packet
410                                              type should document, which fields are set by
411                                              finalize().
412
413                                              finalizeThis() will \e only process the current
414                                              header. Even if only changing fields in this protocol,
415                                              depending on the protocol it may not be enough to
416                                              finalize this header only. See the packet type
417                                              documentation. */
418
419         template <class Other>
420         void finalizeTo();              ///< Update calculated fields
421                                         /**< The finalize() fammily 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
426                                              finalize().
427
428                                              finalizeTo() will automatically process all
429                                              packets/headers/interpreters from the \e first
430                                              occurrence of packet type \a Other (beginning at \c
431                                              this packet searching forward towards deeper nested
432                                              packets) backwards up to \c this.
433
434                                              This call is equivalent to
435                                              \code
436                                                  p.finalizeTo(p.next<Other>())
437                                              \endcode */
438
439         void finalizeTo(Packet const & other);  ///< Update calculated fields
440                                         /**< The finalize() fammily of members will update
441                                              calculated packet fields: checksums, size fields and so
442                                              on. This includes any field, which can be set from
443                                              other information in the packet. Each concrete packet
444                                              type should document, which fields are set by
445                                              finalize().
446
447                                              finalizeTo(other) will automatically process all
448                                              packets/headers/interpreters beginning at \a other
449                                              backwards towards outer packets up to \c this. */
450
451         void finalizeAll();             ///< Update calculated fields
452                                         /**< The finalize() fammily of members will update
453                                              calculated packet fields: checksums, size fields and so
454                                              on. This includes any field, which can be set from
455                                              other information in the packet. Each concrete packet
456                                              type should document, which fields are set by
457                                              finalize().
458
459                                              finalizeAll() will automatically process all
460                                              packets/headers/interpreters from the end of the chain
461                                              (the most inner packet) backwards up to \c this.
462
463                                              This call is equivalent to
464                                              \code
465                                                  p.finalizeTo(p.last())
466                                              \endcode
467
468                                              Beware, that finalizeAll() will \e not finalize any
469                                              headers before \c this, it will \e only process inner
470                                              headers. */
471
472         void dump(std::ostream & os) const; ///< Write out a printable packet representation
473                                         /**< This method is provided mostly to help debugging packet
474                                              problems. Each concrete packet should implement a dump
475                                              method writing out all fields of the packet in a
476                                              readable representation. dump() will call this member
477                                              for each packet/header/interpreter in the chain from \c
478                                              this packet up to the end of the chain. */
479
480         TypeIdValue typeId() const;     ///< Get type of \c this packet
481                                         /**< This value is used e.g. in the packet registry to
482                                              associate packet types with other information.
483                                              \returns A type holding the same information as a
484                                              type_info object, albeit assignable */
485         factory_t factory() const;      ///< Return factory instance of \c this packet
486                                         /**< The returned factory instance can be used to create new
487                                              packets of the given type without knowing the concrete
488                                              type of the packet. The value may be stored away for
489                                              later use if needed. */
490
491         unsigned long id() const;       ///< Unique packet id
492                                         /**< Get a unique packet id. If two packets have the same
493                                              id, they share the internal data representation.. */
494
495         ///@}
496
497     protected:
498         explicit Packet(PacketInterpreterBase::ptr packet);
499
500         PacketInterpreterBase::ptr ptr() const;
501
502     private:
503         Packet checkNext() const;
504         Packet checkLast() const;
505
506         PacketInterpreterBase::ptr packet_;
507
508         template <class PacketType>
509         friend class ConcretePacket;
510         friend class PacketParserBase;
511     };
512
513     /** \brief Protocol specific packet handle
514
515         The ConcretePacket template class extends Packet to provide protocol/packet type specific
516         aspects. These are packet constructors and access to the parsed packet fields.
517
518         The \c PacketType template argument to ConcretePacket is a protocol specific and internal
519         policy class which defines the protocol specific behavior. To access a specific type of
520         packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
521         (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
522
523         The new members provided by ConcretePacket over packet are mostly comprised of the packet
524         constructors. These come in three major flavors:
525
526         \li The create() family of constructors will create completely new packets.
527         \li The createAfter() family of constructors will create new packets (with new data for the
528             packet) \e after a given existing packet.
529         \li The createBefore()  family of constructors will create new packets (again with new data)
530             \e before a given existing packet.
531
532         Whereas create() will create a completely new packet with it's own chain and data storage,
533         createAfter() and createBefore() extend a packet with additional
534         headers/interpreters. createAfter() will set the payload of the given packet to the new
535         packet whereas createBefore() will create a new packet with the existing packet as it's
536         payload.
537
538         createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
539         replacing any possibly existing data whereas the latter will interpret the already \e
540         existing data as given by the type argument.
541
542         \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
543             PacketType policy class.
544      */
545     template <class PacketType>
546     class ConcretePacket
547         : public Packet
548     {
549     public:
550         ///////////////////////////////////////////////////////////////////////////
551         // Types
552
553         typedef PacketType type;
554         typedef typename PacketType::parser Parser;
555
556         ///////////////////////////////////////////////////////////////////////////
557         ///\name Structors and default members
558         ///@{
559
560         // default copy constructor
561         // default copy assignment
562         // default destructor
563         // no conversion constructors
564
565         ConcretePacket();               ///< Create uninitialized packet handle
566         /**< An uninitialized handle is not valid(). It does not
567              allow any operation except assignment and checking for
568              validity. */
569
570         static factory_t factory();     ///< Return factory for packets of specific type
571         /**< This \e static member is like Packet::factory() for a
572              specific packet of type \a PacketType */
573
574         // Create completely new packet
575
576         static ConcretePacket create(); ///< Create default initialized packet
577         /**< The packet will be initialized to it's default empty
578              state. */
579         static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
580         /**< This will create a completely empty and uninitialized
581              packet with <tt>size() == 0</tt>.
582              \param[in] senf::noinit This parameter must always have the
583                  value \c senf::noinit. */
584         static ConcretePacket create(size_type size); ///< Create default initialized packet
585         /**< This member will create a default initialized packet
586              with the given size. If the size parameter is smaller
587              than the minimum allowed packet size an exception will
588              be thrown.
589              \param[in] size Size of the packet to create in bytes.
590              \throws TruncatedPacketException if \a size is smaller
591                  than the smallest permissible size for this type of
592                  packet. */
593         static ConcretePacket create(size_type size, senf::NoInit_t);
594         ///< Create uninitialized packet
595         /**< Creates an uninitialized (all-zero) packet of the exact
596              given size.
597              \param[in] size Size of the packet to create in bytes
598              \param[in] senf::noinit This parameter must always have the
599                  value \c senf::noinit. */
600 #ifndef DOXYGEN
601         template <class ForwardReadableRange>
602         static ConcretePacket create(
603             ForwardReadableRange const & range,
604             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
605 #else
606         template <class ForwardReadableRange>
607         static ConcretePacket create(ForwardReadableRange const & range);
608         ///< Create packet from given data
609         /**< The packet will be created from a copy of the given
610              data. The data from the range will be copied directly
611              into the packet representation. The data will \e not be
612              validated in any way.
613              \param[in] range <a
614                  href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
615                  of data to construct packet from. */
616 #endif
617
618         // Create packet as new packet after a given packet
619
620         static ConcretePacket createAfter(Packet const & packet);
621         ///< Create default initialized packet after \a packet
622         /**< The packet will be initialized to it's default empty
623              state. It will be appended as next header/interpreter
624              after \a packet in that packets interpreter chain.
625              \param[in] packet Packet to append new packet to. */
626         static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t);
627         ///< Create uninitialized empty packet after\a packet
628         /**< This will create a completely empty and uninitialized
629              packet with <tt>size() == 0</tt>. It will be appended
630              as next header/interpreter after \a packet in that
631              packets interpreter chain.
632              \param[in] packet Packet to append new packet to.
633              \param[in] senf::noinit This parameter must always have the
634                  value \c senf::noinit. */
635         static ConcretePacket createAfter(Packet const & packet, size_type size);
636         ///< Create default initialized packet after \a packet
637         /**< This member will create a default initialized packet
638              with the given size. If the size parameter is smaller
639              than the minimum allowed packet size an exception will
640              be thrown. It will be appended as next
641              header/interpreter after \a packet in that packets
642              interpreter chain.
643              \param[in] packet Packet to append new packet to.
644              \param[in] size Size of the packet to create in bytes.
645              \throws TruncatedPacketException if \a size is smaller
646                  than the smallest permissible size for this type of
647                  packet. */
648         static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t);
649         ///< Create uninitialized packet after \a packet
650         /**< Creates an uninitialized (all-zero) packet of the exact
651              given size.  It will be appended as next
652              header/interpreter after \a packet in that packets
653              interpreter chain.
654              \param[in] packet Packet to append new packet to.
655              \param[in] size Size of the packet to create in bytes
656              \param[in] senf::noinit This parameter must always have the
657                  value \c senf::noinit. */
658 #ifndef DOXYGEN
659         template <class ForwardReadableRange>
660         static ConcretePacket createAfter(
661             Packet const & packet,
662             ForwardReadableRange const & range,
663             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
664 #else
665         template <class ForwardReadableRange>
666         static ConcretePacket createAfter(Packet const & packet,
667                                           ForwardReadableRange const & range);
668         ///< Create packet from given data after \a packet
669         /**< The packet will be created from a copy of the given
670              data. The data from the range will be copied directly
671              into the packet representation. The data will \e not be
672              validated in any way.  It will be appended as next
673              header/interpreter after \a packet in that packets
674              interpreter chain.
675              \param[in] packet Packet to append new packet to.
676              \param[in] range <a
677                  href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
678                  of data to construct packet from. */
679 #endif
680
681         // Create packet as new packet (header) before a given packet
682
683         static ConcretePacket createBefore(Packet const & packet);
684         ///< Create default initialized packet before \a packet
685         /**< The packet will be initialized to it's default empty
686              state. It will be prepended as previous
687              header/interpreter before \a packet in that packets
688              interpreter chain.
689              \param[in] packet Packet to prepend new packet to. */
690         static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t);
691         ///< Create uninitialized empty packet before \a packet
692         /**< Creates a completely empty and uninitialized packet. It
693              will be prepended as previous header/interpreter before
694              \a packet in that packets interpreter chain.
695              \param[in] packet Packet to prepend new packet to. */
696
697         // Create a clone of the current packet
698
699         ConcretePacket clone() const;
700
701         ///@}
702         ///////////////////////////////////////////////////////////////////////////
703
704         // Field access
705
706         struct ParserProxy
707         {
708             ParserProxy(Parser const & p) : p_ (p) {}
709             Parser * operator->() { return &p_; }
710             Parser p_;
711         };
712
713         ParserProxy operator->() const;    ///< Access packet fields
714                                         /**< This operator allows to access the parsed fields of the
715                                              packet using the notation <tt>packet->field()</tt>. The
716                                              fields of the packet are specified by the PacketType's
717                                              \c parser member.
718
719                                              The members are not strictly restricted to simple field
720                                              access. The parser class may have any member which is
721                                              needed for full packet access (e.g. checksum validation
722                                              / recreation ...)
723                                              \see \ref packetparser for the parser interface. */
724
725         Parser parser() const;          ///< Access packet field parser directly
726                                         /**< Access the parser of the packet. This is the same
727                                              object returned by the operator->() operator. The
728                                              operator however does not allow to access this object
729                                              itself, only it's members.
730                                              \see \ref packetparser for the parser interface */
731
732     protected:
733
734     private:
735         typedef PacketInterpreter<PacketType> interpreter;
736
737         ConcretePacket(typename interpreter::ptr packet_);
738
739         typename interpreter::ptr ptr() const;
740
741         friend class Packet;
742         friend class PacketInterpreter<PacketType>;
743     };
744
745     /** \brief Generic parser copying
746
747         This operator allows to copy the value of identical parsers. This operation does \e not
748         depend on the parsers detailed implementation, it will just replace the data bytes of the
749         target parser with those from the source packet.
750      */
751     template <class PacketType, class Parser>
752     Parser operator<<(Parser target, ConcretePacket<PacketType> const & packet);
753
754     ///@}
755
756 }
757
758 ///////////////////////////////hh.e////////////////////////////////////////
759 #endif
760 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_Packet_i_)
761 #define HH_SENF_Packets_Packet_i_
762 #include "Packet.cci"
763 #include "Packet.ct"
764 #include "Packet.cti"
765 #endif
766
767
768 // Local Variables:
769 // mode: c++
770 // fill-column: 100
771 // c-file-style: "senf"
772 // indent-tabs-mode: nil
773 // ispell-local-dictionary: "american"
774 // compile-command: "scons -u test"
775 // comment-column: 40
776 // End:
777