Packets/80221Bundle: just another fix for DynamicTLVLengthParser
[senf.git] / Packets / 80221Bundle / TLVPacket.cc
index 5c7c0da..5a17ac7 100644 (file)
 
 // Custom includes
 #include <iomanip>
-#include <senf/Utils/hexdump.hh>
+#include "../../Utils/hexdump.hh"
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+prefix_ senf::safe_data_iterator senf::BaseTLVPacketParser::resizeValueField(
+        DynamicTLVLengthParser::value_type size) 
+{
+    DynamicTLVLengthParser::value_type current_length ( length());
+    length( size);
+
+    safe_data_iterator si (data(), boost::next(i(), 1 + length_bytes() ));
+    if (current_length > size)
+        data().erase( si, boost::next(si, current_length-size));
+    else
+        data().insert( si, size-current_length, 0);
+    return si;
+}
+
+
 prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::value() const 
 {
     switch (bytes() ) {
     case 1:
-        return fixed_length_field().value();
+        return length_field().value();
     case 2:
-        return parse<UInt8Parser>( 1 ).value();
+        return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
     case 3:
-        return parse<UInt16Parser>( 1 ).value();
+        return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
     case 4:
-        return parse<UInt24Parser>( 1 ).value();
+        return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
     case 5:
-        return parse<UInt32Parser>( 1 ).value();
+        return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
     default:
         throw(TLVLengthException());
     };
@@ -56,27 +71,28 @@ prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
 {
     switch (bytes() ) {
     case 1:
-        if (v > 127) throw( TLVLengthException());
-        fixed_length_field() = v;
+        if (v > 128) throw( TLVLengthException());
+        length_field() = v;
         return;
     case 2:
-        if (v > UInt8Parser::max_value) throw( TLVLengthException());
-        parse<UInt8Parser>(1) = v;
-        return;
+        if (v > UInt8Parser::max_value + 128) throw( TLVLengthException());
+        parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
+        break;
     case 3:
-        if (v > UInt16Parser::max_value) throw( TLVLengthException());
-        parse<UInt16Parser>(1) = v;
-        return;
+        if (v > UInt16Parser::max_value + 128) throw( TLVLengthException());
+        parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
+        break;;
     case 4:
-        if (v > UInt24Parser::max_value) throw( TLVLengthException());
-        parse<UInt24Parser>(1) = v;
-        return;
+        if (v > UInt24Parser::max_value + 128) throw( TLVLengthException());
+        parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
+        break;
     case 5:
-        parse<UInt32Parser>(1) = v;
-        return;
+        parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
+        break;
     default:
         throw( TLVLengthException());
     };
+    underflow_flag() = v < 128;
 }
 
 
@@ -87,15 +103,6 @@ prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::opera
 }
 
 
-prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const 
-{
-    if ( extended_length_flag() )
-        return 1 + fixed_length_field();
-    else
-        return 1;
-}
-    
-
 prefix_ void senf::DynamicTLVLengthParser::init() const 
 {
     defaultInit();
@@ -107,19 +114,19 @@ prefix_ void senf::DynamicTLVLengthParser::shrink()
 {
     value_type v = value();
     size_type b = bytes();
-    if (v <= 127) {
+    if (v <= 128) {
         if (b != 1) resize(1);
         return;
     }
-    if (v <= UInt8Parser::max_value) {
+    if (v <= UInt8Parser::max_value + 128) {
         if (b != 2) resize(2);
         return;
     }
-    if (v <= UInt16Parser::max_value) {
+    if (v <= UInt16Parser::max_value + 128) {
         if (b != 3) resize(3);
         return;
     }
-    if (v <= UInt24Parser::max_value) {
+    if (v <= UInt24Parser::max_value + 128 ){
         if (b != 4) resize(4);
         return;
     }
@@ -127,34 +134,24 @@ prefix_ void senf::DynamicTLVLengthParser::shrink()
 }
 
 
-prefix_ void senf::BaseTLVPacketParser:: maxLengthValue(DynamicTLVLengthParser::value_type v)
-    const
+prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v)
 {
-    if (v <= 127)
+    if (v <= 128)
         return;
-    size_type b = senf::bytes( length_());
-    if (v <= UInt8Parser::max_value) {
-        if (b < 2) length_().resize(2);
+    size_type b = bytes();
+    if (v <= UInt8Parser::max_value + 128) {
+        if (b < 2) resize(2);
         return;
     }
-    if (v <= UInt16Parser::max_value) {
-        if (b < 3) length_().resize(3);
+    if (v <= UInt16Parser::max_value + 128) {
+        if (b < 3) resize(3);
         return;
     }
-    if (v <= UInt24Parser::max_value) {
-        if (b < 4) length_().resize(4);
+    if (v <= UInt24Parser::max_value + 128) {
+        if (b < 4) resize(4);
         return;
     }
-    if (b < 5) length_().resize(5);
-}
-
-
-prefix_ senf::PacketInterpreterBase::range senf::GenericTLVPacketParser::value() 
-    const
-{
-    senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_bytes() ));
-    return PacketInterpreterBase::range(
-            begin, boost::next( begin, length()) );
+    if (b < 5) resize(5);
 }
 
 
@@ -164,11 +161,10 @@ prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
     size_type current_size (bytes());
     SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
     
-    safe_data_iterator si (data(), i());
     if (current_size > size)
-        data().erase( si, boost::next(si, current_size-size));
+        data().erase( i(), boost::next(i(), current_size-size));
     else
-        data().insert( si, size-current_size, 0);
+        data().insert( i(), size-current_size, 0);
     
     if (size > 1) {
         safeThis->extended_length_flag() = true;
@@ -176,7 +172,16 @@ prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
     } else {
         safeThis->extended_length_flag() = false;
     }
-    value(v);
+    safeThis->value(v);
+}
+
+
+prefix_ senf::PacketInterpreterBase::range senf::GenericTLVPacketParser::value() 
+    const
+{
+    senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_bytes() ));
+    return PacketInterpreterBase::range(
+            begin, boost::next( begin, length()) );
 }