X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2F80221Bundle%2FTLVPacket.cc;h=12d9bfdb4d00a4007bdfedd071f54f2c70bf5962;hb=b8ca4a544cce3e6023bb56b712a03d6362f2bb79;hp=de06d6181dc5066ffc4b2184415200fde1456154;hpb=32be66071113df31a085821e31414eeb776022fa;p=senf.git diff --git a/Packets/80221Bundle/TLVPacket.cc b/Packets/80221Bundle/TLVPacket.cc index de06d61..12d9bfd 100644 --- a/Packets/80221Bundle/TLVPacket.cc +++ b/Packets/80221Bundle/TLVPacket.cc @@ -28,11 +28,26 @@ // Custom includes #include -#include +#include "../../Utils/hexdump.hh" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ senf::safe_data_iterator senf::BaseTLVPacketParser::resizeValue( + 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() ) { @@ -47,68 +62,46 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v case 5: return parse( 1 ).value(); default: - throw(UnsuportedTLVPacketException()); + throw(TLVLengthException()); }; } + prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) { - if (v > 4294967295u) - throw(UnsuportedTLVPacketException()); - - SafePacketParserWrapper safeThis (*this); - if (v < 128u) { - if (bytes() != 1) { - resize(1); - safeThis->extended_length_flag() = false; - } - safeThis->fixed_length_field() = v; + switch (bytes() ) { + case 1: + if (v > 127) throw( TLVLengthException()); + 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(1) = v; + case 2: + if (v > UInt8Parser::max_value) throw( TLVLengthException()); + parse(1) = v; return; - } - if (v < 65536u) { - if (bytes() != 3) { - resize(3); - safeThis->extended_length_flag() = true; - safeThis->fixed_length_field() = 2; - } - safeThis->parse(1) = v; + case 3: + if (v > UInt16Parser::max_value) throw( TLVLengthException()); + parse(1) = v; return; - } - if (v < 16777216u) { - if (bytes() != 4) { - resize(4); - safeThis->extended_length_flag() = true; - safeThis->fixed_length_field() = 3; - } - safeThis->parse(1) = v; + case 4: + if (v > UInt24Parser::max_value) throw( TLVLengthException()); + parse(1) = v; return; - } - if (v <= 4294967295u) { - if (bytes() != 5) { - resize(5); - safeThis->extended_length_flag() = true; - safeThis->fixed_length_field() = 4; - } - safeThis->parse(1) = v; + case 5: + parse(1) = v; return; - } + default: + throw( TLVLengthException()); + }; } + prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other) { value(other); return *this; } + prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const { if ( extended_length_flag() ) @@ -117,21 +110,104 @@ prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::by return 1; } + prefix_ void senf::DynamicTLVLengthParser::init() const { defaultInit(); - extended_length_flag() = 0; + extended_length_flag() = false; +} + + +prefix_ void senf::DynamicTLVLengthParser::shrink() +{ + value_type v = value(); + size_type b = bytes(); + if (v <= 127) { + if (b != 1) resize(1); + return; + } + if (v <= UInt8Parser::max_value) { + if (b != 2) resize(2); + return; + } + if (v <= UInt16Parser::max_value) { + if (b != 3) resize(3); + return; + } + if (v <= UInt24Parser::max_value) { + if (b != 4) resize(4); + return; + } + if (b != 5) resize(5); +} + + +prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v) +{ + if (v <= 127) + return; + size_type b = bytes(); + if (v <= UInt8Parser::max_value) { + if (b < 2) resize(2); + return; + } + if (v <= UInt16Parser::max_value) { + if (b < 3) resize(3); + return; + } + if (v <= UInt24Parser::max_value) { + if (b < 4) resize(4); + return; + } + if (b < 5) resize(5); } -prefix_ void senf::DynamicTLVLengthParser::resize(size_type size) + +prefix_ void senf::DynamicTLVLengthParser::resize(size_type size) { + value_type v = value(); size_type current_size (bytes()); - safe_data_iterator si (data(), i()); + SafePacketParserWrapper safeThis (*this); 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; + safeThis->fixed_length_field() = size - 1; + } else { + safeThis->extended_length_flag() = false; + } + 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()) ); +} + + +prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os) +{ + boost::io::ios_all_saver ias(os); + os << "GenericTLVPacket:\n" + << std::dec + << " type: " << unsigned( p->type()) << "\n" + << " length: " << unsigned( p->length()) << "\n" + << " value\n:"; + senf::hexdump( p->value().begin(), p->value().end(), os); +} + + +prefix_ void senf::GenericTLVPacketType::finalize(packet p) +{ + p->shrinkLength(); }