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