From: g0dil Date: Mon, 28 Jan 2008 13:38:42 +0000 (+0000) Subject: Howtos/NewPacket: Reformat 'Further reading' list X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=3a1b45cae9d48b1d53fc310e2a283d2b9d17275e Howtos/NewPacket: Reformat 'Further reading' list doclib: Fix some senf.css / doxygen.css interactions Packets: Implement ConcreatePacket::parser Packets: Make the PacketTypeMixin work with (simple) dynamically sized parsers git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@640 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/HowTos/NewPacket/Mainpage.dox b/HowTos/NewPacket/Mainpage.dox index 1395147..a932cb8 100644 --- a/HowTos/NewPacket/Mainpage.dox +++ b/HowTos/NewPacket/Mainpage.dox @@ -848,7 +848,7 @@ senf::RawV6ClientSocketHandle isock (47u); // 47 = Read GRE packets senf::PacketSocketHandle osock; - while (1) { + while (true) { try { GREPacket gre (GREPacket::create(senf::noinit)); isock.read(gre.data(),0u); @@ -887,7 +887,7 @@ senf::TapSocketHandle tap ("tap0"); senf::ConnectedRawV6ClientSocketHandle osock (47u, senf::INet6SocketAddress(argv[1])); - while (1) { + while (true) { senf::EthernetPacket eth (senf::EthernetPacket::create(senf::noinit)); isock.read(eth.data(),0u); GREPacket gre (senf::GREPacket::createBefore(eth)); @@ -900,27 +900,43 @@ \section howto_newpacket_further Further reading - Lets start with references to the important API's (Use the 'Show all members' link to get the - complete API of one of the classes and templates): + Lets start with references to the important API's (Use the List of all members link to + get the complete API of one of the classes and templates): - \li senf::ConcretePacket : this is the API provided by the packet handles. - \li senf::PacketData : this API provides raw data access accessible via the handles 'data' - member. - \li senf::PacketParserBase : this is the generic parser API. This API is accessible via the - packets \c -> operator or via the sub-parsers returned by the field accessors. + + + + + + + + +
senf::ConcretePacket this is the API provided by the packet handles.
senf::PacketData this API provides raw data access accessible via the handles + 'data' member.
senf::PacketParserBase this is the generic parser API. This API is accessible + via the packets \c -> operator or via the sub-parsers returned by the field accessors.
When implementing new packet's, the following information will be helpful: - \li senf::PacketTypeBase : here you find a description of the members which need to be - implemented to provide a 'packet type'. Most of these members will normally be provided by - the mixin helper. - \li senf::PacketTypeMixin : here you find all about the packet type mixin and how to use it. - \li \ref packetparser : This section describes the packet parser facility. - \li \ref packetparsermacros : A complete list and documentation of all the packet parser macros. - \li There are several lists of available reusable packet parsers: \ref parseint, \ref - parsecollection. However, this list is not complete as there are other protocol specific - reusable parsers (without claiming to be exhaustive: senf::INet4AddressParser, - senf::INet6AddressParser, senf::MACAddressParser) + + + + + + + + + + + + +
senf::PacketTypeBase here you find a description of the members which need to + be implemented to provide a 'packet type'. Most of these members will normally be provided by + the mixin helper.
senf::PacketTypeMixin here you find all about the packet type mixin and how to + use it.
\ref packetparser This section describes the packet parser facility.
\link packetparsermacros Packet parser macros\endlink A complete list and + documentation of all the packet parser macros.
\ref parseint, \n \ref parsecollection There are several lists of available + reusable packet parsers: . However, this list is not complete as there are other protocol + specific reusable parsers (without claiming to be exhaustive: senf::INet4AddressParser, + senf::INet6AddressParser, senf::MACAddressParser)
*/ diff --git a/Packets/Packet.cti b/Packets/Packet.cti index 5f67ccb..6331b1c 100644 --- a/Packets/Packet.cti +++ b/Packets/Packet.cti @@ -248,13 +248,21 @@ senf::ConcretePacket::clone() // Field access template -prefix_ typename senf::ConcretePacket::type::parser * +prefix_ typename senf::ConcretePacket::Parser * senf::ConcretePacket::operator->() const { return ptr()->fields_p(); } +template +prefix_ typename senf::ConcretePacket::Parser +senf::ConcretePacket::parser() + const +{ + return ptr()->fields(); +} + // private members template diff --git a/Packets/Packet.hh b/Packets/Packet.hh index 33f6317..996e2c1 100644 --- a/Packets/Packet.hh +++ b/Packets/Packet.hh @@ -569,6 +569,13 @@ namespace senf { / recreation ...) \see \ref packetparser for the parser interface. */ + Parser parser() const; ///< Access packet field parser directly + /**< Access the parser of the packet. This is the same + object returned by the operator->() operator. The + operator however does not allow to access this object + itself, only it's members. + \see \ref packetparser for the parser interface */ + protected: private: diff --git a/Packets/Packet.test.cc b/Packets/Packet.test.cc index fe949cb..90d383b 100644 --- a/Packets/Packet.test.cc +++ b/Packets/Packet.test.cc @@ -49,9 +49,15 @@ namespace { using senf::PacketTypeMixin::nextPacketRange; using senf::PacketTypeMixin::initSize; using senf::PacketTypeMixin::init; - typedef senf::PacketInterpreter interpreter; - static interpreter::size_type initSize() + static size_type initSize() { return 4u; } + + // We need to implement initHeadSize() to force the mixin to switch into 'fixed-size' + // mode. Otherwise, mixin::nextPacketRange() would query the parser for it's size to find + // the header size. Since the parser is VoidPacketParser, the header size would therefore be + // 0 + static size_type initHeadSize() + { return initSize(); } }; typedef senf::ConcretePacket FooPacket; @@ -63,6 +69,10 @@ namespace { SENF_PARSER_FIELD( length, senf::Int32Parser ); SENF_PARSER_FIELD( reserved, senf::UInt16Parser ); + SENF_PARSER_INIT() { + reserved() << 0xA0A0u; + } + SENF_PARSER_FINALIZE(BarPacketParser); }; @@ -77,11 +87,6 @@ namespace { using mixin::nextPacketType; using mixin::initSize; using mixin::init; - static size_type initSize() - { return 8u; } - static void init(packet p) { - p->reserved() = 0xA0A0u; - } static void dump(packet p, std::ostream & os) { os << "BarPacket:\n" << "type: " << p->type() << "\n" @@ -117,6 +122,10 @@ BOOST_AUTO_UNIT_TEST(packet) BOOST_CHECK( ! packet.prev(senf::nothrow) ); BOOST_CHECK( packet.next().prev() == packet ); BOOST_CHECK( packet.next() != packet ); + BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.next().data().begin()), 4 ); + BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.data().end()), 12 ); + BOOST_CHECK_EQUAL( std::distance(packet.next().data().begin(), packet.next().data().end()), 8 ); + BOOST_CHECK( packet.data().end() == packet.next().data().end() ); BOOST_CHECK_EQUAL( packet.size(), 12u ); BOOST_CHECK_EQUAL( packet.next().size(), 8u ); BOOST_CHECK( packet.is() ); diff --git a/Packets/PacketType.ct b/Packets/PacketType.ct index d3cc085..5443c1d 100644 --- a/Packets/PacketType.ct +++ b/Packets/PacketType.ct @@ -43,9 +43,16 @@ senf::PacketTypeMixin::nextPacketRange(Packet p) ///\idea This if condition could be replaced with a compile time switch by checking, wether /// (the function address) Self::initHeadSize is different from PacketTypeBase::initHeadSize if (sz == PacketTypeBase::size_type(-1)) - return PacketTypeBase::range(boost::next(p.data().begin(),Self::initSize()), + return PacketTypeBase::range(boost::next(p.data().begin(), + bytes(p.as< ConcretePacket >().parser())), p.data().end()); else + // If we have a trailer, we do *not* use the 'bytes' value but initSize/initHeadSize, this + // is much safer since the bytes() value will probably not be very correct anyways (what + // should it return ? the size of the header only, the combined size of header and trailer + // or the size of the packet from header to trailer including payload?). + // + // So, the helper only works with fixed-size parsers if the packet has a trailer. return PacketTypeBase::range(boost::next(p.data().begin(),sz), boost::prior(p.data().end(),Self::initSize()-sz)); } diff --git a/Packets/PacketType.hh b/Packets/PacketType.hh index e9d0d30..c23db1e 100644 --- a/Packets/PacketType.hh +++ b/Packets/PacketType.hh @@ -216,11 +216,16 @@ namespace senf { /** \brief Mixin to provide standard implementations for nextPacketRange and nextPacketType - This mixin class simplifies the definition of simple packets with fixed-size (!) headers - and/or trailers. For this type of Packet, this mixin provides the nextPacketRange() - member. If you additionally provide the optional \a Registry argument, PacketTypeMixin - provides a simple implementation of nextPacketType. When using the PacketTypeMixin, the - implementation of a packet is simplified to: + This mixin class simplifies the definition of simple packets: + + \li The packets consist of three sections: The header, the payload and an optional trailer. + \li If the packet has a trailer, both the header and the trailer must have a fixed size. + + This mixin provides the nextPacketRange() member as well as initSize() and init(). If you + additionally provide the optional \a Registry argument, PacketTypeMixin provides a simple + implementation of nextPacketType(). + + When using the PacketTypeMixin, the implementation of a packet is simplified to: \code // Here 'SomeRegistryTag' is optional struct SimplePacketType @@ -232,36 +237,9 @@ namespace senf { typedef SomePacketParser parser; using mixin::nextPacketRange; - // Only if the optional 'Registry' argument is provided - using mixin::nextPacketType; - // Only if using the default implementation + using mixin::nextPacketType; // Only if the optional 'Registry' argument is provided using mixin::initSize; - // Only if using the default implementation - using mixin::init; - - static interpreter::size_type initSize() - { - // This member is optional. If it is not defined, 'senf::init_size::value' - // will be returned. - - // The value returned is the length of the header if initHeadSize() is not defined. - // If initHeadSize is defined, this value is the combined size of the header - // and trailer while initHeadSize() will return the size of the header only. - return packet_size; - } - - static interpreter::size_type initHeadSize() - { - // This member is optional. It returns the header size if the packet has a - // trailer. - return header_size; - } - - static void init(packet p) - { - // This member is optional. The default implementation calls the parsers init() - // member. - } + using mixin::init; static key_t nextPacketKey(packet p) { @@ -286,11 +264,18 @@ namespace senf { { // Write out a readable representation of the packet for debug purposes } + + static interpreter::size_type initHeadSize() + { + // This member is optional. It returns the \e fixed header size if the packet has a + // trailer. + return header_size; + } + }; \endcode - Most of the members are optional, which reduces the implementation of a fixed-sized header - packet with no trailer and a simple next-packet header to + Most of the members are optional, which reduces the minimal implementation of a packet to: \code struct SimplePacketType @@ -304,16 +289,20 @@ namespace senf { using mixin::nextPacketRange; using mixin::nextPacketType; using mixin::initSize; - using mixin::init; + using mixin::init; - static key_t nextPacketKey(packet p) - { return p->typeField(); } + // 'typeField()' is one of the fields defined in the parser which holds + // the next-header information + + static key_t nextPacketKey(packet p) { return p->typeField(); } + static void finalize(packet p) { p->typeField() << key(p.next(senf::nothrow)); } + + static void dump(packet p) { + // should always be implemented although optional + } }; \endcode - If needed, you may additionally add a \c finalize() member. You also should add a \c dump() - member to help debugging but both members are optional. - \ingroup packet_module */ template diff --git a/doclib/senf.css b/doclib/senf.css index be87f66..1e4697d 100644 --- a/doclib/senf.css +++ b/doclib/senf.css @@ -5,6 +5,11 @@ body { font-size: 10pt; } +/* Argh .. doxygen.css has font-size:90% for td ... */ +td { + font-size: 100%; +} + #head { height: 62px; border-top: 5px solid #DECD40; @@ -290,12 +295,15 @@ table.senf th { font-weight: bold; } +table.fixedcolumn td:first-child { + width: 35%; +} + table.ebnf { margin: 0; padding: 0; border-spacing: 0; border: none; - font-size: 120%; /* ???????? Why is THIS needed ?? */ } table.ebnf td { @@ -315,7 +323,6 @@ table.listing { padding: 0; border-spacing: 0; border: none; - font-size: 120%; /* ???????? Why is THIS needed ?? */ } table.listing td {