Packets: Add additional packet parser clarifications
g0dil [Tue, 24 Jul 2007 11:55:16 +0000 (11:55 +0000)]
Packets: Adapt to use ccide-all-includes-guard feature
Packets: Remove ancient doc files (TODO, FUTURE)

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@345 270642c3-0616-0410-b53a-bc976706d245

Packets/.dir.el [new file with mode: 0644]
Packets/FUTURE [deleted file]
Packets/Mainpage.dox
Packets/PacketParser.hh
Packets/TODO [deleted file]

diff --git a/Packets/.dir.el b/Packets/.dir.el
new file mode 100644 (file)
index 0000000..77d54f9
--- /dev/null
@@ -0,0 +1 @@
+(set (make-local-variable 'ccide-all-includes-guard) "SENF_PACKETS_DECL_ONLY")
diff --git a/Packets/FUTURE b/Packets/FUTURE
deleted file mode 100644 (file)
index 65d4484..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-Optimize the PacketRegistry using a vtable like approach. This vtable
-approach should be implemented as a generic vtable library:
-
-Every class which shall be extensible needs to inheriv from the vtable
-base class. This base class adds an integer member to the class. This
-baseclass uses the CRTP pattern to initialize this integer to a type
-specific value.
-
-To get theese values, we use a typeid registry. The typeid-registry is
-a tempalte struct with the class as template arg and a single static
-member fn. This fn has a member variable of type 'typeid sequence
-value'. The constructor of this type will automatically allocate the
-next free typeid integer. This can then efficiently be returned by the
-static retrieval function:
-
-    template <class T>
-    struct senf::vtable::impl::TypeRegistry
-    {
-        static unsigned id() {
-            static senf::vtable::impl::AutoTypeId typeid;
-            return typeid.id();
-        }
-    };
-
-    struct senf::vtable::impl::AutoTypeId
-    {
-        AutoTypeId() : id(nextAutoTypeId()) {}
-        unsigned id;
-    };
-
-    unsigned nextAutoTypeId()
-    {
-        static unsigned id(0);
-        return id++;
-    }
-
-This setup will assign id's uniquely. The Id's will be ordered by the
-first TypeRegistry::id() call. To get the Type id of a type, just call
-senf::vtable::impl::TypeRegistry<SomeType>::id().
-
-The above is bogus ... we don't register the extensible types, we
-register the extensions which are arbitrary types.
-
-The typeid assigned to the extension type is used as an index into a
-vtable. This vtable is in the simplest case, just an std::vector of
-void*. To assign an extension to a specific type, we just add some
-instance of the registered extension type to the vtable of the
-to-be-extended type using the slot given by the typeid of the
-extension type. To get the extension, we just look up the id of the
-extension type and cast the value from the vtable vector to the
-appropriate type. All this is O(1) and does not depend on the number
-of extensions or on the number of extended classes.
-
-The extension vtables are created inside a static method of a
-templated class (template arg is the extensible class). Additionally,
-the extensible class must CRTP-wise inherit the vtable baseclass,
-which will add a vtable pointer to the extensible class and initialize
-it automatically to point to the correct vtable.
-
-To make this even more efficient, all vtables should be kept in a
-list. This allows to keep all vtables to the same size. Then no range
-checking must be done on accessing the vtable, since all vtables are
-all as long as the largest extension id. This of course makes the
-Operation of registering a new extension type O(n), but that should
-not be a problem since extensions are registered once during program
-startup. As a reward, the lookup performance is increased: it is only
-a memory access to find the extension-type id(the address is fixed at
-compile time) followed by an indexed access to the vtable, where the
-vtable address is fetched using another memory access. This differs
-from a compiler-generated vtable access only by a single memory
-access.
index f412bfa..f541660 100644 (file)
         default protocols: Ethernet, Ip, TCP, UDP
     \li <a href="../../MPEGDVBBundle/doc/html/index.html">MPEGDVBBundle</a>: MPEG and DVB
         protocols
+
+    There are two ways to link with a bundle
+    
+    \li If you only work with known packets which you explicitly reference you may just link with
+        the corresponding library.
+    \li If you need to parse unknown packets and want those to be parsed as complete as possible
+        without explicitly referencing the packet type, you will need to link against the combined
+        object file built for every bundle. This way, all packets defined in the bundle will be
+        included whether they are explicitly referenced or not (and they will all automatically be
+        registered).
  */
 
 \f
index 98fdbb2..9a3305b 100644 (file)
     <em>by value</em>, they can be understood as pointers into the packet data with added type
     information providing parsing functions.
 
+    Packet parsers are \e only used within the packet framework. You should never allocate a new
+    parser instance directly, you should the Packet library let that do for you (either by having
+    the parser as a packet parser in a packet type or by having a member in the packet parser which
+    allocates the parser as a sub-parser).
+
     Parsers are built hierarchically. A high-level parser will return other parsers when accessing
     an element (Example: Asking an EthernetParser for the ethertype field by calling the parsers \c
     type() member will return an \c UInt16 parser). The lowest level building blocks then return the
     complex parsers provide type specific access members. Assigning a value to a parser will change
     the underlying representation (the packet data). 
 
-    More complex parsers (especially those representing a collection of values) provide an
-    additional wrapper class for mutating access (e.g. Parse_Vector provides a container wrapper
-    with am STL compatible random-access sequence interface). See the documentation of the specific
-    parser for the wrapper specification.
-
-    Every parser is derived from senf::PacketParserBase. This class provides the necessary
-    housekeeping information and provides the parsers with access to the data.
+    Parsers can be grouped into several categories. These categories are not all defined rigorously
+    but are nevertheless helpful when working with the parsers:
+    \li <em>Value parsers</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which
+        returns an integer value).
+    \li <em>Collection parsers</em> are parsers which model a collection of sub-elements like
+        senf::Parse_List or senf::Parse_Vector.
+    \li <em>Composite parsers</em> collect several fields of arbitrary type into a new
+        parser. Parsers defined using the \ref packetparsermacros fall under this category.
+    \li <em>Packet parsers</em> are used to define a packet type.
 
     \warning Parsers are like iterators: They are invalidated <em>whenever the size of the packet's
     data is changed</em>. You should not store a parser anywhere. If you want to keep a parser
     reference, use the senf::SafePacketParser wrapper. You still will need to take extra care to
     ensure the parser is not invalidated.
+
+    \section parserimpl Packet parser categories
+
+    Every parser is derived from senf::PacketParserBase. This class provides the necessary
+    housekeeping information and provides the parsers with access to the data. You may in principle
+    define arbitrary methods as parser members (e.g. methods to calculate a checksum, methods
+    processing fields in some way and so on). You should however be very wary to access data outside
+    the range assigned to the packet (the range starting at \c i() and with a size of senf::bytes()
+    bytes).
+    
+    Each parser type has specific features
+
+    \subsection parserimpl_value Value parsers
+
+    For a parser \a SomeParser to be a value parser, the following expressions must be valid:
+    \code
+    // SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy
+    // constructible and assignable
+    SomeParser::value_type v; 
+
+    // An instance of 'SomeParser' must have a 'value' member which returns a value which may be
+    // assigned to a variable of type 'value_type'
+    v = p.someParserField().value()
+
+    // It must be possible to assign a new value using the 'value' member
+    p.someParserField().value(v)
+    \endcode
+
+    If at all possible, the 'value_type' should not reference the packet data using iterators or
+    pointers, it should hold a copy of the value (it's Ok for \c value() to return such a reference
+    as long as assigning it to a \c value_type variable will copy the value).
+
+    \subsection parserimpl_collection Collection parsers
+
+    A collection parser \a SomeParser should model STL containers. The parsers themselves will
+    probably only // provide a reduced interface, but the collection parser should have a \c
+    collection member which is a wrapper providing the full interface.
+    \code
+    SomeParser::container c (p.someParserField());
+    \endcode
+
+    You will probably only very seldom need to implement a completely new collection
+    parser. Instead, you can rely on senf::Parse_Vector or senf::Parse_List and implement new
+    polcies.
+
+    \subsection parserimpl_composite Composite parsers
+    
+    If possible, composite parsers should be implemented using the \ref packetparsermacros. In
+    addition to the normal parser requirements, these macros ensure, that for each field,
+    <em>fieldname</em><tt>_t</tt> is a typedef for the fields parser and
+    <em>fieldname</em><tt>_offset</tt> is the offset of the field in bytes from the beginning of the
+    parser (either a constant for fixed size parsers or a member function for dynamically sized
+    parsers). When defining composite parsers without the help of the \ref packetparsermacros, you
+    should provide those same members.
+
+    \subsection parserimpl_packet Packet parsers
+
+    Packet parsers are composite parsers with relaxed requirements. Since a packet parser will never
+    be used as a sub-parser (it will not be used within another composite parser or as value type in
+    a collection parser), the value returned by senf::bytes for this parser must not necessarily
+    cover the complete packet (e.g. if the packet has a trailer, the trailer will live outside the
+    range given by senf::bytes). You may define any member you want to have in your packets field
+    interface. These members may access the packet data in any way. You just need to ensure, that
+    the integration into the packet-type is correct (the senf::PacketTypeMixin will by default use
+    senf::bytes() to find the end of the header).
+    
  */
 
 #ifndef HH_PacketParser_
diff --git a/Packets/TODO b/Packets/TODO
deleted file mode 100644 (file)
index 8749617..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Klasse für IPv6 (v4?) Adressen als Parser und als value type
-
-Bessere check implementierung ?
-check umbauen: check() static machen und vor dem DerivedPacket() constructor
-aufrufen. DerivedPacket() constructor darf dann keine exception mehr
-auslösen
-
-ParseListS wrapper implementieren.
-
----------------------------------------------------------------------------
-Obsolete:
-
-reference-counting: Packet's mit 0 refcount erstellen und dann in
-create hochzählen. Was spricht eigentlich dagegen ???
-  --> Hrmpf .. doch ziemlich kompliziert, ich glaube, das lasse ich