X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacketParser.hh;h=9a3305b698b174dfa336dc39b1f7bee3f5853931;hb=32573fc81844083b2aa02d3d224e4cb327de0d9d;hp=98fdbb25e17634de0717e32580172185b5b2247a;hpb=afa15c46e79de0f407d41fda78b6e8d08700caa8;p=senf.git diff --git a/Packets/PacketParser.hh b/Packets/PacketParser.hh index 98fdbb2..9a3305b 100644 --- a/Packets/PacketParser.hh +++ b/Packets/PacketParser.hh @@ -28,6 +28,11 @@ by value, 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 @@ -56,18 +61,86 @@ 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 Value parsers provide the lowest level parsers (e.g. senf::Parse_UInt16 which + returns an integer value). + \li Collection parsers are parsers which model a collection of sub-elements like + senf::Parse_List or senf::Parse_Vector. + \li Composite parsers collect several fields of arbitrary type into a new + parser. Parsers defined using the \ref packetparsermacros fall under this category. + \li Packet parsers are used to define a packet type. \warning Parsers are like iterators: They are invalidated whenever the size of the packet's data is changed. 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, + fieldname_t is a typedef for the fields parser and + fieldname_offset 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_