From: tho Date: Thu, 8 Oct 2009 14:35:42 +0000 (+0000) Subject: Packets: first steps for a generic TLV base class X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=a79c5e98760ea8232c13d8266eb7ca0ac5cdefd3;hp=5615d25d63a162a6aa3cde53448277da1842a223;p=senf.git Packets: first steps for a generic TLV base class git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1480 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/GenericTLV.ct b/senf/Packets/GenericTLV.ct new file mode 100644 index 0000000..6a90553 --- /dev/null +++ b/senf/Packets/GenericTLV.ct @@ -0,0 +1,81 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief GenericTLV non-inline template implementation */ + +//#include "GenericTLV.ih" + +// Custom includes + +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +template +template +prefix_ Parser senf::GenericTLVParserBase::init() +{ + senf::PacketParserBase::size_type oldSize (bytes() ); + senf::PacketParserBase::size_type newParserSize ( senf::init_bytes::value ); + this->resize( oldSize, newParserSize); + std::fill(this->i(), boost::next(this->i(), newParserSize), 0u); + Parser concreteParser = Parser(this->i(), this->state() ); + concreteParser.init(); +// concreteParser.length() = newParserSize - senf::init_bytes::value; + return concreteParser; +} + +template +prefix_ senf::PacketInterpreterBase::range senf::GenericTLVParserBase::value() + const +{ + senf::PacketData::iterator begin (boost::next(this->i(), senf::init_bytes::value )); + return PacketInterpreterBase::range(begin, boost::next( begin, this->length()) ); +} + +template +template +prefix_ void senf::GenericTLVParserBase::value_(ForwardReadableRange const &range) +{ + unsigned int rangeSize = boost::size(range); + if ( rangeSize != this->length() ) + resize( bytes(), rangeSize + senf::init_bytes::value ); + std::copy( boost::begin(range), boost::end(range), boost::next( + this->i(), senf::init_bytes::value)); + this->length_() = rangeSize; +} + + + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Packets/GenericTLV.cti b/senf/Packets/GenericTLV.cti new file mode 100644 index 0000000..f66eec3 --- /dev/null +++ b/senf/Packets/GenericTLV.cti @@ -0,0 +1,100 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief GenericTLV inline template implementation */ + +//#include "GenericTLV.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template +prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserBase::bytes() +{ + return senf::init_bytes::value + this->length(); +} + +template +prefix_ void senf::GenericTLVParserBase::init() + const +{ + this->defaultInit(); +} + +template +template +prefix_ Parser senf::GenericTLVParserBase::as() +{ + return Parser(this->i(), this->state() ); +} + +template +template +prefix_ bool senf::GenericTLVParserBase::is() +{ + return this->type().value() == Parser::TYPEID; +} + +template +template +prefix_ void senf::GenericTLVParserBase::value( + ForwardReadableRange const & val, + typename boost::disable_if >::type *) +{ + value_( val); +} + +template +template +prefix_ void senf::GenericTLVParserBase::value( + std::pair const & val, + typename boost::disable_if >::type *) +{ + value_( val); +} + +template +template +prefix_ void senf::GenericTLVParserBase::value( + std::pair const & val, + typename boost::enable_if >::type *) +{ + this->type() = val.first; + value_( val.second); +} + +///////////////////////////////cti.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Packets/GenericTLV.hh b/senf/Packets/GenericTLV.hh new file mode 100644 index 0000000..894d728 --- /dev/null +++ b/senf/Packets/GenericTLV.hh @@ -0,0 +1,93 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief GenericTLV public header */ + +#ifndef HH_SENF_Packets_GenericTLV_ +#define HH_SENF_Packets_GenericTLV_ 1 + +// Custom includes +#include +#include + +//#include "GenericTLV.hh.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + template + class GenericTLVParserBase : public Base + { + public: + GenericTLVParserBase(senf::PacketParserBase::data_iterator i, senf::PacketParserBase::state_type s) + : Base(i,s) {} + + senf::PacketParserBase::size_type bytes(); + void init() const; + + template + Parser init(); + + template + Parser as(); + + template + bool is(); + + senf::PacketInterpreterBase::range value() const; + + template + void value(ForwardReadableRange const & val, + typename boost::disable_if >::type * = 0); + + template + void value(std::pair const & val, + typename boost::disable_if >::type * = 0); + + template + void value(std::pair const & val, + typename boost::enable_if >::type * = 0); + + private: + template + void value_(ForwardReadableRange const &range); + }; +} + + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "GenericTLV.cci" +#include "GenericTLV.ct" +#include "GenericTLV.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Packets/GenericTLV.test.cc b/senf/Packets/GenericTLV.test.cc new file mode 100644 index 0000000..84be10c --- /dev/null +++ b/senf/Packets/GenericTLV.test.cc @@ -0,0 +1,156 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// @AUTHOR@ +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief GenericTLV unit tests */ + +// Custom includes +#include "GenericTLV.hh" +#include + +#include +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + struct MyTLVParserBase + : public senf::PacketParserBase + { +# include SENF_PARSER() + SENF_PARSER_FIELD ( type, senf::UInt8Parser ); + SENF_PARSER_FIELD_RO ( length, senf::UInt8Parser ); + SENF_PARSER_FINALIZE ( MyTLVParserBase ); + }; + + struct MyGenericTLVParser + : public senf::GenericTLVParserBase + { + typedef senf::GenericTLVParserBase base; + MyGenericTLVParser(data_iterator i, state_type s) : base(i,s) {} + }; + + struct MyConcreteTLVParser + : public MyTLVParserBase + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MyTLVParserBase ); + SENF_PARSER_FIELD ( myValue, senf::UInt32Parser ); + SENF_PARSER_FINALIZE ( MyConcreteTLVParser ); + + SENF_PARSER_INIT() { + type() = TYPEID; + length_() = 4; + } + static const type_t::value_type TYPEID = 0x42; + }; + + class MyTestPacketParser + : public senf::PacketParserBase + { +# include SENF_PARSER() + SENF_PARSER_FIELD_RO ( list_length, senf::UInt8Parser ); + SENF_PARSER_LIST ( tlv_list, list_length, MyGenericTLVParser ); + SENF_PARSER_FINALIZE ( MyTestPacketParser ); + }; + + struct MyTestPacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin + { + typedef senf::PacketTypeMixin mixin; + typedef MyTestPacketParser parser; + + using mixin::nextPacketRange; + using mixin::init; + using mixin::initSize; + }; + typedef senf::ConcretePacket MyTestPacket; +} + + +BOOST_AUTO_UNIT_TEST(GenericTLV_parser) +{ + BOOST_CHECK_EQUAL( senf::init_bytes::value, + senf::init_bytes::value) ; + + unsigned char data[] = { + 0x42, 0x04, // type, length + 0x00, 0x01, 0x02, 0x03 // value + }; + + senf::DataPacket dataPacket ( senf::DataPacket::create(data)); + MyGenericTLVParser genericTLVParser (dataPacket.data().begin(), &dataPacket.data()); + + BOOST_CHECK_EQUAL( senf::bytes( genericTLVParser), sizeof(data) ); + BOOST_CHECK_EQUAL( genericTLVParser.type(), 0x42 ); + BOOST_CHECK_EQUAL( genericTLVParser.length(), 0x04 ); + SENF_CHECK_EQUAL_COLLECTIONS( data+2, data+sizeof(data), + genericTLVParser.value().begin(), genericTLVParser.value().end() ); + genericTLVParser.value( data ); + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + genericTLVParser.value().begin(), genericTLVParser.value().end() ); + + std::vector value (4, 0xab); + genericTLVParser.value( std::make_pair(0x42, value)); + + BOOST_CHECK( genericTLVParser.is()); + + MyConcreteTLVParser concreteTLVParser ( genericTLVParser.as()); + BOOST_CHECK_EQUAL( concreteTLVParser.type(), 0x42 ); + BOOST_CHECK_EQUAL( concreteTLVParser.length(), 0x04 ); + BOOST_CHECK_EQUAL( concreteTLVParser.myValue(), 0xabababab ); +} + +BOOST_AUTO_UNIT_TEST(GenericTLV_packet) +{ + MyTestPacket p ( MyTestPacket::create()); + MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() ); + MyConcreteTLVParser tlv ( tlvContainer.push_back_space().init()); + tlv.myValue() << 0xffff; + p.finalizeThis(); + + unsigned char data[] = { + 0x01, // tlv list length + // first tlv: + 0x42, 0x04, // type, length + 0x00, 0x00, 0xff, 0xff // value + }; + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + p.data().begin(), p.data().end() ); +} + + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: