From: g0dil Date: Fri, 30 Apr 2010 10:35:53 +0000 (+0000) Subject: Packet: Implement createInsertBefore() API X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=3a3350157a52c268d5082a4aac4aba643417071f;p=senf.git Packet: Implement createInsertBefore() API git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1610 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/Packet.cti b/senf/Packets/Packet.cti index 8e56512..21600c6 100644 --- a/senf/Packets/Packet.cti +++ b/senf/Packets/Packet.cti @@ -267,6 +267,20 @@ senf::ConcretePacket::createBefore(Packet const & packet, senf::NoIn return ConcretePacket(interpreter::createBefore(packet.ptr(), senf::noinit)); } +template +prefix_ senf::ConcretePacket +senf::ConcretePacket::createInsertBefore(Packet const & packet) +{ + return ConcretePacket(interpreter::createInsertBefore(packet.ptr())); +} + +template +prefix_ senf::ConcretePacket +senf::ConcretePacket::createInsertBefore(Packet const & packet, senf::NoInit_t) +{ + return ConcretePacket(interpreter::createInsertBefore(packet.ptr(), senf::noinit)); +} + // Create a clone of the current packet template diff --git a/senf/Packets/Packet.hh b/senf/Packets/Packet.hh index ffe8d5d..00b00f7 100644 --- a/senf/Packets/Packet.hh +++ b/senf/Packets/Packet.hh @@ -172,9 +172,9 @@ namespace senf { template Packet(ConcretePacket packet); ///< Copy-construct Packet from ConcretePacket - /**< This constructor allows to convert an arbitrary - ConcretePacket into a general Packet, loosing the - protocol specific interface. */ + /**< This constructor allows to convert an arbitrary + ConcretePacket into a general Packet, loosing the + protocol specific interface. */ ///@} /////////////////////////////////////////////////////////////////////////// @@ -182,129 +182,124 @@ namespace senf { ///\name Interpreter chain access ///@{ - Packet next() const; - ///< Get next packet in chain - /**< \throws InvalidPacketChainException if no next packet - exists */ - Packet next(NoThrow_t) const; - ///< Get next packet in chain - /**< \returns in - valid() packet if no next packet - exists */ + Packet next() const; ///< Get next packet in chain + /**< \throws InvalidPacketChainException if no next packet + exists */ + Packet next(NoThrow_t) const; ///< Get next packet in chain + /**< \returns in - valid() packet if no next packet + exists */ template OtherPacket next() const; - ///< Get next packet in chain and cast to \a OtherPacket - /**< \throws std::bad_cast if the next() packet is not of - type \a OtherPacket - \throws InvalidPacketChainException if no next packet - exists */ + ///< Get next packet in chain and cast to \a OtherPacket + /**< \throws std::bad_cast if the next() packet is not of + type \a OtherPacket + \throws InvalidPacketChainException if no next packet + exists */ template OtherPacket next(NoThrow_t) const; - ///< Get next packet in chain and cast to \a OtherPacket - /**< \throws std::bad_cast if the next() packet is not of - type \a OtherPacket - \returns in - valid() packet if no next packet - exists */ + ///< Get next packet in chain and cast to \a OtherPacket + /**< \throws std::bad_cast if the next() packet is not of + type \a OtherPacket + \returns in - valid() packet if no next packet + exists */ template OtherPacket find() const; - ///< Search chain forward for packet of type \a OtherPacket - /**< The search will start with the current packet. - \throws InvalidPacketChainException if no packet of - type \a OtherPacket can be found. */ + ///< Search chain forward for packet of type \a OtherPacket + /**< The search will start with the current packet. + \throws InvalidPacketChainException if no packet of + type \a OtherPacket can be found. */ template OtherPacket find(NoThrow_t) const; - ///< Search chain forward for packet of type \a OtherPacket - /**< The search will start with the current packet. - \returns in - valid() packet if no packet of type \a - OtherPacket can be found. */ - - Packet prev() const; - ///< Get previous packet in chain - /**< \throws InvalidPacketChainException if no previous - packet exists */ - Packet prev(NoThrow_t) const; - ///< Get previous packet in chain - /**< \returns in - valid() packet if no previous packet - exists */ + ///< Search chain forward for packet of type \a OtherPacket + /**< The search will start with the current packet. + \returns in - valid() packet if no packet of type \a + OtherPacket can be found. */ + + Packet prev() const; ///< Get previous packet in chain + /**< \throws InvalidPacketChainException if no previous + packet exists */ + Packet prev(NoThrow_t) const; ///< Get previous packet in chain + /**< \returns in - valid() packet if no previous packet + exists */ template OtherPacket prev() const; - ///< Get previous packet in chain and cast to \a OtherPacket - /**< \throws std::bad_cast, if the previous packet is not of - type \a OtherPacket - \throws InvalidPacketChainException if no previous - packet exists */ + ///< Get previous packet in chain and cast to \a OtherPacket + /**< \throws std::bad_cast, if the previous packet is not of + type \a OtherPacket + \throws InvalidPacketChainException if no previous + packet exists */ template OtherPacket prev(NoThrow_t) const; - ///< Get previous packet in chain and cast to \a OtherPacket - /**< \throws std::bad_cast, if the previous packet is not of - type \a OtherPacket - \returns in - valid() packet if no previous packet - exists */ + ///< Get previous packet in chain and cast to \a OtherPacket + /**< \throws std::bad_cast, if the previous packet is not of + type \a OtherPacket + \returns in - valid() packet if no previous packet + exists */ template OtherPacket rfind() const; - ///< Search chain backwards for packet of type \a OtherPacket - /**< The search will start with the current packet. - \throws InvalidPacketChainException if no packet of - type \a OtherPacket can be found. */ + ///< Search chain backwards for packet of type \a OtherPacket + /**< The search will start with the current packet. + \throws InvalidPacketChainException if no packet of + type \a OtherPacket can be found. */ template OtherPacket rfind(NoThrow_t) const; - ///< Search chain backwards for packet of type \a OtherPacket - /**< The search will start with the current packet. - \returns in - valid() packet if no packet of type \a - OtherPacket can be found. */ + ///< Search chain backwards for packet of type \a OtherPacket + /**< The search will start with the current packet. + \returns in - valid() packet if no packet of type \a + OtherPacket can be found. */ - Packet first() const; - ///< Return first packet in chain - template OtherPacket first() const; - ///< Return first packet in chain and cast - /**< \throws std::bad_cast if the first() packet is not of - type \a OtherPacket */ + Packet first() const; ///< Return first packet in chain + template OtherPacket first() const; + ///< Return first packet in chain and cast + /**< \throws std::bad_cast if the first() packet is not of + type \a OtherPacket */ - Packet last() const; - ///< Return last packet in chain + Packet last() const; ///< Return last packet in chain template OtherPacket last() const; - ///< Return last packet in chain and cast - /**< \throws std::bad_cast if the last() packet is not of - type \a OtherPacket */ + ///< Return last packet in chain and cast + /**< \throws std::bad_cast if the last() packet is not of + type \a OtherPacket */ template OtherPacket parseNextAs() const; - ///< Interpret payload of \c this as \a OtherPacket - /**< parseNextAs() will throw away the packet chain after - the current packet if necessary. It will then parse the - payload section of \c this packet as given by \a - OtherPacket. The new packet is added to the chain after - \c this. - \returns new packet instance sharing the same data and - placed after \c this packet in the chain. - \throws InvalidPacketChainException if no next - packet header is allowed (viz. nextPacketRange() of the the current - PacketType returns no_range() ) */ + ///< Interpret payload of \c this as \a OtherPacket + /**< parseNextAs() will throw away the packet chain after + the current packet if necessary. It will then parse the + payload section of \c this packet as given by \a + OtherPacket. The new packet is added to the chain after + \c this. + \returns new packet instance sharing the same data and + placed after \c this packet in the chain. + \throws InvalidPacketChainException if no next packet + header is allowed (viz. nextPacketRange() of the + the current PacketType returns no_range() ) */ Packet parseNextAs(factory_t factory) const; - ///< Interpret payload of \c this as \a factory type packet - /**< parseNextAs() will throw away the packet chain after - the current packet if necessary. It will then parse the - payload section of \c this packet as given by \a - factory. The new packet is added to the chain after - \c this. - \returns new packet instance sharing the same data and - placed after \c this packet in the chain. - \throws InvalidPacketChainException if no next - packet header is allowed (viz. nextPacketRange() of the the current - PacketType returns no_range() ) */ + ///< Interpret payload of \c this as \a factory type packet + /**< parseNextAs() will throw away the packet chain after + the current packet if necessary. It will then parse the + payload section of \c this packet as given by \a + factory. The new packet is added to the chain after + \c this. + \returns new packet instance sharing the same data and + placed after \c this packet in the chain. + \throws InvalidPacketChainException if no next packet + header is allowed (viz. nextPacketRange() of the + the current PacketType returns no_range() ) */ template bool is() const; - ///< Check, whether \c this packet is of the given type + ///< Check, whether \c this packet is of the given type template OtherPacket as() const; - ///< Cast current packet to the given type - /**< This operations returns a handle to the same packet - header/interpreter however upcast to the given - ConcretePacket type which have been instantiated before. - \throws std::bad_cast if the current packet is not of - type \a OtherPacket */ + ///< Cast current packet to the given type + /**< This operations returns a handle to the same packet + header/interpreter however upcast to the given + ConcretePacket type which have been instantiated + before. + \throws std::bad_cast if the current packet is not of + type \a OtherPacket */ Packet append(Packet const & packet) const; ///< Append the given packet to \c this packet - /**< This operation will replace the payload section of \c - this packet with \a packet. This operation will replace - the packet chain after \c this packet with a clone of - \a packet and will replace the raw data of the payload - of \c this with the raw data of \a packet. \c this - packet will not share any date with \a packet. - \returns Packet handle to the cloned \a packet, placed - after \c this in the packet/header/interpreter - chain. */ + /**< This operation will replace the payload section of \c + this packet with \a packet. This operation will replace + the packet chain after \c this packet with a clone of + \a packet and will replace the raw data of the payload + of \c this with the raw data of \a packet. \c this + packet will not share any date with \a packet. + \returns Packet handle to the cloned \a packet, placed + after \c this in the packet/header/interpreter + chain. */ ///@} @@ -330,9 +325,9 @@ namespace senf { struct. \code - struct MyAnnotation { + struct MyAnnotation { int value; - }; + }; senf::Packet p (...); @@ -351,11 +346,11 @@ namespace senf { lead to a program crash. \code - struct MyStringAnnotation : senf::ComplexAnnotation { + struct MyStringAnnotation : senf::ComplexAnnotation { std::string value; - }; + }; \endcode - (This type is not POD since \c std::string is not POD) + (This type is not POD since \c std::string is not POD) \see \ref packet_usage_annotation @@ -562,40 +557,40 @@ namespace senf { // no conversion constructors ConcretePacket(); ///< Create uninitialized packet handle - /**< An uninitialized handle is not valid(). It does not - allow any operation except assignment and checking for - validity. */ + /**< An uninitialized handle is not valid(). It does not + allow any operation except assignment and checking for + validity. */ static factory_t factory(); ///< Return factory for packets of specific type - /**< This \e static member is like Packet::factory() for a - specific packet of type \a PacketType */ + /**< This \e static member is like Packet::factory() for a + specific packet of type \a PacketType */ // Create completely new packet static ConcretePacket create(); ///< Create default initialized packet - /**< The packet will be initialized to it's default empty - state. */ + /**< The packet will be initialized to it's default empty + state. */ static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet - /**< This will create a completely empty and uninitialized - packet with size() == 0. - \param[in] senf::noinit This parameter must always have the - value \c senf::noinit. */ + /**< This will create a completely empty and uninitialized + packet with size() == 0. + \param[in] senf::noinit This parameter must always have + the value \c senf::noinit. */ static ConcretePacket create(size_type size); ///< Create default initialized packet - /**< This member will create a default initialized packet - with the given size. If the size parameter is smaller - than the minimum allowed packet size an exception will - be thrown. - \param[in] size Size of the packet to create in bytes. - \throws TruncatedPacketException if \a size is smaller - than the smallest permissible size for this type of - packet. */ + /**< This member will create a default initialized packet + with the given size. If the size parameter is smaller + than the minimum allowed packet size an exception will + be thrown. + \param[in] size Size of the packet to create in bytes. + \throws TruncatedPacketException if \a size is smaller + than the smallest permissible size for this type of + packet. */ static ConcretePacket create(size_type size, senf::NoInit_t); - ///< Create uninitialized packet - /**< Creates an uninitialized (all-zero) packet of the exact - given size. - \param[in] size Size of the packet to create in bytes - \param[in] senf::noinit This parameter must always have the - value \c senf::noinit. */ + ///< Create uninitialized packet + /**< Creates an uninitialized (all-zero) packet of the exact + given size. + \param[in] size Size of the packet to create in bytes + \param[in] senf::noinit This parameter must always have + the value \c senf::noinit. */ #ifndef DOXYGEN template static ConcretePacket create( @@ -604,56 +599,56 @@ namespace senf { #else template static ConcretePacket create(ForwardReadableRange const & range); - ///< Create packet from given data - /**< The packet will be created from a copy of the given - data. The data from the range will be copied directly - into the packet representation. The data will \e not be - validated in any way. - \param[in] range Boost.Range - of data to construct packet from. */ + ///< Create packet from given data + /**< The packet will be created from a copy of the given + data. The data from the range will be copied directly + into the packet representation. The data will \e not be + validated in any way. + + \param[in] range Boost.Range + of data to construct packet from. */ #endif // Create packet as new packet after a given packet static ConcretePacket createAfter(Packet const & packet); - ///< Create default initialized packet after \a packet - /**< The packet will be initialized to it's default empty - state. It will be appended as next header/interpreter - after \a packet in that packets interpreter chain. - \param[in] packet Packet to append new packet to. */ + ///< Create default initialized packet after \a packet + /**< The packet will be initialized to it's default empty + state. It will be appended as next header/interpreter + after \a packet in that packets interpreter chain. + \param[in] packet Packet to append new packet to. */ static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t); - ///< Create uninitialized empty packet after\a packet - /**< This will create a completely empty and uninitialized - packet with size() == 0. It will be appended - as next header/interpreter after \a packet in that - packets interpreter chain. - \param[in] packet Packet to append new packet to. - \param[in] senf::noinit This parameter must always have the - value \c senf::noinit. */ + ///< Create uninitialized empty packet after\a packet + /**< This will create a completely empty and uninitialized + packet with size() == 0. It will be appended + as next header/interpreter after \a packet in that + packets interpreter chain. + \param[in] packet Packet to append new packet to. + \param[in] senf::noinit This parameter must always have + the value \c senf::noinit. */ static ConcretePacket createAfter(Packet const & packet, size_type size); - ///< Create default initialized packet after \a packet - /**< This member will create a default initialized packet - with the given size. If the size parameter is smaller - than the minimum allowed packet size an exception will - be thrown. It will be appended as next - header/interpreter after \a packet in that packets - interpreter chain. - \param[in] packet Packet to append new packet to. - \param[in] size Size of the packet to create in bytes. - \throws TruncatedPacketException if \a size is smaller - than the smallest permissible size for this type of - packet. */ + ///< Create default initialized packet after \a packet + /**< This member will create a default initialized packet + with the given size. If the size parameter is smaller + than the minimum allowed packet size an exception will + be thrown. It will be appended as next + header/interpreter after \a packet in that packets + interpreter chain. + \param[in] packet Packet to append new packet to. + \param[in] size Size of the packet to create in bytes. + \throws TruncatedPacketException if \a size is smaller + than the smallest permissible size for this type of + packet. */ static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t); - ///< Create uninitialized packet after \a packet - /**< Creates an uninitialized (all-zero) packet of the exact - given size. It will be appended as next - header/interpreter after \a packet in that packets - interpreter chain. - \param[in] packet Packet to append new packet to. - \param[in] size Size of the packet to create in bytes - \param[in] senf::noinit This parameter must always have the - value \c senf::noinit. */ + ///< Create uninitialized packet after \a packet + /**< Creates an uninitialized (all-zero) packet of the exact + given size. It will be appended as next + header/interpreter after \a packet in that packets + interpreter chain. + \param[in] packet Packet to append new packet to. + \param[in] size Size of the packet to create in bytes + \param[in] senf::noinit This parameter must always have + the value \c senf::noinit. */ #ifndef DOXYGEN template static ConcretePacket createAfter( @@ -664,34 +659,36 @@ namespace senf { template static ConcretePacket createAfter(Packet const & packet, ForwardReadableRange const & range); - ///< Create packet from given data after \a packet - /**< The packet will be created from a copy of the given - data. The data from the range will be copied directly - into the packet representation. The data will \e not be - validated in any way. It will be appended as next - header/interpreter after \a packet in that packets - interpreter chain. - \param[in] packet Packet to append new packet to. - \param[in] range Boost.Range - of data to construct packet from. */ + ///< Create packet from given data after \a packet + /**< The packet will be created from a copy of the given + data. The data from the range will be copied directly + into the packet representation. The data will \e not be + validated in any way. It will be appended as next + header/interpreter after \a packet in that packets + interpreter chain. + \param[in] packet Packet to append new packet to. + \param[in] range Boost.Range + of data to construct packet from. */ #endif // Create packet as new packet (header) before a given packet static ConcretePacket createBefore(Packet const & packet); - ///< Create default initialized packet before \a packet - /**< The packet will be initialized to it's default empty - state. It will be prepended as previous - header/interpreter before \a packet in that packets - interpreter chain. - \param[in] packet Packet to prepend new packet to. */ + ///< Create default initialized packet before \a packet + /**< The packet will be initialized to it's default empty + state. It will be prepended as previous + header/interpreter before \a packet in that packets + interpreter chain. + \param[in] packet Packet to prepend new packet to. */ static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t); - ///< Create uninitialized empty packet before \a packet - /**< Creates a completely empty and uninitialized packet. It - will be prepended as previous header/interpreter before - \a packet in that packets interpreter chain. - \param[in] packet Packet to prepend new packet to. */ + ///< Create uninitialized empty packet before \a packet + /**< Creates a completely empty and uninitialized packet. It + will be prepended as previous header/interpreter before + \a packet in that packets interpreter chain. + \param[in] packet Packet to prepend new packet to. */ + + static ConcretePacket createInsertBefore(Packet const & packet); + static ConcretePacket createInsertBefore(Packet const & packet, senf::NoInit_t); // Create a clone of the current packet diff --git a/senf/Packets/Packet.test.cc b/senf/Packets/Packet.test.cc index 21362e7..0581add 100644 --- a/senf/Packets/Packet.test.cc +++ b/senf/Packets/Packet.test.cc @@ -281,6 +281,21 @@ SENF_AUTO_UNIT_TEST(concretePacket) BOOST_CHECK_EQUAL( FooPacket::createBefore(packet,senf::noinit).size(), 10u ); BOOST_CHECK_EQUAL( packet.size(), 10u ); + BOOST_CHECK_EQUAL( FooPacket::createInsertBefore(packet).size(), 14u ); + BOOST_CHECK_EQUAL( packet.size(), 10u ); + BOOST_REQUIRE( packet.prev() ); + BOOST_CHECK_EQUAL( packet.prev().size(), 14u ); + BOOST_REQUIRE( packet.prev().prev() ); + BOOST_CHECK_EQUAL( packet.prev().prev().size(), 14u ); + + BOOST_CHECK_EQUAL( FooPacket::createInsertBefore(packet,senf::noinit).size(), 10u ); + BOOST_CHECK_EQUAL( packet.size(), 10u ); + BOOST_REQUIRE_NO_THROW( packet.prev().prev().prev() ); + BOOST_CHECK_THROW( packet.prev().prev().prev().prev(), senf::InvalidPacketChainException ); + BOOST_CHECK_EQUAL( packet.prev().size(), 10u ); + BOOST_CHECK_EQUAL( packet.prev().prev().size(), 14u ); + BOOST_CHECK_EQUAL( packet.prev().prev().prev().size(), 14u ); + SENF_CHECK_NOT_EQUAL( packet.clone(), packet ); BOOST_CHECK_EQUAL( BarPacket::create()->reserved(), 0xA0A0u ); } diff --git a/senf/Packets/PacketImpl.cc b/senf/Packets/PacketImpl.cc index 5b0ad43..5fc7bf9 100644 --- a/senf/Packets/PacketImpl.cc +++ b/senf/Packets/PacketImpl.cc @@ -76,6 +76,14 @@ prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase p->assignImpl(this); } +prefix_ void senf::detail::PacketImpl::prependInterpreter(PacketInterpreterBase * p, + PacketInterpreterBase * before) +{ + interpreter_list::iterator i (interpreter_list::current(*before)); + interpreters_.insert(i, *p); + p->assignImpl(this); +} + // Data container prefix_ void senf::detail::PacketImpl::clear(PacketData * self) diff --git a/senf/Packets/PacketImpl.hh b/senf/Packets/PacketImpl.hh index 489c6e2..e98a8c6 100644 --- a/senf/Packets/PacketImpl.hh +++ b/senf/Packets/PacketImpl.hh @@ -174,6 +174,7 @@ namespace detail { void appendInterpreter (PacketInterpreterBase * p); void prependInterpreter (PacketInterpreterBase * p); + void prependInterpreter (PacketInterpreterBase * p, PacketInterpreterBase * before); void truncateInterpreters (PacketInterpreterBase * p); void truncateInterpretersBackwards (PacketInterpreterBase * p); diff --git a/senf/Packets/PacketImpl.test.cc b/senf/Packets/PacketImpl.test.cc index a6c08df..2a2b74a 100644 --- a/senf/Packets/PacketImpl.test.cc +++ b/senf/Packets/PacketImpl.test.cc @@ -153,25 +153,30 @@ SENF_AUTO_UNIT_TEST(packetImpl_interpreters) p->add_ref(); { - senf::PacketInterpreterBase::ptr pi2 ( + senf::PacketInterpreterBase::ptr pi3 ( senf::detail::packet::test::TestDriver::create( p,p->begin(),p->end(),senf::PacketInterpreterBase::Append)); - senf::PacketInterpreterBase::ptr pi3 ( + senf::PacketInterpreterBase::ptr pi4 ( senf::detail::packet::test::TestDriver::create( p,p->end(),p->end(),senf::PacketInterpreterBase::Append)); senf::PacketInterpreterBase::ptr pi1 ( senf::detail::packet::test::TestDriver::create( p,p->begin(),p->end(),senf::PacketInterpreterBase::Prepend)); + senf::PacketInterpreterBase::ptr pi2 ( + senf::detail::packet::test::TestDriver::create( + p,p->begin(),p->end(),pi3)); BOOST_CHECK_EQUAL(p->first(), pi1.get()); BOOST_CHECK_EQUAL(p->next(p->first()), pi2.get()); BOOST_CHECK_EQUAL(p->next(p->next(p->first())), pi3.get()); - BOOST_CHECK( !p->next(p->next(p->next(p->first()))) ); - - BOOST_CHECK_EQUAL(p->last(), pi3.get()); - BOOST_CHECK_EQUAL(p->prev(p->last()), pi2.get()); - BOOST_CHECK_EQUAL(p->prev(p->prev(p->last())), pi1.get()); - BOOST_CHECK( !p->prev(p->prev(p->prev(p->last()))) ); + BOOST_CHECK_EQUAL(p->next(p->next(p->next(p->first()))), pi4.get()); + BOOST_CHECK( !p->next(p->next(p->next(p->next(p->first())))) ); + + BOOST_CHECK_EQUAL(p->last(), pi4.get()); + BOOST_CHECK_EQUAL(p->prev(p->last()), pi3.get()); + BOOST_CHECK_EQUAL(p->prev(p->prev(p->last())), pi2.get()); + BOOST_CHECK_EQUAL(p->prev(p->prev(p->prev(p->last()))), pi1.get()); + BOOST_CHECK( !p->prev(p->prev(p->prev(p->prev(p->last())))) ); p->insert(&pi2->data(),p->begin(),10,0x00u); BOOST_CHECK_EQUAL(pi1->data().size(), 10u); diff --git a/senf/Packets/PacketInterpreter.cci b/senf/Packets/PacketInterpreter.cci index fef8049..7eec8e5 100644 --- a/senf/Packets/PacketInterpreter.cci +++ b/senf/Packets/PacketInterpreter.cci @@ -116,7 +116,15 @@ prefix_ senf::PacketInterpreterBase::PacketInterpreterBase(detail::PacketImpl * : PacketData(std::distance(impl->begin(),b), std::distance(impl->begin(),e)) { - impl->prependInterpreter(this); + impl->prependInterpreter(this); +} + +prefix_ senf::PacketInterpreterBase::PacketInterpreterBase(detail::PacketImpl * impl, + iterator b, iterator e, ptr before) + : PacketData(std::distance(impl->begin(),b), + std::distance(impl->begin(),e)) +{ + impl->prependInterpreter(this, before.get()); } prefix_ senf::PacketInterpreterBase::ptr diff --git a/senf/Packets/PacketInterpreter.ct b/senf/Packets/PacketInterpreter.ct index 49a34e1..2278181 100644 --- a/senf/Packets/PacketInterpreter.ct +++ b/senf/Packets/PacketInterpreter.ct @@ -147,10 +147,29 @@ senf::PacketInterpreter::createBefore(PacketInterpreterBase::ptr pac { if (packet->prev()) packet->impl().truncateInterpretersBackwards(packet->prev().get()); - + return create(&packet->impl(),packet->data().begin(),packet->data().end(),Prepend); } +template +prefix_ typename senf::PacketInterpreter::ptr +senf::PacketInterpreter::createInsertBefore(PacketInterpreterBase::ptr packet) +{ + ptr pi (createInsertBefore(packet, senf::noinit)); + pi->data().insert(pi->data().begin(),initHeadSize(),byte(0x00u)); + pi->data().insert(pi->data().end(),initSize()-initHeadSize(),byte(0x00u)); + pi->init(); + return pi; +} + +template +prefix_ typename senf::PacketInterpreter::ptr +senf::PacketInterpreter::createInsertBefore(PacketInterpreterBase::ptr packet, + senf::NoInit_t) +{ + return create(&packet->impl(),packet->data().begin(),packet->data().end(),packet); +} + //////////////////////////////////////// // private members @@ -332,6 +351,24 @@ createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) return senf::PacketInterpreter::createBefore(packet,senf::noinit); } +template +prefix_ senf::PacketInterpreterBase::ptr +senf::PacketInterpreter::FactoryImpl:: +createInsertBefore(PacketInterpreterBase::ptr packet) + const +{ + return senf::PacketInterpreter::createInsertBefore(packet); +} + +template +prefix_ senf::PacketInterpreterBase::ptr +senf::PacketInterpreter::FactoryImpl:: +createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) + const +{ + return senf::PacketInterpreter::createInsertBefore(packet,senf::noinit); +} + // Parse next packet in chain template diff --git a/senf/Packets/PacketInterpreter.cti b/senf/Packets/PacketInterpreter.cti index 8dd19a9..29eee09 100644 --- a/senf/Packets/PacketInterpreter.cti +++ b/senf/Packets/PacketInterpreter.cti @@ -148,6 +148,14 @@ senf::PacketInterpreter::create(detail::PacketImpl * impl, iterator } template +prefix_ typename senf::PacketInterpreter::ptr +senf::PacketInterpreter::create(detail::PacketImpl * impl, iterator b, iterator e, + PacketInterpreterBase::ptr before) +{ + return ptr(new PacketInterpreter(impl,b,e,before)); +} + +template prefix_ senf::PacketInterpreter::PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t) : PacketInterpreterBase(impl,b,e,Append) @@ -159,6 +167,14 @@ prefix_ senf::PacketInterpreter::PacketInterpreter(detail::PacketImp : PacketInterpreterBase(impl,b,e,Prepend) {} +template +prefix_ +senf::PacketInterpreter::PacketInterpreter(detail::PacketImpl * impl, iterator b, + iterator e, + PacketInterpreterBase::ptr before) + : PacketInterpreterBase(impl,b,e,before) +{} + // PacketType access template diff --git a/senf/Packets/PacketInterpreter.hh b/senf/Packets/PacketInterpreter.hh index e2591cf..0a546a6 100644 --- a/senf/Packets/PacketInterpreter.hh +++ b/senf/Packets/PacketInterpreter.hh @@ -111,6 +111,9 @@ namespace senf { virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0; virtual ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0; + virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet) const = 0; + virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0; + // Parse next packet in chain virtual ptr parseNext(ptr packet) const = 0; @@ -186,6 +189,7 @@ namespace senf { PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t); PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t); + PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before); ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base); ptr appendClone(detail::PacketImpl * impl, range r); @@ -282,6 +286,9 @@ namespace senf { static ptr createBefore(PacketInterpreterBase::ptr packet); static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t); + static ptr createInsertBefore(PacketInterpreterBase::ptr packet); + static ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t); + // Create a clone of the current packet ptr clone(); @@ -305,9 +312,13 @@ namespace senf { PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t); PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t); + PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, + PacketInterpreterBase::ptr before); static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t); static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t); + static ptr create(detail::PacketImpl * impl, iterator b, iterator e, + PacketInterpreterBase::ptr before); // PacketType access @@ -360,6 +371,12 @@ namespace senf { senf::NoInit_t) const; + virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet) + const; + virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet, + senf::NoInit_t) + const; + // Parse next packet in chain virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet) diff --git a/senf/Packets/PacketInterpreter.test.cc b/senf/Packets/PacketInterpreter.test.cc index 0afb7bb..7d796c9 100644 --- a/senf/Packets/PacketInterpreter.test.cc +++ b/senf/Packets/PacketInterpreter.test.cc @@ -208,6 +208,13 @@ SENF_AUTO_UNIT_TEST(packetInterpreter) p,senf::noinit)); BOOST_CHECK_EQUAL( p3->data().size(), 10u ); + + senf::PacketInterpreter::ptr p4 + (senf::PacketInterpreter::createInsertBefore(p)); + + BOOST_CHECK_EQUAL( p->data().size(), 10u ); + BOOST_CHECK_EQUAL( p4->data().size(), 18u ); + BOOST_CHECK_EQUAL( p3->data().size(), 18u ); } } @@ -275,11 +282,15 @@ SENF_AUTO_UNIT_TEST(packetInterpreter_factory) BOOST_CHECK( ! p->prev()->prev() ); BOOST_CHECK_EQUAL( p->prev()->data().size(), 12u ); - BOOST_CHECK_EQUAL( - factory->createBefore(p,senf::noinit)->data().size(), 4u ); + BOOST_CHECK_EQUAL( factory->createBefore(p,senf::noinit)->data().size(), 4u ); BOOST_REQUIRE( p->prev() ); BOOST_CHECK( ! p->prev()->prev() ); BOOST_CHECK_EQUAL( p->prev()->data().size(), 4u ); + + BOOST_CHECK_EQUAL( factory->createInsertBefore(p,senf::noinit)->data().size(), 4u ); + BOOST_REQUIRE( p->prev() ); + BOOST_REQUIRE( p->prev()->prev() ); + BOOST_CHECK( ! p->prev()->prev()->prev() ); } { diff --git a/senf/Packets/main.test.hh b/senf/Packets/main.test.hh index df95156..9801594 100644 --- a/senf/Packets/main.test.hh +++ b/senf/Packets/main.test.hh @@ -47,6 +47,11 @@ namespace test { PacketInterpreterBase::Prepend_t) { return PacketInterpreter::create(impl,b,e,PacketInterpreterBase::Prepend); } + template + static typename PacketInterpreter::ptr create(PacketImpl * impl, iterator b, iterator e, + PacketInterpreterBase::ptr before) + { return PacketInterpreter::create(impl,b,e,before); } + static PacketImpl * impl(PacketInterpreterBase::ptr p) { return &p->impl(); } };