switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / Packet.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
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
10 //
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.
14 //
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.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
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.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Packet public header */
30
31 #ifndef HH_SENF_Packets_Packet_
32 #define HH_SENF_Packets_Packet_ 1
33
34 // Custom includes
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"
41
42 //#include "Packet.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 namespace senf {
46
47     /** \defgroup packet_module Packet Handling
48
49         The basic groundwork of the %Packet library is the packet handling:
50
51         \li The packet classes provide access to a chain of packet headers (more generically called
52             interpreters).
53         \li They automatically manage the required memory resources and the shared packet data.
54
55         \section packet_module_chain The Interpreter Chain
56
57         The central data structure for a packet is the interpreter chain
58
59         \image html structure.png The Interpreter Chain
60
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.
66
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.
70
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.
76
77         \section packet_module_management Resource Management
78
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
84         destroyed.
85
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).
99      */
100
101     template <class PackeType> class ConcretePacket;
102
103     ///\addtogroup packet_module
104     //\{
105
106     /** \brief Main %Packet class
107
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.
112
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.
116
117         \section packet_semantics Semantics
118
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.
123
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.
127
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
132         packets).
133
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 >).
139
140         \see
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
144      */
145     class Packet
146         : public safe_bool<Packet>,
147           public boost::equality_comparable<Packet>
148     {
149     public:
150         //-////////////////////////////////////////////////////////////////////////
151         // Types
152
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)
157
158         //-////////////////////////////////////////////////////////////////////////
159         ///\name Structors and default members
160         //\{
161
162         // default copy constructor
163         // default copy assignment
164         // default destructor
165
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
169                                              validity. */
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. */
175
176         // conversion constructors
177
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. */
184
185         //\}
186         //-////////////////////////////////////////////////////////////////////////
187
188         ///\name Interpreter chain access
189         //\{
190
191         Packet      next() const;       ///< Get next packet in chain
192                                         /**< \throws InvalidPacketChainException if no next packet
193                                              exists */
194         Packet      next(NoThrow_t) const; ///< Get next packet in chain
195                                         /**< \returns in - valid() packet if no next packet
196                                              exists */
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
200                                              type \a OtherPacket
201                                              \throws InvalidPacketChainException if no next packet
202                                                  exists */
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. */
218
219         Packet      prev() const;       ///< Get previous packet in chain
220                                         /**< \throws InvalidPacketChainException if no previous
221                                              packet exists */
222         Packet      prev(NoThrow_t) const; ///< 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                                         /**< \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. */
246
247
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 */
253
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  */
259
260
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
267                                              \c this.
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
279                                              \c this.
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() ) */
285
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
293                                              before.
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
301                                              before.
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. */
305
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
315                                                  chain. */
316
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() */
321         //\}
322
323         ///\name Data access
324         //\{
325
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. */
331         //\}
332
333         ///\name Annotations
334         //\{
335
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
341                                              struct.
342
343                                              \code
344                                              struct MyAnnotation {
345                                                  int value;
346                                              };
347
348                                              senf::Packet p (...);
349
350                                              p.annotation<MyAnnotation>().value = 1;
351                                              \endcode
352
353                                              Annotations are shared by all headers / interpreters
354                                              within a single packet chain.
355
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.
363
364                                              \code
365                                              struct MyStringAnnotation : senf::ComplexAnnotation {
366                                                  std::string value;
367                                              };
368                                              \endcode
369                                              (This type is not POD since \c std::string is not POD)
370
371                                              \see \ref packet_usage_annotation
372
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 /
380                                                  \c delete).
381
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.
391                                           */
392
393         template <class Annotation>
394         Annotation const & annotation() const; ///< Get packet annotation
395                                         /**< \see annotation() */
396
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. */
402         //\}
403
404         ///\name Other methods
405         //\{
406
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()
411                                         /**< \see 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.
416
417                                              This is an alias for boolean_test() which is called
418                                              when using a packet in a boolean context. */
419
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
426                                              finalize().
427
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
432                                              documentation. */
433
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
441                                              finalize().
442
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.
448
449                                              This call is equivalent to
450                                              \code
451                                                  p.finalizeTo(p.next<Other>())
452                                              \endcode */
453
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
460                                              finalize().
461
462                                              finalizeTo(other) will automatically process all
463                                              packets/headers/interpreters beginning at \a other
464                                              backwards towards outer packets up to \c this. */
465
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
472                                              finalize().
473
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.
477
478                                              This call is equivalent to
479                                              \code
480                                                  p.finalizeTo(p.last())
481                                              \endcode
482
483                                              Beware, that finalizeAll() will \e not finalize any
484                                              headers before \c this, it will \e only process inner
485                                              headers. */
486
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. */
494
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. */
505
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. */
509
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. */
513
514         //\}
515
516     protected:
517         explicit Packet(PacketInterpreterBase::ptr const & packet);
518
519         PacketInterpreterBase::ptr const & ptr() const;
520
521     private:
522         Packet getNext() const;
523         Packet getLast() const;
524
525         PacketInterpreterBase::ptr packet_;
526
527         template <class PacketType>
528         friend class ConcretePacket;
529         friend class PacketParserBase;
530     };
531
532     /** \brief Protocol specific packet handle
533
534         The ConcretePacket template class extends Packet to provide protocol/packet type specific
535         aspects. These are packet constructors and access to the parsed packet fields.
536
537         The \c PacketType template argument to ConcretePacket is a protocol specific and internal
538         policy class which defines the protocol specific behavior. To access a specific type of
539         packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
540         (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
541
542         The new members provided by ConcretePacket over packet are mostly comprised of the packet
543         constructors. These come in three major flavors:
544
545         \li The create() family of constructors will create completely new packets.
546         \li The createAfter() family of constructors will create new packets (with new data for the
547             packet) \e after a given existing packet <em>thereby destroying and overwriting  any
548             possibly existing packets and data after the given packet</em>.
549         \li The createBefore() family of constructors will create new packets (again with new data)
550             \e before a given existing packet <em>thereby destroying and overwriting any possibly
551             existing packets and data before the given packet</em>.
552         \li The createInsertBefore() family of constructors will create new packets \e before a
553             given packet \e inserting them into the packet chain after any existing packets before
554             the given packet.
555
556         Whereas create() will create a completely new packet with it's own chain and data storage,
557         createAfter(), createBefore() and createInsertBefore() extend a packet with additional
558         headers/interpreters. createAfter() will set the payload of the given packet to the new
559         packet whereas createBefore() and createInsertBefore() will create a new packet with the
560         existing packet as it's payload.
561
562         createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
563         replacing any possibly existing data whereas the latter will interpret the already \e
564         existing data as given by the type argument.
565
566         \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
567             PacketType policy class.
568      */
569     template <class PacketType>
570     class ConcretePacket
571         : public Packet
572     {
573     public:
574         //-////////////////////////////////////////////////////////////////////////
575         // Types
576
577         typedef PacketType type;
578         typedef typename PacketType::parser Parser;
579
580         //-////////////////////////////////////////////////////////////////////////
581         ///\name Structors and default members
582         //\{
583
584         // default copy constructor
585         // default copy assignment
586         // default destructor
587         // no conversion constructors
588
589         ConcretePacket();               ///< Create uninitialized packet handle
590                                         /**< An uninitialized handle is not valid(). It does not
591                                              allow any operation except assignment and checking for
592                                              validity. */
593
594         static factory_t factory();     ///< Return factory for packets of specific type
595                                         /**< This \e static member is like Packet::factory() for a
596                                              specific packet of type \a PacketType */
597
598         // Create completely new packet
599
600         static ConcretePacket create(); ///< Create default initialized packet
601                                         /**< The packet will be initialized to it's default empty
602                                              state. */
603         static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
604                                         /**< This will create a completely empty and uninitialized
605                                              packet with <tt>size() == 0</tt>.
606                                              \param[in] senf::noinit This parameter must always have
607                                                  the value \c senf::noinit. */
608         static ConcretePacket create(size_type size); ///< Create default initialized packet
609                                         /**< This member will create a default initialized packet
610                                              with the given size. If the size parameter is smaller
611                                              than the minimum allowed packet size an exception will
612                                              be thrown.
613                                              \param[in] size Size of the packet to create in bytes.
614                                              \throws TruncatedPacketException if \a size is smaller
615                                                  than the smallest permissible size for this type of
616                                                  packet. */
617         static ConcretePacket create(size_type size, senf::NoInit_t);
618                                         ///< Create uninitialized packet
619                                         /**< Creates an uninitialized (all-zero) packet of the exact
620                                              given size.
621                                              \param[in] size Size of the packet to create in bytes
622                                              \param[in] senf::noinit This parameter must always have
623                                                  the value \c senf::noinit. */
624 #ifndef DOXYGEN
625         template <class ForwardReadableRange>
626         static ConcretePacket create(
627             ForwardReadableRange const & range,
628             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
629 #else
630         template <class ForwardReadableRange>
631         static ConcretePacket create(ForwardReadableRange const & range);
632                                         ///< Create packet from given data
633                                         /**< The packet will be created from a copy of the given
634                                              data. The data from the range will be copied directly
635                                              into the packet representation. The data will \e not be
636                                              validated in any way.
637
638                                              \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
639                                                  of data to construct packet from. */
640 #endif
641
642         // Create packet as new packet after a given packet
643
644         static ConcretePacket createAfter(Packet const & packet);
645                                         ///< Create default initialized packet after \a packet
646                                         /**< The packet will be initialized to it's default empty
647                                              state. It will be appended as next header/interpreter
648                                              after \a packet in that packets interpreter chain.
649                                              \param[in] packet Packet to append new packet to. */
650         static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t);
651                                         ///< Create uninitialized empty packet after\a packet
652                                         /**< This will create a completely empty and uninitialized
653                                              packet with <tt>size() == 0</tt>. It will be appended
654                                              as next header/interpreter after \a packet in that
655                                              packets interpreter chain.
656                                              \param[in] packet Packet to append new packet to.
657                                              \param[in] senf::noinit This parameter must always have
658                                                  the value \c senf::noinit. */
659         static ConcretePacket createAfter(Packet const & packet, size_type size);
660                                         ///< Create default initialized packet after \a packet
661                                         /**< This member will create a default initialized packet
662                                              with the given size. If the size parameter is smaller
663                                              than the minimum allowed packet size an exception will
664                                              be thrown. It will be appended as next
665                                              header/interpreter after \a packet in that packets
666                                              interpreter chain.
667                                              \param[in] packet Packet to append new packet to.
668                                              \param[in] size Size of the packet to create in bytes.
669                                              \throws TruncatedPacketException if \a size is smaller
670                                                  than the smallest permissible size for this type of
671                                                  packet. */
672         static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t);
673                                         ///< Create uninitialized packet after \a packet
674                                         /**< Creates an uninitialized (all-zero) packet of the exact
675                                              given size.  It will be appended as next
676                                              header/interpreter after \a packet in that packets
677                                              interpreter chain.
678                                              \param[in] packet Packet to append new packet to.
679                                              \param[in] size Size of the packet to create in bytes
680                                              \param[in] senf::noinit This parameter must always have
681                                                  the value \c senf::noinit. */
682 #ifndef DOXYGEN
683         template <class ForwardReadableRange>
684         static ConcretePacket createAfter(
685             Packet const & packet,
686             ForwardReadableRange const & range,
687             typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
688 #else
689         template <class ForwardReadableRange>
690         static ConcretePacket createAfter(Packet const & packet,
691                                           ForwardReadableRange const & range);
692                                         ///< Create packet from given data after \a packet
693                                         /**< The packet will be created from a copy of the given
694                                              data. The data from the range will be copied directly
695                                              into the packet representation. The data will \e not be
696                                              validated in any way.  It will be appended as next
697                                              header/interpreter after \a packet in that packets
698                                              interpreter chain.
699                                              \param[in] packet Packet to append new packet to.
700                                              \param[in] range <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a>
701                                                  of data to construct packet from. */
702 #endif
703
704         // Create packet as new packet (header) before a given packet
705
706         static ConcretePacket createBefore(Packet const & packet);
707                                         ///< Create default initialized packet before \a packet
708                                         /**< The packet will be initialized to it's default empty
709                                              state. It will be prepended as previous
710                                              header/interpreter before \a packet in that packets
711                                              interpreter chain.
712                                              \warning This constructor will destroy any existing
713                                                  headers before \a packet and replace them with the
714                                                  new header.
715                                              \param[in] packet Packet to prepend new packet to. */
716         static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t);
717                                         ///< Create uninitialized empty packet before \a packet
718                                         /**< Creates a completely empty and uninitialized packet. It
719                                              will be prepended as previous header/interpreter before
720                                              \a packet in that packets interpreter chain.
721                                              \warning This constructor will destroy any existing
722                                                  headers before \a packet and replace them with the
723                                                  new header.
724                                              \param[in] packet Packet to prepend new packet to. */
725
726         static ConcretePacket createInsertBefore(Packet const & packet);
727                                         ///< Insert default initialized packet before \a packet
728                                         /**< The new packet header will be initialized to it' s
729                                              default empty state. It will be inserted into the
730                                              packet chain before \a packet.
731                                              \param[in] packet Packet before which to insert the new
732                                                  packet */
733         static ConcretePacket createInsertBefore(Packet const & packet, senf::NoInit_t);
734                                         ///< Insert uninitialized empty packet before \a packet
735                                         /**< Inserts a completely empty and uninitialized packet
736                                              before \a packet into the header/interpreter chain.
737                                              \param[in] packet Packet before which to insert the new
738                                                  packet */
739
740         // Create a clone of the current packet
741
742         ConcretePacket clone() const;
743
744         //\}
745         //-////////////////////////////////////////////////////////////////////////
746
747         // Field access
748
749         struct ParserProxy
750         {
751             ParserProxy(Parser const & p) : p_ (p) {}
752             Parser * operator->() { return &p_; }
753             Parser p_;
754         };
755
756         ParserProxy operator->() const;    ///< Access packet fields
757                                         /**< This operator allows to access the parsed fields of the
758                                              packet using the notation <tt>packet->field()</tt>. The
759                                              fields of the packet are specified by the PacketType's
760                                              \c parser member.
761
762                                              The members are not strictly restricted to simple field
763                                              access. The parser class may have any member which is
764                                              needed for full packet access (e.g. checksum validation
765                                              / recreation ...)
766                                              \see \ref packetparser for the %parser interface. */
767
768         Parser parser() const;          ///< Access packet field parser directly
769                                         /**< Access the parser of the packet. This is the same
770                                              object returned by the operator->() operator. The
771                                              operator however does not allow to access this object
772                                              itself, only it's members.
773                                              \see \ref packetparser for the %parser interface */
774
775     protected:
776
777     private:
778         typedef PacketInterpreter<PacketType> interpreter;
779
780         ConcretePacket(typename interpreter::ptr const & packet_);
781
782         interpreter * ptr() const;
783
784         friend class Packet;
785         friend class PacketInterpreter<PacketType>;
786     };
787
788     /** \brief Generic parser copying
789
790         This operator allows to copy the value of identical parsers. This operation does \e not
791         depend on the parsers detailed implementation, it will just replace the data bytes of the
792         target parser with those from the source packet.
793      */
794     template <class PacketType, class Parser>
795     Parser operator<<(Parser target, ConcretePacket<PacketType> const & packet);
796
797     //\}
798
799 }
800
801 //-/////////////////////////////////////////////////////////////////////////////////////////////////
802 #endif
803 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_Packet_i_)
804 #define HH_SENF_Packets_Packet_i_
805 #include "Packet.cci"
806 #include "Packet.ct"
807 #include "Packet.cti"
808 #endif
809
810 \f
811 // Local Variables:
812 // mode: c++
813 // fill-column: 100
814 // c-file-style: "senf"
815 // indent-tabs-mode: nil
816 // ispell-local-dictionary: "american"
817 // compile-command: "scons -u test"
818 // comment-column: 40
819 // End:
820