TLVPacket creating with changing HeaderSize doesn't work :(
tho [Mon, 1 Oct 2007 11:35:55 +0000 (11:35 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@454 270642c3-0616-0410-b53a-bc976706d245

Packets/MPEGDVBBundle/TLVPacket.cc
Packets/MPEGDVBBundle/TLVPacket.hh
Packets/MPEGDVBBundle/TLVPacket.test.cc

index 8d24a3f..270d81f 100644 (file)
 
 // Custom includes
 #include <iomanip>
-
+#include <senf/Utils/hexdump.hh>
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+prefix_ senf::Parse_TLVPacketLength::value_type senf::Parse_TLVPacketLength::value() const {
+    switch (bytes() ) {
+    case 1:
+        return fixed_length_field().value();
+    case 2:
+        return parse<Parse_UInt8>( 1 ).value();
+    case 3:
+        return parse<Parse_UInt16>( 1 ).value();
+    case 4:
+        return parse<Parse_UInt24>( 1 ).value();
+    case 5:
+        return parse<Parse_UInt32>( 1 ).value();
+    default:
+        throw(UnsuportedTLVPacketException());
+    };
+}
+
+prefix_ void senf::Parse_TLVPacketLength::value(value_type const & v) {
+    if (v > 4294967295u)
+        throw(UnsuportedTLVPacketException());
+        
+    if (v < 128u) {
+        if (bytes() != 1) resize(1);
+        fixed_length_field() = v;
+        return;
+    }
+    if (v < 256u) {
+        if (bytes() != 2) resize(2);
+        parse<Parse_UInt8>(1) = v;
+        return;
+    }
+    if (v < 65536u) {
+        if (bytes() != 3) resize(3);
+        parse<Parse_UInt16>(1) = v;
+        return;
+    }
+    if (v < 16777216u) {
+        if (bytes() != 4) resize(4);
+        parse<Parse_UInt24>(1) = v;
+        return;
+    }
+    if (v <= 4294967295u) {
+        if (bytes() != 5) resize(5);
+        parse<Parse_UInt32>(1) = v;
+        return;
+    }
+}
+
+prefix_ senf::Parse_TLVPacketLength const & senf::Parse_TLVPacketLength::operator= (value_type other) {
+    value(other);
+    return *this; 
+}
+
+prefix_ senf::Parse_TLVPacketLength::size_type senf::Parse_TLVPacketLength::bytes() const {
+    if ( extended_length_flag() )
+        return 1 + fixed_length_field();
+    else
+        return 1;
+}
+    
+prefix_ void senf::Parse_TLVPacketLength::init() const {
+    defaultInit();
+    extended_length_flag() = 0;
+}
+
+prefix_ void senf::Parse_TLVPacketLength::resize(size_type size) {
+    std::cout << "senf::Parse_TLVPacketLength::resize: " << unsigned(size) << "\n";
+//    hexdump(data().begin(), data().end(), std::cout);
+    
+    size_type current_size (bytes());
+    safe_data_iterator si (data(), i());
+    
+    if (current_size > size)
+        data().erase( si, boost::next(si, current_size-size));
+    else {
+        data().insert( si, size-current_size, 0);
+        Parse_TLVPacketLength(si,state()).init();
+    }
+    
+    if (size > 1) {
+        extended_length_flag() = 1;
+        fixed_length_field() = size-1;
+    } else {
+        extended_length_flag() = 0;
+    }
+    
+//    hexdump(data().begin(), data().end(), std::cout);
+}
+
+
 prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
 {
     os << "TLVPacket:\n"
@@ -41,10 +131,25 @@ prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
        << "  length: " << unsigned(p->length()) << "\n";
 }
 
+prefix_ senf::PacketParserBase::size_type senf::TLVPacketType::initSize()
+{
+    return 5;  // 4 bytes type + 1 byte length
+}
+
+prefix_ void senf::TLVPacketType::init(packet p)
+{
+    p->init();
+}
+
+prefix_ void senf::TLVPacketType::finalize(packet p)
+{
+    p->length() = p.next().data().size();
+}
+
 prefix_ senf::PacketInterpreterBase::optional_range 
 senf::TLVPacketType::nextPacketRange(packet p) 
 {
-    if (p.data().size() < 6)
+    if (p.data().size() < 5)
         return no_range();
     return range(
             boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
index a1b3628..2bbccb3 100644 (file)
@@ -44,10 +44,11 @@ namespace senf {
         }
     };
 
-    struct Parse_TLVPacketLength 
+    class Parse_TLVPacketLength 
         : public detail::packet::ParseIntOps<Parse_TLVPacketLength, boost::uint32_t>,
           public PacketParserBase
     {
+    public:
 #       ifndef DOXYGEN
         
         SENF_PACKET_PARSER_NO_INIT(Parse_TLVPacketLength);
@@ -55,7 +56,20 @@ namespace senf {
 #       endif
 
         typedef boost::uint32_t value_type;
+    
+        value_type value() const;
+
+        void value(value_type const & v);
         
+        Parse_TLVPacketLength const & operator= (value_type other);
+            
+        static const size_type init_bytes = 1;
+
+        size_type bytes() const;
+            
+        void init() const;
+
+    private:
         typedef Parse_Flag      <    0 > Parse_extended_length_flag;
         typedef Parse_UIntField < 1, 8 > Parse_fixed_length;
 
@@ -67,37 +81,8 @@ namespace senf {
             return parse<Parse_fixed_length>( 0 );
         }
         
-        value_type value() const {
-            switch( bytes() ) {
-                case 1:
-                    return fixed_length_field().value();
-                case 2:
-                    return parse<Parse_UInt8>( 1 ).value();
-                case 3:
-                    return parse<Parse_UInt16>( 1 ).value();
-                case 4:
-                    return parse<Parse_UInt24>( 1 ).value();
-                case 5:
-                    return parse<Parse_UInt32>( 1 ).value();
-                default:
-                    throw(UnsuportedTLVPacketException()); 
-            };
-        }
-        
-        static const size_type init_bytes = 1;
+        void resize(size_type size);
 
-        size_type bytes() const {
-            if ( extended_length_flag() )
-                return 1 + fixed_length_field();
-            else
-                return 1;
-        }
-        
-        void init() const {
-            defaultInit();
-            extended_length_flag() = 0;
-        }
-        
     };  
         
     /** \brief parse TLVPacket Packet
@@ -137,7 +122,9 @@ namespace senf {
         typedef Parse_TLVPacket parser;
 
         static optional_range nextPacketRange(packet p);
-        
+        static void init(packet p);
+        static size_type initSize();
+        static void finalize(packet p);
         static void dump(packet p, std::ostream & os);
     };
         
index f642823..63645a4 100644 (file)
@@ -28,7 +28,6 @@
 // Custom includes
 #include "TLVPacket.hh"
 #include <senf/Packets.hh>
-#include <senf/Utils/hexdump.hh>
 
 #include <boost/test/auto_unit_test.hpp>
 #include <boost/test/test_tools.hpp>
 
 using namespace senf;
 
-BOOST_AUTO_UNIT_TEST(tlvPacket_parser)
+BOOST_AUTO_UNIT_TEST(tlvPacket_static)
 {
+    // check static values:
     // number of bytes to allocate for a new TLVPacket should be 5
     BOOST_CHECK_EQUAL( init_bytes<Parse_TLVPacket>::value, 5u );
+    BOOST_CHECK_EQUAL( TLVPacketType::initSize(), 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
+        0x0A, // first bit not set, length=10
         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload)
     };
             
-    senf::TLVPacket p (senf::TLVPacket::create(data));
+    senf::TLVPacket tlvPacket (senf::TLVPacket::create(data));
     
-    BOOST_CHECK_EQUAL( p->type(), 0x01234567u );
-    BOOST_CHECK_EQUAL( p->length(), 0x0Au );
+    BOOST_CHECK_EQUAL( tlvPacket->type(), 0x01234567u );
+    BOOST_CHECK_EQUAL( tlvPacket->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);
+    PacketData & tlvPacket_value (tlvPacket.next().data());
+    BOOST_CHECK_EQUAL( tlvPacket_value.size(), 0x0Au);
+    for (int i=0, j=tlvPacket_value.size(); i<j; i++)
+        BOOST_CHECK_EQUAL( tlvPacket_value[i], i );
 }
 
 BOOST_AUTO_UNIT_TEST(tlvPacket_parse_packet_with_extended_length)
@@ -72,17 +73,52 @@ BOOST_AUTO_UNIT_TEST(tlvPacket_parse_packet_with_extended_length)
         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload)
     };
             
-    senf::TLVPacket p (senf::TLVPacket::create(data));
+    senf::TLVPacket tlvPacket (senf::TLVPacket::create(data));
     
-    BOOST_CHECK_EQUAL( p->type(), 0x01234567u );
-    BOOST_CHECK_EQUAL( p->length(), 0x0Au );
+    BOOST_CHECK_EQUAL( tlvPacket->type(), 0x01234567u );
+    BOOST_CHECK_EQUAL( tlvPacket->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);
+    PacketData & tlvPacket_value (tlvPacket.next().data());
+    BOOST_CHECK_EQUAL( tlvPacket_value.size(), 0x0Au);
+    for (int i=0, j=tlvPacket_value.size(); i<j; i++)
+        BOOST_CHECK_EQUAL( tlvPacket_value[i], i );
 }
 
+BOOST_AUTO_UNIT_TEST(tlvPacket_create_packet_with_simple_length)
+{
+    std::string payload ("Hello, world!");
+    TLVPacket tlvPacket (TLVPacket::create());
+    tlvPacket->type() = 42u;
+    DataPacket::createAfter( tlvPacket, payload );
+    tlvPacket.finalize();
+
+    BOOST_CHECK_EQUAL( tlvPacket->type(), 42u);
+    BOOST_CHECK_EQUAL( tlvPacket->length(), 13u);
+    
+    PacketData & tlvPacket_value (tlvPacket.next().data());
+    BOOST_CHECK( equal( tlvPacket_value.begin(), tlvPacket_value.end(), payload.begin() ));
+}
+
+/*
+BOOST_AUTO_UNIT_TEST(tlvPacket_create_packet_with_extended_length)
+{
+    std::string payload (
+            "This is a very long string with more than 127 characters to check if the TLV-Packet "
+            "works correctly with an extended length. That's all." );
+    TLVPacket tlvPacket (TLVPacket::create( payload.size() + 4 + 2));
+    tlvPacket->type() = 42u;
+    DataPacket::createAfter( tlvPacket, payload );
+    tlvPacket.finalize();
+        
+    BOOST_CHECK_EQUAL( tlvPacket->type(), 42u );
+    BOOST_CHECK_EQUAL( tlvPacket->length(), payload.size() );
+    
+    PacketData & tlvPacket_value (tlvPacket.next().data());
+   
+    BOOST_CHECK( equal( tlvPacket_value.begin(), tlvPacket_value.end(), payload.begin() ));
+}
+*/
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_