From: g0dil Date: Mon, 22 Sep 2008 19:33:23 +0000 (+0000) Subject: Packets: Extend finalize() API X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=078c34233b7d5ca7f9fd9dfb77568f840ad41915 Packets: Extend finalize() API git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@914 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/HowTos/NewPacket/Mainpage.dox b/HowTos/NewPacket/Mainpage.dox index 28403e0..0547543 100644 --- a/HowTos/NewPacket/Mainpage.dox +++ b/HowTos/NewPacket/Mainpage.dox @@ -939,7 +939,7 @@ senf::EthernetPacket eth (senf::EthernetPacket::create(senf::noinit)); isock.read(eth.data(),0u); GREPacket gre (senf::GREPacket::createBefore(eth)); - gre.finalize(); + gre.finalizeAll(); osock.write(gre.data()); } } diff --git a/Packets/DefaultBundle/EthernetPacket.test.cc b/Packets/DefaultBundle/EthernetPacket.test.cc index 3644b51..4c25433 100644 --- a/Packets/DefaultBundle/EthernetPacket.test.cc +++ b/Packets/DefaultBundle/EthernetPacket.test.cc @@ -83,12 +83,12 @@ BOOST_AUTO_UNIT_TEST(ethernetPacket_create) vlan->cfi() = true; vlan->vlanId() = 0x234u; - eth.finalize(); + eth.finalizeAll(); BOOST_CHECK_EQUAL(eth->type_length(), 0x8100u); BOOST_CHECK_EQUAL(vlan->type(), 0u); senf::IPv4Packet ip (senf::IPv4Packet::createAfter(vlan)); - eth.finalize(); + eth.finalizeAll(); BOOST_CHECK_EQUAL(vlan->type(), 0x0800u); } @@ -101,7 +101,7 @@ BOOST_AUTO_UNIT_TEST(ethernetPacket_llcsnap) senf::LlcSnapPacket llcsnap (senf::LlcSnapPacket::createAfter(eth)); senf::DataPacket payload (senf::DataPacket::createAfter( llcsnap, std::string("Hello, world!"))); - eth.finalize(); + eth.finalizeAll(); BOOST_CHECK_EQUAL( eth->type_length(), 8u + 13u); BOOST_CHECK_EQUAL( llcsnap->dsap(), 0xaa ); @@ -111,7 +111,7 @@ BOOST_AUTO_UNIT_TEST(ethernetPacket_llcsnap) BOOST_CHECK_EQUAL( llcsnap->type_length(), 0u); senf::IPv4Packet ip (senf::IPv4Packet::createAfter(llcsnap)); - eth.finalize(); + eth.finalizeAll(); BOOST_CHECK_EQUAL(llcsnap->type_length(), 0x0800u); } diff --git a/Packets/DefaultBundle/IPv4Packet.test.cc b/Packets/DefaultBundle/IPv4Packet.test.cc index b2a16e6..423e19f 100644 --- a/Packets/DefaultBundle/IPv4Packet.test.cc +++ b/Packets/DefaultBundle/IPv4Packet.test.cc @@ -77,13 +77,13 @@ BOOST_AUTO_UNIT_TEST(ipV4Packet_create) BOOST_CHECK( ! ip->validateChecksum() ); - ip.finalize(); + ip.finalizeAll(); BOOST_CHECK_EQUAL( ip->length(), 28u ); BOOST_CHECK_EQUAL( ip->protocol(), 17u ); BOOST_CHECK_EQUAL( ip->checksum(), 0xbad2 ); // Check, that the checksum field is correctly skipped - ip.finalize(); + ip.finalizeAll(); BOOST_CHECK_EQUAL( ip->checksum(), 0xbad2 ); BOOST_CHECK( ip->validateChecksum() ); diff --git a/Packets/DefaultBundle/LlcSnapPacket.test.cc b/Packets/DefaultBundle/LlcSnapPacket.test.cc index 6d9ec74..8f2bb4e 100644 --- a/Packets/DefaultBundle/LlcSnapPacket.test.cc +++ b/Packets/DefaultBundle/LlcSnapPacket.test.cc @@ -59,7 +59,7 @@ BOOST_AUTO_UNIT_TEST(llcSnapPacket_ethernet) senf::EthernetPacket eth (senf::EthernetPacket::createAfter(llcsnap)); senf::DataPacket payload (senf::DataPacket::createAfter( eth, std::string("Hello, world!"))); - llcsnap.finalize(); + llcsnap.finalizeAll(); BOOST_CHECK_EQUAL( llcsnap->dsap(), 0xaa ); BOOST_CHECK_EQUAL( llcsnap->ssap(), 0xaa ); diff --git a/Packets/DefaultBundle/UDPPacket.test.cc b/Packets/DefaultBundle/UDPPacket.test.cc index ca2f000..6df9409 100644 --- a/Packets/DefaultBundle/UDPPacket.test.cc +++ b/Packets/DefaultBundle/UDPPacket.test.cc @@ -73,7 +73,7 @@ BOOST_AUTO_UNIT_TEST(udpPacket_create) // validates, since the checksum is 0 and thus ignored ! BOOST_CHECK( udp->validateChecksum() ); - ip.finalize(); + ip.finalizeAll(); BOOST_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), ip.data().begin(), ip.data().end() ); BOOST_CHECK( udp->validateChecksum() ); diff --git a/Packets/MPEGDVBBundle/MPESection.test.cc b/Packets/MPEGDVBBundle/MPESection.test.cc index 91ba677..311c6da 100644 --- a/Packets/MPEGDVBBundle/MPESection.test.cc +++ b/Packets/MPEGDVBBundle/MPESection.test.cc @@ -164,7 +164,7 @@ BOOST_AUTO_UNIT_TEST(MPESection_create) }; senf::DataPacket payload (senf::DataPacket::createAfter(ip, payload_data)); - sec.finalize(); + sec.finalizeAll(); unsigned char sec_data[] = { 0x3e, 0xb0, 0x77, 0x00, 0x00, 0xc3, 0x00, 0x00, diff --git a/Packets/MPEGDVBBundle/TLVPacket.test.cc b/Packets/MPEGDVBBundle/TLVPacket.test.cc index e454827..5fd157f 100644 --- a/Packets/MPEGDVBBundle/TLVPacket.test.cc +++ b/Packets/MPEGDVBBundle/TLVPacket.test.cc @@ -94,7 +94,7 @@ BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_simple_length) TestTLVPacket tlvPacket (TestTLVPacket::create()); tlvPacket->type() = 42u; DataPacket::createAfter( tlvPacket, payload ); - tlvPacket.finalize(); + tlvPacket.finalizeAll(); BOOST_CHECK_EQUAL( tlvPacket->type(), 42u); BOOST_CHECK_EQUAL( tlvPacket->length(), 13u); @@ -113,7 +113,7 @@ BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_extended_length) TestTLVPacket tlvPacket (TestTLVPacket::create()); tlvPacket->type() = 42u; DataPacket::createAfter( tlvPacket, payload ); - tlvPacket.finalize(); + tlvPacket.finalizeAll(); BOOST_CHECK_EQUAL( tlvPacket->type(), 42u ); BOOST_CHECK_EQUAL( tlvPacket->length(), payload.size() ); @@ -123,7 +123,7 @@ BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_extended_length) payload = std::string("This is a short string with less than 127 characters. That's all."); DataPacket::createAfter( tlvPacket, payload ); - tlvPacket.finalize(); + tlvPacket.finalizeAll(); BOOST_CHECK_EQUAL( tlvPacket->type(), 42u ); BOOST_CHECK_EQUAL( tlvPacket->length(), payload.size() ); @@ -186,7 +186,7 @@ void test_TLVFixPacket_creating() TLVFixPacketType tlvPacket (TLVFixPacketType::create()); tlvPacket->type() = 42u; DataPacket::createAfter( tlvPacket, payload ); - tlvPacket.finalize(); + tlvPacket.finalizeAll(); BOOST_CHECK_EQUAL( tlvPacket->type(), 42u); BOOST_CHECK_EQUAL( tlvPacket->length(), 13u); @@ -216,7 +216,7 @@ void test_invalid_TLVFixPacket_creating(boost::uint32_t max_value) tlvPacket->type() = 42u; DataPacket payload (DataPacket::createAfter( tlvPacket, max_value+1)); //DataPacket::createAfter( payload, 1); // this is one byte to much. - BOOST_CHECK_THROW( tlvPacket.finalize(), UnsuportedTLVPacketException); + BOOST_CHECK_THROW( tlvPacket.finalizeAll(), UnsuportedTLVPacketException); } BOOST_AUTO_UNIT_TEST(TLVFixPacket_create_invalid_packet) diff --git a/Packets/Mainpage.dox b/Packets/Mainpage.dox index 6ae0de7..cfa8e30 100644 --- a/Packets/Mainpage.dox +++ b/Packets/Mainpage.dox @@ -201,7 +201,7 @@ eth->source() = senf::MACAddress::from_string("00:11:22:33:44:55"); eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66"); - eth.finalize(); + eth.finalizeAll(); \endcode Again, realize, that \a eth, \a ip, \a udp and \a payload share the same internal packet @@ -274,12 +274,12 @@ eth->source() = senf::MACAddress::from_string("00:11:22:33:44:55"); eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66"); - eth.finalize(); + eth.finalizeAll(); \endcode As seen above, packet fields are accessed using the -> operator whereas other packet - facilities (like \c finalize()) are directly accessed using the member operator. The field - values are simply set using appropriately named accessors. As a last step, the \c finalize() + facilities (like \c finalizeAll()) are directly accessed using the member operator. The field + values are simply set using appropriately named accessors. As a last step, the \c finalizeAll() call will update all calculated fields (fields like next-protocol, header or payload length, checksums etc). Now the packet is ready. We may now send it out using a packet socket diff --git a/Packets/Packet.cci b/Packets/Packet.cci index f02dabd..35bd931 100644 --- a/Packets/Packet.cci +++ b/Packets/Packet.cci @@ -137,11 +137,19 @@ prefix_ bool senf::Packet::operator==(Packet other) return ptr() == other.ptr(); } -prefix_ void senf::Packet::finalize() - const +prefix_ void senf::Packet::finalizeThis() { - last(); // Make sure the packet is complete - ptr()->finalize(); + ptr()->finalizeThis(); +} + +prefix_ void senf::Packet::finalizeTo(Packet other) +{ + ptr()->finalizeTo(other.ptr()); +} + +prefix_ void senf::Packet::finalizeAll() +{ + ptr()->finalizeTo(last().ptr()); } prefix_ void senf::Packet::dump(std::ostream & os) diff --git a/Packets/Packet.cti b/Packets/Packet.cti index 6dec365..fac31c0 100644 --- a/Packets/Packet.cti +++ b/Packets/Packet.cti @@ -128,6 +128,13 @@ prefix_ OtherPacket senf::Packet::first() return first().as(); } +template +prefix_ void senf::Packet::finalizeTo() +{ + Packet p (find(nothrow)); + ptr()->finalizeTo(p ? p.ptr() : last().ptr()); +} + /////////////////////////////////////////////////////////////////////////// // senf::ConcretePacket diff --git a/Packets/Packet.hh b/Packets/Packet.hh index f08a996..af45ff2 100644 --- a/Packets/Packet.hh +++ b/Packets/Packet.hh @@ -330,15 +330,50 @@ namespace senf { This is an alias for boolean_test() which is called when using a packet in a boolean context. */ - void finalize() const; ///< Update calculated fields + void finalizeThis(); ///< Update calculated fields /**< This call will update all calculated fields of the - packet after it has been created or changed. This - includes checksums, payload size fields or other - fields, which can be set from other information in the - packet. Each concrete packet type should document, - which fields are set by finalize(). + packet. This includes checksums, payload size fields or + other fields, which can be set from other information + in the packet. Each concrete packet type should + document, which fields are set by finalize(). + + finalizeThis() will \e only process the current + header. Even if only changing fields in this protocol, + depending on the protocol it may not be enough to + finalize this header only. See the packet type + documentation. */ + + template + void finalizeTo(); ///< Update calculated fields + /**< This call will update all calculated fields of the + packet. This includes checksums, payload size fields or + other fields, which can be set from other information + in the packet. Each concrete packet type should + document, which fields are set by finalize(). + + finalizeTo() will automatically process all + packets/headers/interpreters from the first occurrence + of packet type \a Other backwards up to \c this. */ + + void finalizeTo(Packet other); ///< Update calculated fields + /**< This call will update all calculated fields of the + packet. This includes checksums, payload size fields or + other fields, which can be set from other information + in the packet. Each concrete packet type should + document, which fields are set by finalize(). + + finalizeAll(other) will automatically process all + packets/headers/interpreters from \a other backwards up + to \c this. */ + + void finalizeAll(); ///< Update calculated fields + /**< This call will update all calculated fields of the + packet. This includes checksums, payload size fields or + other fields, which can be set from other information + in the packet. Each concrete packet type should + document, which fields are set by finalize(). - finalize() will automatically process all + finalizeAll() will automatically process all packets/headers/interpreters from the end of the chain backwards up to \c this. */ diff --git a/Packets/Packet.test.cc b/Packets/Packet.test.cc index 937901c..2da754d 100644 --- a/Packets/Packet.test.cc +++ b/Packets/Packet.test.cc @@ -159,11 +159,11 @@ BOOST_AUTO_UNIT_TEST(packet) packet.dump(s); BOOST_CHECK_EQUAL( s.str(), "BarPacket:\ntype: 0\nlength: 0\n" ); - packet.finalize(); + packet.finalizeAll(); BOOST_CHECK_EQUAL( packet.last().as()->type(), BarPacket::type::parser::type_t::value_type(-1) ); packet.last().append(FooPacket::create()); - packet.finalize(); + packet.finalizeAll(); BOOST_CHECK_EQUAL( packet.find()->type(), 1u ); BOOST_CHECK( packet.factory() == FooPacket::factory() ); diff --git a/Packets/PacketInterpreter.cc b/Packets/PacketInterpreter.cc index 3d8a382..466ba1f 100644 --- a/Packets/PacketInterpreter.cc +++ b/Packets/PacketInterpreter.cc @@ -79,13 +79,18 @@ prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os) i->v_dump(os); } -prefix_ void senf::PacketInterpreterBase::finalize() +prefix_ void senf::PacketInterpreterBase::finalizeThis() { - for (ptr i (last()) ; i.get() != this ; i = i->prev()) - i->v_finalize(); v_finalize(); } +prefix_ void senf::PacketInterpreterBase::finalizeTo(ptr other) +{ + for (ptr i (other); i.get() != this && i.get(); i = i->prev()) + i->finalizeThis(); + finalizeThis(); +} + /////////////////////////////////////////////////////////////////////////// // senf::PacketInterpreterBase::Factory diff --git a/Packets/PacketInterpreter.hh b/Packets/PacketInterpreter.hh index b42cb19..24f29c2 100644 --- a/Packets/PacketInterpreter.hh +++ b/Packets/PacketInterpreter.hh @@ -166,7 +166,8 @@ namespace senf { ///@{ optional_range nextPacketRange(); - void finalize(); + void finalizeThis(); + void finalizeTo(ptr other); void dump(std::ostream & os); TypeIdValue typeId(); factory_t factory();