NEW FILE HEADER / COPYRIGHT FORMAT
[senf.git] / Packets / MPEGDVBBundle / TLVPacket.cc
index 8d24a3f..42e0dd6 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 //
 // Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Thorsten Horstmann <thorsten.horstmann@fokus.fraunhofer.de>
+// Fraunhofer Institute for Open Communication Systems (FOKUS) 
+// Competence Center NETwork research (NET), St. Augustin, GERMANY 
+//     Thorsten Horstmann <tho@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 
 // Custom includes
 #include <iomanip>
-
+#include <senf/Utils/hexdump.hh>
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ void senf::TLVPacketType::dump(packet p, std::ostream & os)
+prefix_ senf::TLVPacketLengthParser::value_type senf::TLVPacketLengthParser::value() const 
+{
+    switch (bytes() ) {
+    case 1:
+        return fixed_length_field().value();
+    case 2:
+        return parse<UInt8Parser>( 1 ).value();
+    case 3:
+        return parse<UInt16Parser>( 1 ).value();
+    case 4:
+        return parse<UInt24Parser>( 1 ).value();
+    case 5:
+        return parse<UInt32Parser>( 1 ).value();
+    default:
+        throw(UnsuportedTLVPacketException());
+    };
+}
+
+prefix_ void senf::TLVPacketLengthParser::value(value_type const & v) 
+{
+    if (v > 4294967295u)
+        throw(UnsuportedTLVPacketException());
+    
+    SafePacketParserWrapper<TLVPacketLengthParser> safeThis (*this);
+    if (v < 128u) {
+        if (bytes() != 1) {
+            resize(1);
+            safeThis->extended_length_flag() = false;
+        }
+        safeThis->fixed_length_field() = v;
+        return;
+    }
+    if (v < 256u) {
+        if (bytes() != 2) {
+           resize(2);
+            safeThis->extended_length_flag() = true;
+           safeThis->fixed_length_field() = 1;
+       }
+        safeThis->parse<UInt8Parser>(1) = v;
+        return;
+    }
+    if (v < 65536u) {
+        if (bytes() != 3) {
+           resize(3);
+           safeThis->extended_length_flag() = true;
+           safeThis->fixed_length_field() = 2;
+       }
+        safeThis->parse<UInt16Parser>(1) = v;
+        return;
+    }
+    if (v < 16777216u) {
+        if (bytes() != 4) {
+           resize(4);
+           safeThis->extended_length_flag() = true;
+           safeThis->fixed_length_field() = 3;
+       }
+        safeThis->parse<UInt24Parser>(1) = v;
+        return;
+    }
+    if (v <= 4294967295u) {
+        if (bytes() != 5) {
+           resize(5);
+           safeThis->extended_length_flag() = true;
+           safeThis->fixed_length_field() = 4;
+       }
+        safeThis->parse<UInt32Parser>(1) = v;
+        return;
+    }
+}
+
+prefix_ senf::TLVPacketLengthParser const & senf::TLVPacketLengthParser::operator= (value_type other) 
+{
+    value(other);
+    return *this; 
+}
+
+prefix_ senf::TLVPacketLengthParser::size_type senf::TLVPacketLengthParser::bytes() const 
+{
+    if ( extended_length_flag() )
+        return 1 + fixed_length_field();
+    else
+        return 1;
+}
+    
+prefix_ void senf::TLVPacketLengthParser::init() const 
 {
-    os << "TLVPacket:\n"
-       << std::dec
-       << "  type: " <<  unsigned(p->type()) << "\n"
-       << "  length: " << unsigned(p->length()) << "\n";
+    defaultInit();
+    extended_length_flag() = 0;
 }
 
-prefix_ senf::PacketInterpreterBase::optional_range 
-senf::TLVPacketType::nextPacketRange(packet p) 
+prefix_ void senf::TLVPacketLengthParser::resize(size_type size) 
 {
-    if (p.data().size() < 6)
-        return no_range();
-    return range(
-            boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
-            p.data().end() );
+    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);
 }