X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacketParser.hh;h=c6a38e82a4844f23915aa838f9a91e4362572ead;hb=a18d131c38ffe7178ea4736ed3f584125e9903ae;hp=9a3305b698b174dfa336dc39b1f7bee3f5853931;hpb=32573fc81844083b2aa02d3d224e4cb327de0d9d;p=senf.git diff --git a/Packets/PacketParser.hh b/Packets/PacketParser.hh index 9a3305b..c6a38e8 100644 --- a/Packets/PacketParser.hh +++ b/Packets/PacketParser.hh @@ -63,13 +63,13 @@ 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 + \li \ref parserimpl_value 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 + \li \ref parserimpl_collection 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 + \li \ref parserimpl_composite 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. + \li \ref parserimpl_packet 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 @@ -118,7 +118,7 @@ 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. + policies. \subsection parserimpl_composite Composite parsers @@ -140,7 +140,8 @@ 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_ @@ -150,7 +151,7 @@ #include #include #include -#include "Utils/SafeBool.hh" +#include "../Utils/SafeBool.hh" #include "PacketTypes.hh" #include "PacketData.hh" @@ -161,7 +162,7 @@ namespace senf { /** \brief Parser Base class - Parsers come in two favors: fixed and dynamically sized parsers. A fixed size + Parsers come in two flavors: fixed and dynamically sized parsers. A fixed size parser has a constant size, it will always parse a fixed number of bytes. The low-level 'final' parsers (like the integer parsers) are fixed size parsers as are composite parsers built up only of fixed-size fields. @@ -369,6 +370,7 @@ namespace senf { # else /** \brief Generic parser copying + This operator allows to copy the values of identical parsers. This operation does \e not depend on the parsers detailed implementation, it will just replace the data bytes of the target parser with those from the source parser. This allows to easily copy around complex @@ -403,6 +405,28 @@ namespace senf { Parser operator<<(Parser target, Value const & value); # endif +# ifndef DOXYGEN + template + typename boost::enable_if_c < + boost::is_base_of::value + && ! boost::is_base_of::value, + Parser >::type + operator<<(Parser target, boost::optional const & value); +# else + /** \brief Generic parser value assignment + + This operator allows to assign a value to parsers which implement a value(\a + value) member. This special version allows to assign optional values: IF the + optional value is not set, the assignment will be skipped. + + This operator allows to use a common syntax for assigning values or parsers to a parser. + + \ingroup packetparser + */ + template + Parser operator<<(Parser target, boost::optional const & value); +# endif + /** \defgroup packetparsermacros Helper macros for defining new packet parsers To simplify the definition of simple packet parsers, several macros are provided. Before @@ -413,10 +437,24 @@ namespace senf { using these macros has the following form (This is a concrete example from the definition of the ethernet packet in DefaultBundle/EthernetPacket.hh) - \dontinclude EthernetPacket.hh - \skipline struct Parse_EthVLan : public PacketParserBase - \until }; - + \code + struct Parse_EthVLan : public PacketParserBase + { + typedef Parse_UIntField < 0, 3 > Parse_Priority; + typedef Parse_Flag < 3 > Parse_CFI; + typedef Parse_UIntField < 4, 16 > Parse_VLanId; + typedef Parse_UInt16 Parse_Type; + + SENF_PACKET_PARSER_INIT(Parse_EthVLan); + + SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS( + ((OverlayField)( priority, Parse_Priority )) + ((OverlayField)( cfi, Parse_CFI )) + ((Field )( vlanId, Parse_VLanId )) + ((Field )( type, Parse_Type )) ); + }; + \endcode + The macros take care of the following: \li They define the accessor functions returning parsers of the given type. \li They automatically calculate the offset of the fields from the preceding fields.