Packets: Fix next()/prev() etc. semantics, naming and doc
g0dil [Thu, 17 Jan 2008 09:27:51 +0000 (09:27 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@616 270642c3-0616-0410-b53a-bc976706d245

Packets/DefaultBundle/UDPPacket.cc
Packets/Packet.ct
Packets/Packet.cti
Packets/Packet.hh
Packets/Packet.test.cc
Packets/PacketInterpreter.cti

index b5328ad..8d4a850 100644 (file)
@@ -54,11 +54,11 @@ prefix_ boost::uint16_t senf::UDPPacketParser::calcChecksum()
     summer.feed( i()+checksum_offset+2, data().end() );
     
     // Now on to the awkward part: the IP pseudo header
-    IPv4Packet ipv4 (packet().prev<IPv4Packet>(nothrow));
+    IPv4Packet ipv4 (packet().rfind<IPv4Packet>());
     if (ipv4) {
         // Pseudo header defined in RFC768
         summer.feed( ipv4->source().i(), 
-                     ipv4->source().i() + IPv4PacketParser::source_t::fixed_bytes );
+                     ipv4->source().i() + IPv4Packet::Parser::source_t::fixed_bytes );
         ///\fixme What about a hop-by-hop routing option? Which destination is used in IPv4 ?
         summer.feed( ipv4->destination().i(), 
                      ipv4->destination().i() + IPv4PacketParser::destination_t::fixed_bytes );
@@ -70,10 +70,10 @@ prefix_ boost::uint16_t senf::UDPPacketParser::calcChecksum()
     } 
     else {
         // Pseudo header defined in RFC2460
-        IPv6Packet ipv6 (packet().prev<IPv6Packet>(nothrow));
+        IPv6Packet ipv6 (packet().rfind<IPv6Packet>());
         if (ipv6) {
             summer.feed( ipv6->source().i(), 
-                         ipv6->source().i() + IPv6PacketParser::source_t::fixed_bytes );
+                         ipv6->source().i() + IPv6Packet::Parser::source_t::fixed_bytes );
             ///\todo Implement routing header support
             // The destination used here must be the *final* destination ...
             summer.feed( ipv6->destination().i(), 
index 27516cb..48b83fc 100644 (file)
@@ -34,7 +34,7 @@
 // senf::Packet
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findNext(NoThrow_t)
+prefix_ OtherPacket senf::Packet::find()
     const
 {
     Packet p (*this);
@@ -47,7 +47,7 @@ prefix_ OtherPacket senf::Packet::findNext(NoThrow_t)
 }
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findPrev(NoThrow_t)
+prefix_ OtherPacket senf::Packet::rfind()
     const
 {
     Packet p (*this);
index 492a7d7..18443fa 100644 (file)
@@ -60,6 +60,8 @@ template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::as()
     const
 {
+    if (!is<OtherPacket>())
+        throw std::bad_cast();
     return OtherPacket(ptr()->as<typename OtherPacket::type>());
 }
 
@@ -67,81 +69,28 @@ template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::next()
     const
 {
-    OtherPacket p (next<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
-}
-
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::next(NoThrow_t)
-    const
-{
-    Packet p (next());
-    return p ? p.findNext<OtherPacket>(nothrow) : OtherPacket();
+    return next().as<OtherPacket>();
 }
 
 template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::prev()
     const
 {
-    OtherPacket p (prev<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
-}
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
-    const
-{
-    Packet p (prev());
-    return p ? p.findPrev<OtherPacket>(nothrow) : OtherPacket();
-}
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findNext()
-    const
-{
-    OtherPacket p (findNext<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
-}
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findPrev()
-    const
-{
-    OtherPacket p (findPrev<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
+    return prev().as<OtherPacket>();
 }
 
 template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::last()
     const
 {
-    return last().findPrev<OtherPacket>();
-}
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::last(NoThrow_t)
-    const
-{
-    return last().findPrev<OtherPacket>(nothrow);
+    return last().as<OtherPacket>();
 }
 
 template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::first()
     const
 {
-    return first().findNext<OtherPacket>();
-}
-
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::first(NoThrow_t)
-    const
-{
-    return first().findNext<OtherPacket>(nothrow);
+    return first().as<OtherPacket>();
 }
 
 ///////////////////////////////////////////////////////////////////////////
index 2e9ae28..9855adb 100644 (file)
@@ -145,12 +145,12 @@ namespace senf {
         // Types
         
         typedef void type;              ///< Type of the packet.
-        typedef senf::detail::packet::size_type size_type; ///< Unsigned type to represent packet size
+        typedef senf::detail::packet::size_type size_type;
+                                        ///< Unsigned type to represent packet size
         typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
 
-                                        /// Special argument flag
-                                        /** Used in some ConcretePacket constructors */
-        enum NoInit_t { noinit };       
+        enum NoInit_t { noinit };       ///< Special argument flag
+                                        /**< Used in some ConcretePacket constructors */
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
@@ -161,14 +161,14 @@ namespace senf {
         // default destructor
         
         Packet();                       ///< Create uninitialized packet handle
-                                        /**< An uninitialized handle is not valid(). It does not
+                                        /**< An uninitialized handle is in - valid(). It does not
                                              allow any operation except assignment and checking for
                                              validity. */
         Packet clone() const;           ///< Create copy packet
-                                        /**< clone() will create a complete copy the packet. The
-                                             returned packet will have the same data and packet
-                                             chain. It does however not share any data with the
-                                             original packet. */
+                                        /**< clone() will create a complete copy of \c this
+                                             packet. The returned packet will have the same data and
+                                             packet chain. It does however not share any data with
+                                             the original packet. */
 
         // conversion constructors
 
@@ -189,90 +189,51 @@ namespace senf {
                                         /**< \returns in - valid() packet, if no next packet 
                                              exists */
         template <class OtherPacket> OtherPacket next() const; 
-                                        ///< Get next packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket next(NoThrow_t) const; 
-                                        ///< Get next packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
-        template <class OtherPacket> OtherPacket findNext() const;
-                                        ///< Find next packet of given type in chain
-                                        /**< findNext() is like next(), it will however return \c
-                                             *this if it is of the given type. 
-                                             \throws InvalidPacketChainException if no such packet
-                                                 is found */
-        template <class OtherPacket> OtherPacket findNext(NoThrow_t) const;
-                                        ///< Find next packet of given type in chain
-                                        /**< findNext() is like next(), it will however return \c
-                                             *this if it is of the given type.
-                                             \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
+                                        ///< 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 <class OtherPacket> OtherPacket find() 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
                                         /**< \returns in - valid() packet, if no previous packet 
                                              exists */
         template <class OtherPacket> OtherPacket prev() const; 
-                                        ///< Get previous packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
-                                        ///< Get previous packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
-        template <class OtherPacket> OtherPacket findPrev() const;
-                                        ///< Find previous packet of given type in chain
-                                        /**< findPrev() is like prev(), it will however return \c
-                                             *this if it is of the type 
-                                             \throws InvalidPacketChainException if no such packet
-                                                 is found */
-        template <class OtherPacket> OtherPacket findPrev(NoThrow_t) const;
-                                        ///< Find previous packet of given type in chain
-                                        /**< findPrev() is like prev(), it will however return \c
-                                             *this if it is of the type 
-                                             \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
+                                        ///< 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 <class OtherPacket> OtherPacket rfind() 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. */
 
 
                                      Packet      first() const;
                                         ///< Return first packet in chain
         template <class OtherPacket> OtherPacket first() const;
-                                        ///< Return first packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket first(NoThrow_t) const;
-                                        ///< Return first packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
+                                        ///< 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
         template <class OtherPacket> OtherPacket last() const;
-                                        ///< Return last packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket last(NoThrow_t) const;
-                                        ///< Return last packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in - valid() packet, if no such packet is
-                                             found */
+                                        ///< Return last packet in chain and cast
+                                        /**< \throws std::bad_cast if the last() packet is not of
+                                             type \a OtherPacket  */
 
 
         template <class OtherPacket> OtherPacket parseNextAs() const;
-                                        ///< Parse payload as given by \a OtherPacket and add packet
+                                        ///< 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
@@ -281,32 +242,32 @@ namespace senf {
                                              \returns new packet instance sharing the same data and
                                                  placed after \c this packet in the chain. */
                                      Packet      parseNextAs(factory_t factory) const;
-                                        ///< Parse payload as given by \a factory and add packet
+                                        ///< 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
-                                             OtherPacket. The new packet is added to the chain after
+                                             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. */
+
         template <class OtherPacket> bool        is() const;
                                         ///< Check, whether \c this packet is of the given type
         template <class OtherPacket> OtherPacket as() const;
                                         ///< Cast current packet to the given type
                                         /**< This operations returns a handle to the same packet
                                              header/interpreter however cast to the given
-                                             ConcretePacket type. <b>This conversion is
-                                             unchecked</b>. If the packet really is of a different
-                                             type, this will wreak havoc with the packet
-                                             data-structures. You can validate whether the
-                                             conversion is valid using is(). */
+                                             ConcretePacket type.
+                                             \throws std::bad_cast if the current packet is not of
+                                                 type \a OtherPacket */
 
         Packet append(Packet 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 if \a packet.
+                                             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. */
@@ -430,6 +391,7 @@ namespace senf {
         // Types
         
         typedef PacketType type;
+        typedef typename PacketType::parser Parser;
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
@@ -565,7 +527,7 @@ namespace senf {
 
         // Field access
 
-        typename type::parser * operator->() const; ///< Access packet fields
+        Parser * operator->() const;    ///< Access packet fields
                                         /**< This operator allows to access the parsed fields of the
                                              packet using the notation <tt>packet->field()</tt>. The
                                              fields of the packet are specified by the PacketType's
index 8af4e6a..d738f60 100644 (file)
@@ -155,7 +155,7 @@ BOOST_AUTO_UNIT_TEST(packet)
                        BarPacket::type::parser::type_t::value_type(-1) );
     packet.last().append(FooPacket::create());
     packet.finalize();
-    BOOST_CHECK_EQUAL( packet.next<BarPacket>()->type(), 1u );
+    BOOST_CHECK_EQUAL( packet.find<BarPacket>()->type(), 1u );
 
     BOOST_CHECK( packet.factory() == FooPacket::factory() );
 
@@ -166,25 +166,19 @@ BOOST_AUTO_UNIT_TEST(packet)
     BOOST_REQUIRE( packet.next() );
     BOOST_REQUIRE( packet.next().is<BarPacket>() );
     BOOST_CHECK( packet.last().is<FooPacket>() );
-    BOOST_CHECK_EQUAL( packet.last<BarPacket>()->type(), 1u );
+    BOOST_CHECK_EQUAL( packet.last().rfind<BarPacket>()->type(), 1u );
     BOOST_CHECK_EQUAL( packet.next().size(), 11u );
     BOOST_REQUIRE( packet.next().next() );
     BOOST_CHECK( packet.next().next().is<FooPacket>() );
     BOOST_CHECK( ! packet.next().next().next() );
     BOOST_CHECK_EQUAL( packet.next().next().data()[0], 0x81u );
 
-    BOOST_CHECK( packet.first<FooPacket>() == packet );
-    BOOST_CHECK( packet.first<FooPacket>(senf::nothrow) == packet );
-    BOOST_CHECK( packet.last<BarPacket>() == packet.last().prev() );
-    BOOST_CHECK( packet.last<BarPacket>(senf::nothrow) == packet.last().prev() );
-    BOOST_CHECK( packet.findNext<FooPacket>() == packet );
-    BOOST_CHECK( packet.findNext<FooPacket>(senf::nothrow) == packet );
-    BOOST_CHECK( packet.last().findPrev<FooPacket>() == packet.last() );
-    BOOST_CHECK( packet.last().findPrev<FooPacket>(senf::nothrow) == packet.last() );
+    BOOST_CHECK( packet.first().find<FooPacket>() == packet );
+    BOOST_CHECK( packet.last().rfind<BarPacket>() == packet.last().prev() );
+    BOOST_CHECK( packet.find<FooPacket>() == packet );
+    BOOST_CHECK( packet.last().rfind<FooPacket>() == packet.last() );
     BOOST_CHECK( packet.next<BarPacket>() == packet.next() );
-    BOOST_CHECK( packet.next<BarPacket>(senf::nothrow) == packet.next() );
-    BOOST_CHECK( packet.last().prev<FooPacket>() == packet );
-    BOOST_CHECK( packet.last().prev<FooPacket>(senf::nothrow) == packet );
+    BOOST_CHECK( packet.last().prev().prev<FooPacket>() == packet );
 }
 
 BOOST_AUTO_UNIT_TEST(concretePacket)
index f179ae3..1896850 100644 (file)
@@ -121,7 +121,7 @@ template <class PacketType>
 prefix_ typename senf::PacketInterpreter<PacketType>::parser
 senf::PacketInterpreter<PacketType>::fields()
 {
-    return parser(&data());
+    return parser (data().begin(),&data());
 }
 
 template <class PacketType>