TLVPacket creating with changing HeaderSize doesn't work :(
[senf.git] / Packets / MPEGDVBBundle / TLVPacket.cc
index d93d5c2..270d81f 100644 (file)
@@ -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)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief DSMCCSection non-inline non-template implementation */
+    \brief TLVPacket non-inline non-template implementation */
 
 #include "TLVPacket.hh"
 //#include "TLVPacket.ih"
 
 // Custom includes
 #include <iomanip>
-#include "../../Utils/hexdump.hh"
-#include "../../Packets/DefaultBundle/EthernetPacket.hh"
-
+#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_ senf::PacketParserBase::size_type senf::Parse_TLVPacket::bytes()
-    const
-{
-    return 4 + senf::bytes( length() );
+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::init(packet p)
-//{
-//    p->init();
-//}
 
 prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
 {
@@ -57,14 +133,30 @@ prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
 
 prefix_ senf::PacketParserBase::size_type senf::TLVPacketType::initSize()
 {
-    return 4 + 1;
+    return 5;  // 4 bytes type + 1 byte length
+}
+
+prefix_ void senf::TLVPacketType::init(packet p)
+{
+    p->init();
 }
 
-prefix_ senf::PacketParserBase::size_type senf::TLVPacketType::initHeadSize()
+prefix_ void senf::TLVPacketType::finalize(packet p)
 {
-    return 4 + 1;
+    p->length() = p.next().data().size();
 }
 
+prefix_ senf::PacketInterpreterBase::optional_range 
+senf::TLVPacketType::nextPacketRange(packet p) 
+{
+    if (p.data().size() < 5)
+        return no_range();
+    return range(
+            boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
+            p.data().end() );
+}
+
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_