diff --git a/Packets/MPEGDVBBundle/DatagramSection.hh b/Packets/MPEGDVBBundle/DatagramSection.hh index b0e9331d12373c7b98cebe0c2b3645fbbe6efe60..110feab72936f027890ce6d41b6aa7ab274e3682 100644 --- a/Packets/MPEGDVBBundle/DatagramSection.hh +++ b/Packets/MPEGDVBBundle/DatagramSection.hh @@ -110,8 +110,6 @@ namespace senf { typedef Parse_DatagramSection parser; using mixin::nextPacketRange; -// using mixin::nextPacketType; - //using mixin::initSize; using mixin::init; static void dump(packet p, std::ostream & os); diff --git a/Packets/MPEGDVBBundle/TLVPacket.cc b/Packets/MPEGDVBBundle/TLVPacket.cc index 74b03809362f2ec939bce749682c915d41a900a1..8d24a3f0da3cefcb974af30c5d0ac7ede5e4aa31 100644 --- a/Packets/MPEGDVBBundle/TLVPacket.cc +++ b/Packets/MPEGDVBBundle/TLVPacket.cc @@ -1,4 +1,4 @@ -// $Id: SNDUPacket.cc 423 2007-08-31 22:05:37Z g0dil $ +// $Id$ // // Copyright (C) 2007 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) @@ -33,15 +33,6 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// - -prefix_ senf::PacketParserBase::size_type senf::Parse_TLVPacket::bytes() - const -{ -//#include <iostream> -// std::cout << "XX: " << unsigned( 4 + senf::bytes( length() ) ) << "\n"; - return 4 + senf::bytes( length() ); -} - prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os) { os << "TLVPacket:\n" @@ -50,10 +41,15 @@ prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os) << " length: " << unsigned(p->length()) << "\n"; } -//prefix_ senf::PacketParserBase::size_type senf::TLVPacketType::initSize() -//{ -// return 4 + 1; -//} +prefix_ senf::PacketInterpreterBase::optional_range +senf::TLVPacketType::nextPacketRange(packet p) +{ + if (p.data().size() < 6) + return no_range(); + return range( + boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ), + p.data().end() ); +} ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Packets/MPEGDVBBundle/TLVPacket.hh b/Packets/MPEGDVBBundle/TLVPacket.hh index 449f148867b11eec55580542eb60938fc2367cd6..a1b3628d463050ef9501ac523148acfe47aa4e21 100644 --- a/Packets/MPEGDVBBundle/TLVPacket.hh +++ b/Packets/MPEGDVBBundle/TLVPacket.hh @@ -1,4 +1,4 @@ -// $Id: SNDUPacket.hh 423 2007-08-31 22:05:37Z g0dil $ +// $Id$ // // Copyright (C) 2007 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) @@ -21,7 +21,7 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief SNDUPacket public header */ + \brief TLVPacket public header */ #ifndef HH_TLVPacket_ #define HH_TLVPacket_ 1 @@ -37,7 +37,6 @@ namespace senf { - struct UnsuportedTLVPacketException : public std::exception { virtual char const * what() const throw() { @@ -53,17 +52,20 @@ namespace senf { SENF_PACKET_PARSER_NO_INIT(Parse_TLVPacketLength); +# endif + + typedef boost::uint32_t value_type; + typedef Parse_Flag < 0 > Parse_extended_length_flag; typedef Parse_UIntField < 1, 8 > Parse_fixed_length; - SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS( - ((OverlayField)( extended_length_flag, Parse_extended_length_flag )) - ((Field )( fixed_length_field, Parse_fixed_length )) - ); + Parse_extended_length_flag extended_length_flag() const { + return parse<Parse_extended_length_flag>( 0 ); + } -# endif - - typedef boost::uint32_t value_type; + Parse_fixed_length fixed_length_field() const { + return parse<Parse_fixed_length>( 0 ); + } value_type value() const { switch( bytes() ) { @@ -82,6 +84,8 @@ namespace senf { }; } + static const size_type init_bytes = 1; + size_type bytes() const { if ( extended_length_flag() ) return 1 + fixed_length_field(); @@ -108,25 +112,12 @@ namespace senf { SENF_PACKET_PARSER_INIT(Parse_TLVPacket); - SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS( + SENF_PACKET_PARSER_DEFINE_FIELDS( ((Field)( type, Parse_UInt32 )) ((Field)( length, Parse_TLVPacketLength )) ); # endif - -// Parse_UInt32 type() const { -// return parse<Parse_UInt32>( 0 ); -// } - -// Parse_TLVPacketLength length() const { -// return parse<Parse_TLVPacketLength>( 4 ); -// } - - PacketParserBase::size_type bytes() const; - - static const size_type init_bytes = 4+1; // 4 bytes type + 1 byte length - }; /** \brief TLV Packet @@ -140,21 +131,14 @@ namespace senf { \ingroup protocolbundle_mpegdvb */ struct TLVPacketType - : public PacketTypeBase, - public PacketTypeMixin<TLVPacketType> + : public PacketTypeBase { - typedef PacketTypeMixin<TLVPacketType> mixin; typedef ConcretePacket<TLVPacketType> packet; typedef Parse_TLVPacket parser; - using mixin::nextPacketRange; - using mixin::init; - using mixin::initSize; + static optional_range nextPacketRange(packet p); static void dump(packet p, std::ostream & os); - -// static PacketParserBase::size_type initSize(); -// static PacketParserBase::size_type initHeadSize(); }; typedef TLVPacketType::packet TLVPacket; diff --git a/Packets/MPEGDVBBundle/TLVPacket.test.cc b/Packets/MPEGDVBBundle/TLVPacket.test.cc index 46199302705ef5f1289160afc381f7e9e990e7b8..f642823de9249ae5e7db338bd5243d779e7e3898 100644 --- a/Packets/MPEGDVBBundle/TLVPacket.test.cc +++ b/Packets/MPEGDVBBundle/TLVPacket.test.cc @@ -1,4 +1,4 @@ -// $Id: TransportPacket.test.cc 389 2007-08-10 15:06:54Z tho $ +// $Id$ // // Copyright (C) 2007 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) @@ -38,27 +38,49 @@ using namespace senf; +BOOST_AUTO_UNIT_TEST(tlvPacket_parser) +{ + // number of bytes to allocate for a new TLVPacket should be 5 + BOOST_CHECK_EQUAL( init_bytes<Parse_TLVPacket>::value, 5u ); +} + +BOOST_AUTO_UNIT_TEST(tlvPacket_parse_packet_with_simple_length) +{ + unsigned char data[] = { + 0x01, 0x23, 0x45, 0x67, // type + 0x0A, // first not set, length=10 + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload) + }; + + senf::TLVPacket p (senf::TLVPacket::create(data)); + + BOOST_CHECK_EQUAL( p->type(), 0x01234567u ); + BOOST_CHECK_EQUAL( p->length(), 0x0Au ); + + PacketData & p_value (p.next().data()); + BOOST_CHECK_EQUAL( p_value.size(), 0x0Au); + for (int i=0, j=p_value.size(); i<j; i++) + BOOST_CHECK_EQUAL( p_value[i], i); +} + BOOST_AUTO_UNIT_TEST(tlvPacket_parse_packet_with_extended_length) { unsigned char data[] = { 0x01, 0x23, 0x45, 0x67, // type 0x81, // first and last bit set => one byte length following 0x0A, // length (10 bytes value) - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A // value (payload) + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload) }; senf::TLVPacket p (senf::TLVPacket::create(data)); -#include <iostream> - p.dump(std::cout); - BOOST_CHECK_EQUAL( p->type(), 0x01234567u ); BOOST_CHECK_EQUAL( p->length(), 0x0Au ); - senf::PacketData & p_value (p.next().data()); - senf::hexdump( p_value.begin(), p_value.end(), std::cout ); - -// BOOST_CHECK_EQUAL( p_value.size(), 0x0Au); + PacketData & p_value (p.next().data()); + BOOST_CHECK_EQUAL( p_value.size(), 0x0Au); + for (int i=0, j=p_value.size(); i<j; i++) + BOOST_CHECK_EQUAL( p_value[i], i); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Packets/MPEGDVBBundle/TransportPacket.hh b/Packets/MPEGDVBBundle/TransportPacket.hh index 94248c9898ebc47f0a47ac71062aa845cb22a8c8..31b66cd3352ae71d55083519c87fda66bb728de0 100644 --- a/Packets/MPEGDVBBundle/TransportPacket.hh +++ b/Packets/MPEGDVBBundle/TransportPacket.hh @@ -30,7 +30,6 @@ #include <algorithm> #include "../../Packets/PacketType.hh" #include "../../Packets/ParseInt.hh" -#include "../../Packets/PacketRegistry.hh" #include "../../Packets/PacketParser.hh" //#include "TransportPacket.mpp" @@ -40,7 +39,7 @@ namespace senf { /** \brief Parse a Transport Stream packet - Parser implementing the header of a MPEG Transport Stream Packet. + Parser implementing the header of a MPEG Transport Stream packet. \see TransportPacketType */ @@ -89,6 +88,40 @@ namespace senf { /** \brief Transport Stream packet + <table class="senf"> + <tr style="text-align:center"> + <th>Syntax</th><th>No. of bits</th></tr> + <tr> + <td>transport_packet() {</td> <td></td> + </tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::sync_byte() "sync_byte"</td> + <td>8</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::transport_error_indicator() "transport_error_indicator"</td> + <td>1</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::pusi() "payload_uni_start_indicator"</td> + <td>1</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::transport_priority() "transport_priority"</td> + <td>1</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::pid() "PID"</td> + <td>13</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::transport_scrmbl_ctrl() "transport_scrambling_control"</td> + <td>2</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::adaptation_field_ctrl() "adaptation_field_control"</td> + <td>2</td></tr> + <tr> + <td style="padding-left:2em">\ref Parse_TransportPacket::continuity_counter() "continuity_counter"</td> + <td>4</td></tr> + <tr> + <td>}</td> <td></td></tr> + </table> + \par Packet type (typedef): \ref TransportPacket @@ -106,7 +139,6 @@ namespace senf { typedef Parse_TransportPacket parser; using mixin::nextPacketRange; - // using mixin::nextPacketType; using mixin::init; using mixin::initSize; diff --git a/Packets/PacketParser.hh b/Packets/PacketParser.hh index 1b8c21432cfcffac5e9d79fc1ee00267c666dac5..6871d1dcd488846db4a4c3e0c6e8d38e6d2dd301 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 <em>Value parsers</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which + \li <em>\ref parserimpl_value</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 + \li <em>\ref parserimpl_collection</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 + \li <em>\ref parserimpl_composite</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. + \li <em>\ref parserimpl_packet</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 @@ -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). - + + <hr> */ #ifndef HH_PacketParser_ diff --git a/Packets/PacketType.hh b/Packets/PacketType.hh index 863f96668b6137e24e2fcce141ee41b9e6689e8f..7146d08266eb40151ff3d3f71e084d4e40da9eaa 100644 --- a/Packets/PacketType.hh +++ b/Packets/PacketType.hh @@ -214,11 +214,11 @@ 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 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: \code // Here 'SomeRegistryTag' is optional struct SimplePacketType