Utils: Revamp documentation overview and add some missing docs
[senf.git] / Packets / Packet.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief Packet public header */
23
24 #ifndef HH_Packet_
25 #define HH_Packet_ 1
26
27 // Custom includes
28 #include <boost/operators.hpp>
29
30 #include "../Utils/Exception.hh"
31 #include "../Utils/safe_bool.hh"
32 #include "PacketInterpreter.hh"
33
34 //#include "Packet.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
36
37 namespace senf {
38
39     /** \defgroup packet_module Packet Handling
40
41         The basic groundwork of the Packet library is the packet handling:
42
43         \li The packet classes provide access to a chain of packet headers (more generically called
44             interpreters).
45         \li They automatically manage the required memory resources and the shared packet data.
46
47         \section packet_module_chain The Interpreter Chain
48
49         The central data structure for a packet is the interpreter chain
50
51         \image html structure.png The Interpreter Chain
52
53         This image depicts a packet with several headers. Each interpreter is responsible for a
54         specific sub-range of the complete packet. This range always \e includes the packets payload
55         (This is, why we call the data structure interpreter and not header: The interpreter is
56         responsible for interpreting a range of the packet according to a specific protocol), the
57         packet interpreters are nested inside each other.
58     
59         For each interpreter, this structure automatically divides the packet into three areas (each
60         of which are optional): The header, the payload and the trailer. Every packet will have
61         either a header or a payload section while most don't have a trailer.
62
63         As user of the library you always interact with the chain through one (or more) of the
64         interpreters. The interpreter provides methods to traverse to the following or preceding
65         header (interpreter) and provides two levels of access to the packet data: Generic low-level
66         access in the form of an STL compatible sequence and access to the parsed fields which are
67         provided by the parser associated with the concrete packet type.
68
69         \section packet_module_management Resource Management
70
71         The interface to the packet library is provided using a handle class (\ref Packet for
72         generic, protocol agnostic access and \ref ConcretePacket derived from \ref Packet to access
73         a specific protocol). This handle automatically manages the resources associated with the
74         packet (the interpreter chain and the data storage holding the packet data). The resources
75         are automatically released when the last packet handle referencing a specific packet is
76         destroyed.
77
78         \implementation The packet chain is provided on two levels: The internal representation \ref
79             PacketInterpreterBase and \ref PacketInterpreter which are referenced by the Handle
80             classes \ref Packet and \ref ConcretePacket. \n
81             The internal representation classes are pertinent in the sense, that they exist
82             regardless of the existence of a handle referencing them (as long as the packet
83             exists). Still the interpreter chain is lazy and packet interpreters beside the first
84             are only created dynamically when accessed (this is implemented in the handle not in the
85             internal representation). \n
86             The packet interpreters make use of a pool allocator. This provides extremely efficient
87             creation and destruction of packet interpreter's and removes the dynamic memory
88             management overhead from the packet interpreter management. The packet implementation
89             class (\ref PacketImpl which holds the packet data itself) however is still dynamically
90             managed (however there is only a single instance for each packet).
91      */
92
93     template <class PackeType> class ConcretePacket;
94
95     ///\addtogroup packet_module
96     ///@{
97     
98     /** \brief Main Packet class
99
100         Packet is the main externally visible class of the packet library. Packet is a handle into
101         the internal packet representation. From Packet you may access the data of that specific
102         sub-packet/header/interpreter and navigate to the neighboring
103         sub-packets/headers/interpreters.
104
105         Packet is protocol agnostic. This class only provides non-protocol dependent members. To
106         access the protocol specific features of a packet (like header fields) the ConcretePacket
107         class extending Packet is provided.
108
109         \section packet_semantics Semantics
110         
111         All operations accessing the data of \c this packet in some way will ignore any preceding
112         packets/headers/interpreters in the chain. It does not matter, whether a given packet is
113         taken from the middle or the beginning of the chain, all operations (except those explicitly
114         accessing the chain of course) should work the same.
115         
116         This especially includes members like clone() or append(): clone() will clone \e only from
117         \c this packet until the end of the chain, append() will append the given packet \e ignoring
118         any possibly preceding packets/headers/interpreters.
119
120         In the same way, the data() member provides an STL-sequence compatible view of the packet
121         data. This only includes the data which is part of \c this packet including header, trailer
122         \e and payload but \e not the headers or trailers of packets \e before \c this packet in the
123         packet/header/interpreter chain (nonetheless, this data overlaps with the data of other
124         packets).
125
126         Several members are member templates taking an \a OtherPacket template parameter. This
127         parameter must be the ConcretePacket instantiation associated with some concrete packet type
128         (protocol). For each implemented protocol, typedefs should be provided for these
129         instantiations (Example: \ref EthernetPacket is a typedef for
130         \ref ConcretePacket < \ref EthernetPacketType >).
131
132         \see 
133             \ref ConcretePacket for the type specific interface\n
134             \ref PacketData for the sequence interface\n
135             \ref packetparser for a specification of the parser interface
136       */
137     class Packet
138         : public safe_bool<Packet>,
139           public boost::equality_comparable<Packet>
140     {
141     public:
142         ///////////////////////////////////////////////////////////////////////////
143         // Types
144         
145         typedef void type;              ///< Type of the packet.
146         typedef senf::detail::packet::size_type size_type; ///< Unsigned type to represent packet size
147         typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
148
149                                         /// Special argument flag
150                                         /** Used in some ConcretePacket constructors */
151         enum NoInit_t { noinit };       
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 not 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 the packet. The
167                                              returned packet will have the same data and packet
168                                              chain. It does however not share any data with the
169                                              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                                         /**< \returns in - valid() packet, if no next packet 
188                                              exists */
189         template <class OtherPacket> OtherPacket next() const; 
190                                         ///< Get next packet of given type in chain
191                                         /**< \throws InvalidPacketChainException if no such packet
192                                              is found */
193         template <class OtherPacket> OtherPacket next(NoThrow_t) const; 
194                                         ///< Get next packet of given type in chain
195                                         /**< \param[in] nothrow This argument always has the value
196                                              \c senf::nothrow
197                                              \returns in - valid() packet, if no such packet is
198                                              found */
199         template <class OtherPacket> OtherPacket findNext() const;
200                                         ///< Find next packet of given type in chain
201                                         /**< findNext() is like next(), it will however return \c
202                                              *this if it is of the given type. 
203                                              \throws InvalidPacketChainException if no such packet
204                                                  is found */
205         template <class OtherPacket> OtherPacket findNext(NoThrow_t) const;
206                                         ///< Find next packet of given type in chain
207                                         /**< findNext() is like next(), it will however return \c
208                                              *this if it is of the given type.
209                                              \param[in] nothrow This argument always has the value
210                                              \c senf::nothrow
211                                              \returns in - valid() packet, if no such packet is
212                                              found */
213         
214
215                                      Packet      prev() const; 
216                                         ///< Get previous packet in chain
217                                         /**< \returns in - valid() packet, if no previous packet 
218                                              exists */
219         template <class OtherPacket> OtherPacket prev() const; 
220                                         ///< Get previous packet of given type in chain
221                                         /**< \throws InvalidPacketChainException if no such packet
222                                              is found */
223         template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
224                                         ///< Get previous packet of given type in chain
225                                         /**< \param[in] nothrow This argument always has the value
226                                              \c senf::nothrow
227                                              \returns in - valid() packet, if no such packet is
228                                              found */
229         template <class OtherPacket> OtherPacket findPrev() const;
230                                         ///< Find previous packet of given type in chain
231                                         /**< findPrev() is like prev(), it will however return \c
232                                              *this if it is of the type 
233                                              \throws InvalidPacketChainException if no such packet
234                                                  is found */
235         template <class OtherPacket> OtherPacket findPrev(NoThrow_t) const;
236                                         ///< Find previous packet of given type in chain
237                                         /**< findPrev() is like prev(), it will however return \c
238                                              *this if it is of the type 
239                                              \param[in] nothrow This argument always has the value
240                                              \c senf::nothrow
241                                              \returns in - valid() packet, if no such packet is
242                                              found */
243
244
245                                      Packet      first() const;
246                                         ///< Return first packet in chain
247         template <class OtherPacket> OtherPacket first() const;
248                                         ///< Return first packet of given type in chain
249                                         /**< \throws InvalidPacketChainException if no such packet
250                                              is found */
251         template <class OtherPacket> OtherPacket first(NoThrow_t) const;
252                                         ///< Return first packet of given type in chain
253                                         /**< \param[in] nothrow This argument always has the value
254                                              \c senf::nothrow
255                                              \returns in - valid() packet, if no such packet is
256                                              found */
257
258                                      Packet      last() const;
259                                         ///< Return last packet in chain
260         template <class OtherPacket> OtherPacket last() const;
261                                         ///< Return last packet of given type in chain
262                                         /**< \throws InvalidPacketChainException if no such packet
263                                              is found */
264         template <class OtherPacket> OtherPacket last(NoThrow_t) const;
265                                         ///< Return last packet of given type in chain
266                                         /**< \param[in] nothrow This argument always has the value
267                                              \c senf::nothrow
268                                              \returns in - valid() packet, if no such packet is
269                                              found */
270
271
272         template <class OtherPacket> OtherPacket parseNextAs() const;
273                                         ///< Parse payload as given by \a OtherPacket and add packet
274                                         /**< parseNextAs() will throw away the packet chain after
275                                              the current packet if necessary. It will then parse the
276                                              payload section of \c this packet as given by \a
277                                              OtherPacket. The new packet is added to the chain after
278                                              \c this.
279                                              \returns new packet instance sharing the same data and
280                                                  placed after \c this packet in the chain. */
281                                      Packet      parseNextAs(factory_t factory) const;
282                                         ///< Parse payload as given by \a factory and add packet
283                                         /**< parseNextAs() will throw away the packet chain after
284                                              the current packet if necessary. It will then parse the
285                                              payload section of \c this packet as given by \a
286                                              OtherPacket. The new packet is added to the chain after
287                                              \c this.
288                                              \returns new packet instance sharing the same data and
289                                                  placed after \c this packet in the chain. */
290         template <class OtherPacket> bool        is() const;
291                                         ///< Check, whether \c this packet is of the given type
292         template <class OtherPacket> OtherPacket as() const;
293                                         ///< Cast current packet to the given type
294                                         /**< This operations returns a handle to the same packet
295                                              header/interpreter however cast to the given
296                                              ConcretePacket type. <b>This conversion is
297                                              unchecked</b>. If the packet really is of a different
298                                              type, this will wreak havoc with the packet
299                                              data-structures. You can validate whether the
300                                              conversion is valid using is(). */
301
302         Packet append(Packet packet) const; ///< Append the given packet to \c this packet
303                                         /**< This operation will replace the payload section of \c
304                                              this packet with \a packet. This operation will replace
305                                              the packet chain after \c this packet with a clone of
306                                              \a packet and will replace the raw data of the payload
307                                              of \c this with the raw data if \a packet.
308                                              \returns Packet handle to the cloned \a packet, placed
309                                                  after \c this in the packet/header/interpreter
310                                                  chain. */
311
312         ///@}
313
314         ///\name Data access
315         ///@{
316
317         PacketData & data() const;      ///< Access the packets raw data container
318         size_type size() const;         ///< Return size of packet in bytes
319                                         /**< This size does \e not include the size of any preceding
320                                              headers/packets/interpreters. It does however include
321                                              \c this packets payload. */
322         
323         ///@}
324
325         ///\name Other methods
326         ///@{
327
328         bool operator==(Packet other) const; ///< Check for packet identity
329                                         /**< Two packet handles compare equal if they really are the
330                                              same packet header in the same packet chain. */
331         bool boolean_test() const;      ///< Check, whether the packet is valid()
332                                         /**< \see valid() */
333         bool valid() const;             ///< Check, whether the packet is valid()
334                                         /**< An in - valid() packet does not allow any operation
335                                              except checking for validity and assignment. in -
336                                              valid() packets serve the same role as 0-pointers. 
337                                              
338                                              This is an alias for boolean_test() which is called
339                                              when using a packet in a boolean context. */
340
341         void finalize() const;          ///< Update calculated fields
342                                         /**< This call will update all calculated fields of the
343                                              packet after it has been created or changed. This
344                                              includes checksums, payload size fields or other
345                                              fields, which can be set from other information in the
346                                              packet. Each concrete packet type should document,
347                                              which fields are set by finalize().
348
349                                              finalize() will automatically process all
350                                              packets/headers/interpreters from the end of the chain
351                                              backwards up to \c this. */
352
353         void dump(std::ostream & os) const; ///< Write out a printable packet representation
354                                         /**< This method is provided mostly to help debugging packet
355                                              problems. Each concrete packet should implement a dump
356                                              method writing out all fields of the packet in a
357                                              readable representation. dump() will call this member
358                                              for each packet/header/interpreter in the chain from \c
359                                              this packet up to the end of the chain. */
360
361         TypeIdValue typeId() const;     ///< Get id of \c this packet
362                                         /**< This value is used e.g. in the packet registry to
363                                              associate packet types with other information.
364                                              \returns A type holding the same information as a
365                                                  type_info object, albeit assignable */
366         factory_t factory() const;      ///< Return factory instance of \c this packet
367                                         /**< The returned factory instance can be used to create new
368                                              packets of the given type without knowing the concrete
369                                              type of the packet. The value may be stored away for
370                                              later use if needed. */
371         
372         ///@}
373
374     protected:
375         explicit Packet(PacketInterpreterBase::ptr packet);
376
377         PacketInterpreterBase::ptr ptr() const;
378
379     private:
380         Packet checkNext() const;
381         Packet checkLast() const;
382         
383         PacketInterpreterBase::ptr packet_;
384         
385         template <class PacketType>
386         friend class ConcretePacket;
387         friend class PacketParserBase;
388     };
389
390     /** \brief Protocol specific packet handle
391
392         The ConcretePacket template class extends Packet to provide protocol/packet type specific
393         aspects. These are packet constructors and access to the parsed packet fields.
394
395         The \c PacketType template argument to ConcretePacket is a protocol specific and internal
396         policy class which defines the protocol specific behavior. To access a specific type of
397         packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
398         (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
399
400         The new members provided by ConcretePacket over packet are mostly comprised of the packet
401         constructors. These come in three major flavors:
402         
403         \li The create() family of constructors will create completely new packets.
404         \li The createAfter() family of constructors will create new packets (with new data for the
405             packet) \e after a given existing packet.
406         \li The createBefore()  family of constructors will create new packets (again with new data)
407             \e before a given existing packet.
408         
409         Whereas create() will create a completely new packet with it's own chain and data storage,
410         createAfter() and createBefore() extend a packet with additional
411         headers/interpreters. createAfter() will set the payload of the given packet to the new
412         packet whereas createBefore() will create a new packet with the existing packet as it's
413         payload. 
414
415         createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
416         replacing any possibly existing data whereas the latter will interpret the already \e
417         existing data as given by the type argument.
418         
419         \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
420             PacketType policy class.
421       */
422     template <class PacketType>
423     class ConcretePacket 
424         : public Packet
425     {
426     public:
427         ///////////////////////////////////////////////////////////////////////////
428         // Types
429         
430         typedef PacketType type;
431
432         ///////////////////////////////////////////////////////////////////////////
433         ///\name Structors and default members
434         ///@{
435
436         // default copy constructor
437         // default copy assignment
438         // default destructor
439         // no conversion constructors
440
441         ConcretePacket();               ///< Create uninitialized packet handle
442                                         /**< An uninitialized handle is not valid(). It does not
443                                              allow any operation except assignment and checking for
444                                              validity. */
445
446         static factory_t factory();     ///< Return factory for packets of specific type
447                                         /**< This \e static member is like Packet::factory() for a
448                                              specific packet of type \a PacketType */
449
450         // Create completely new packet
451
452         static ConcretePacket create(); ///< Create default initialized packet
453                                         /**< The packet will be initialized to it's default empty
454                                              state. */
455         static ConcretePacket create(NoInit_t); ///< Create uninitialized empty packet
456                                         /**< This will create a completely empty and uninitialized
457                                              packet with <tt>size() == 0</tt>.
458                                              \param[in] noinit This parameter must always have the
459                                                  value \c senf::noinit. */
460         static ConcretePacket create(size_type size); ///< Create default initialized packet
461                                         /**< This member will create a default initialized packet
462                                              with the given size. If the size parameter is smaller
463                                              than the minimum allowed packet size an exception will
464                                              be thrown.
465                                              \param[in] size Size of the packet to create in bytes.
466                                              \throws TruncatedPacketException if \a size is smaller
467                                                  than the smallest permissible size for this type of
468                                                  packet. */
469         static ConcretePacket create(size_type size, NoInit_t); ///< Create uninitialized packet
470                                         /**< Creates an uninitialized (all-zero) packet of the exact
471                                              given size. 
472                                              \param[in] size Size of the packet to create in bytes
473                                              \param[in] noinit This parameter must always have the
474                                                  value \c senf::noinit. */
475         template <class ForwardReadableRange>
476         static ConcretePacket create(ForwardReadableRange const & range); 
477                                         ///< Create packet from given data
478                                         /**< The packet will be created from a copy of the given
479                                              data. The data from the range will be copied directly
480                                              into the packet representation. The data will \e not be
481                                              validated in any way.
482                                              \param[in] range <a
483                                                  href="http://www.boost.org/libs/range/index.html">Boost.Range</a> 
484                                                  of data to construct packet from. */
485
486         // Create packet as new packet after a given packet
487
488         static ConcretePacket createAfter(Packet packet); 
489                                         ///< Create default initialized packet after \a packet
490                                         /**< The packet will be initialized to it's default empty
491                                              state. It will be appended as next header/interpreter
492                                              after \a packet in that packets interpreter chain.
493                                              \param[in] packet Packet to append new packet to. */
494         static ConcretePacket createAfter(Packet packet, NoInit_t);
495                                         ///< Create uninitialized empty packet after\a packet
496                                         /**< This will create a completely empty and uninitialized
497                                              packet with <tt>size() == 0</tt>. It will be appended
498                                              as next header/interpreter after \a packet in that
499                                              packets interpreter chain.
500                                              \param[in] packet Packet to append new packet to.
501                                              \param[in] noinit This parameter must always have the
502                                                  value \c senf::noinit. */
503         static ConcretePacket createAfter(Packet packet, size_type size);
504                                         ///< Create default initialized packet after \a packet
505                                         /**< This member will create a default initialized packet
506                                              with the given size. If the size parameter is smaller
507                                              than the minimum allowed packet size an exception will
508                                              be thrown. It will be appended as next
509                                              header/interpreter after \a packet in that packets
510                                              interpreter chain.
511                                              \param[in] packet Packet to append new packet to.
512                                              \param[in] size Size of the packet to create in bytes.
513                                              \throws TruncatedPacketException if \a size is smaller
514                                                  than the smallest permissible size for this type of
515                                                  packet. */
516         static ConcretePacket createAfter(Packet packet, size_type size, NoInit_t);
517                                         ///< Create uninitialized packet after \a packet
518                                         /**< Creates an uninitialized (all-zero) packet of the exact
519                                              given size.  It will be appended as next
520                                              header/interpreter after \a packet in that packets
521                                              interpreter chain.
522                                              \param[in] packet Packet to append new packet to.
523                                              \param[in] size Size of the packet to create in bytes
524                                              \param[in] noinit This parameter must always have the
525                                                  value \c senf::noinit. */
526         template <class ForwardReadableRange>
527         static ConcretePacket createAfter(Packet packet, 
528                                           ForwardReadableRange const & range);
529                                         ///< Create packet from given data after \a packet
530                                         /**< The packet will be created from a copy of the given
531                                              data. The data from the range will be copied directly
532                                              into the packet representation. The data will \e not be
533                                              validated in any way.  It will be appended as next
534                                              header/interpreter after \a packet in that packets
535                                              interpreter chain.
536                                              \param[in] packet Packet to append new packet to.
537                                              \param[in] range <a
538                                                  href="http://www.boost.org/libs/range/index.html">Boost.Range</a> 
539                                                  of data to construct packet from. */
540
541         // Create packet as new packet (header) before a given packet
542
543         static ConcretePacket createBefore(Packet packet); 
544                                         ///< Create default initialized packet before \a packet
545                                         /**< The packet will be initialized to it's default empty
546                                              state. It will be prepended as previous
547                                              header/interpreter before \a packet in that packets
548                                              interpreter chain.
549                                              \param[in] packet Packet to prepend new packet to. */
550         static ConcretePacket createBefore(Packet packet, NoInit_t);
551                                         ///< Create uninitialized empty packet before \a packet
552                                         /**< Creates a completely empty and uninitialized packet. It
553                                              will be prepended as previous header/interpreter before
554                                              \a packet in that packets interpreter chain.
555                                              \param[in] packet Packet to prepend new packet to. */
556         
557         // Create a clone of the current packet
558
559         ConcretePacket clone() const;
560
561         ///@}
562         ///////////////////////////////////////////////////////////////////////////
563
564         // Field access
565
566         typename type::parser * operator->() const; ///< Access packet fields
567                                         /**< This operator allows to access the parsed fields of the
568                                              packet using the notation <tt>packet->field()</tt>. The
569                                              fields of the packet are specified by the PacketType's
570                                              \c parser member. 
571
572                                              The members are not strictly restricted to simple field
573                                              access. The parser class may have any member which is
574                                              needed for full packet access (e.g. checksum validation
575                                              / recreation ...)
576                                              \see \ref packetparser for the parser interface. */
577
578     protected:
579
580     private:
581         typedef PacketInterpreter<PacketType> interpreter;
582
583         ConcretePacket(typename interpreter::ptr packet_);
584         
585         typename interpreter::ptr ptr() const;
586
587         friend class Packet;
588         friend class PacketInterpreter<PacketType>;
589     };
590
591     ///@}
592
593 }
594
595 ///////////////////////////////hh.e////////////////////////////////////////
596 #endif
597 #if !defined(HH_Packets__decls_) && !defined(HH_Packet_i_)
598 #define HH_Packet_i_
599 #include "Packet.cci"
600 #include "Packet.ct"
601 #include "Packet.cti"
602 #endif
603
604 \f
605 // Local Variables:
606 // mode: c++
607 // fill-column: 100
608 // c-file-style: "senf"
609 // indent-tabs-mode: nil
610 // ispell-local-dictionary: "american"
611 // compile-command: "scons -u test"
612 // comment-column: 40
613 // End:
614