Every parser is derived from senf::PacketParserBase. This class provides the necessary
housekeeping information and provides the parsers with access to the data.
+
+ \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.
*/
#ifndef HH_PacketParser_
#include <boost/optional.hpp>
#include "Utils/SafeBool.hh"
#include "PacketTypes.hh"
-#define HH_PacketData_DeclOnly
#include "PacketData.hh"
-#undef HH_PacketData_DeclOnly
#include "PacketParser.mpp"
///////////////////////////////hh.p////////////////////////////////////////
struct init_bytes : public detail::ParserInitBytes<Parser>
{};
+# ifndef DOXYGEN
+ template <class Parser>
+ typename boost::enable_if<
+ boost::is_base_of<PacketParserBase, Parser>,
+ Parser >::type
+ operator<<(Parser target, Parser source);
+# else
/** \brief Generic parser copying
This operator allows to copy the values of identical parsers. This operation does \e not
\ingroup packetparser
*/
template <class Parser>
- typename boost::enable_if<
- boost::is_base_of<PacketParserBase, Parser>,
- Parser >::type
- operator<<(Parser target, Parser source);
+ Parser operator<<(Parser target, Parser source);
+# endif
+# ifndef DOXYGEN
+ template <class Parser, class Value>
+ typename boost::enable_if_c <
+ boost::is_base_of<PacketParserBase, Parser>::value
+ && ! boost::is_base_of<PacketParserBase, Value>::value,
+ Parser >::type
+ operator<<(Parser target, Value const & value);
+# else
/** \brief Generic parser value assignment
This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
\ingroup packetparser
*/
template <class Parser, class Value>
- typename boost::enable_if_c <
- boost::is_base_of<PacketParserBase, Parser>::value
- && ! boost::is_base_of<PacketParserBase, Value>::value,
- Parser >::type
- operator<<(Parser target, Value const & value);
+ Parser operator<<(Parser target, Value const & value);
+# endif
/** \defgroup packetparsermacros Helper macros for defining new packet parsers
These macros simplify providing the above defined interface. A typical packet declaration
using these macros has the following form (This is a concrete example from the definition of
- the ethernet packet in <tt>DefaultBundle//EthernetPacket.hh</tt>)
- \code
- struct Parse_EthVLan : public senf::PacketParserBase
- {
- SENF_PACKET_PARSER_INIT(Parse_EthVLan);
-
- // ////////////////////////////////////////////////////////////////////////
-
- typedef senf::Parse_UIntField < 0, 3 > Parse_Priority;
- typedef senf::Parse_Flag < 3 > Parse_CFI;
- typedef senf::Parse_UIntField < 4, 16 > Parse_VLanId;
- typedef senf::Parse_UInt16 Parse_Type;
-
- SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
- ((OverlayField)( priority, Parse_Priority ))
- ((OverlayField)( cfi, Parse_CFI ))
- ((Field )( vlanId, Parse_VLanId ))
- ((Field )( type, Parse_Type ))
- );
- };
- \endcode
+ the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
+
+ \dontinclude EthernetPacket.hh
+ \skipline struct Parse_EthVLan : public PacketParserBase
+ \until };
The macros take care of the following:
\li They define the accessor functions returning parsers of the given type.
\hideinitializer
*/
# define SENF_PACKET_PARSER_DEFINE_FIELDS(fields) \
- SENF_PACKET_PARSER_I_DEFINE_FIELDS(fields)
+ SENF_PACKET_PARSER_I_DEFINE_FIELDS(0,fields)
+
+ /** \brief Define fields for a dynamically sized parser (with offset)
+
+ Define the fields as specified in \a fields. This macro supports dynamically sized
+ subfields, the resulting parser will be dynamically sized.
+
+ The \a offset argument gives the byte offset at which to start parsing the fields. This
+ helps defining extended parser deriving from a base parser:
+ \code
+ struct ExtendedParser : public BaseParser
+ {
+ ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
+ SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(senf::bytes(BaseParser(*this)),
+ ( ... fields ... ) );
+
+ void init() {
+ BaseParser::init();
+ defaultInit();
+ // other init code
+ }
+ }
+ \endcode
+
+ \ingroup packetparsermacros
+ \hideinitializer
+ */
+# define SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(offset,fields) \
+ SENF_PACKET_PARSER_I_DEFINE_FIELDS(offset,fields)
+
/** \brief Define fields for a fixed size parser
Define the fields as specified in \a fields. This macro only supports fixed size
\hideinitializer
*/
# define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(fields) \
- SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(fields)
+ SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(0,fields)
+
+ /** \brief Define fields for a fixed size parser
+
+ Define the fields as specified in \a fields. This macro only supports fixed size
+ subfields, the resulting parser will also be a fixed size parser.
+ The \a offset argument gives the byte offset at which to start parsing the fields. This
+ helps defining extended parser deriving from a base parser:
+ \code
+ struct ExtendedParser : public BaseParser
+ {
+ ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
+
+ SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(BaseParser::fixed_bytes,
+ ( ... fields ... ) );
+
+ void init() {
+ BaseParser::init();
+ defaultInit();
+ // other init code
+ }
+ }
+ \endcode
+
+ \ingroup packetparsermacros
+ \hideinitializer
+ */
+# define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(offset,fields) \
+ SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(offset,fields)
+
+ /** \brief Default parser parsing nothing
+ */
struct VoidPacketParser
: public PacketParserBase
{
location will \e not be updated accordingly and therefore the parser will be
invalid.
- Additionally a SafePacketparser has an uninitialized state. The only allowed operations in
+ Additionally a SafePacketParser has an uninitialized state. The only allowed operations in
this state are the boolean test for validity and assigning another parser.
+
+ \ingroup packetparser
*/
template <class Parser>
class SafePacketParser
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketParser_i_)
+#define HH_PacketParser_i_
#include "PacketParser.cci"
#include "PacketParser.ct"
#include "PacketParser.cti"
// comment-column: 40
// End:
-// LocalWords: templated PacketParser defgroup packetparser PacketParsers li
-// LocalWords: EthernetParser ethertype UInt senf PacketParserBase tt
-// LocalWords: struct FooParser const init endcode ingroup param SomeParser
-// LocalWords: ethernet DefaultBundle EthernetPacket hh EthVLan UIntField CFI
-// LocalWords: VLanId OverlayField cfi vlanId accessor defaultInit bitfield
-// LocalWords: SomePacket SimpleVectorSizer packetparsermacros Fraunhofer std
-// LocalWords: hideinitializer Institut fuer offene Kommunikationssysteme STL
-// LocalWords: FOKUS Kompetenzzentrum Satelitenkommunikation SatCom Bund cerr
-// LocalWords: berlios dil Structors someField someVector someOtherField
-// LocalWords: TruncatedPacketException