typedef Parse_DatagramSection parser;
using mixin::nextPacketRange;
-// using mixin::nextPacketType;
- //using mixin::initSize;
using mixin::init;
static void dump(packet p, std::ostream & os);
-// $Id: SNDUPacket.cc 423 2007-08-31 22:05:37Z g0dil $
+// $Id$
//
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
#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"
<< " 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////////////////////////////////////////
-// $Id: SNDUPacket.hh 423 2007-08-31 22:05:37Z g0dil $
+// $Id$
//
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// 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
namespace senf {
-
struct UnsuportedTLVPacketException : public std::exception
{
virtual char const * what() const throw() {
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() ) {
};
}
+ static const size_type init_bytes = 1;
+
size_type bytes() const {
if ( extended_length_flag() )
return 1 + fixed_length_field();
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
\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;
-// $Id: TransportPacket.test.cc 389 2007-08-10 15:06:54Z tho $
+// $Id$
//
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
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////////////////////////////////////////
#include <algorithm>
#include "../../Packets/PacketType.hh"
#include "../../Packets/ParseInt.hh"
-#include "../../Packets/PacketRegistry.hh"
#include "../../Packets/PacketParser.hh"
//#include "TransportPacket.mpp"
/** \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
*/
/** \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
typedef Parse_TransportPacket parser;
using mixin::nextPacketRange;
- // using mixin::nextPacketType;
using mixin::init;
using mixin::initSize;
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
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
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_
/** \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