Packets: Extend finalize() API
[senf.git] / Packets / Packet.cti
index 532c3b0..fac31c0 100644 (file)
@@ -1,6 +1,8 @@
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
@@ -24,6 +26,7 @@
 //#include "Packet.ih"
 
 // Custom includes
+#include "../Utils/Exception.hh"
 
 #define prefix_ inline
 ///////////////////////////////cti.p///////////////////////////////////////
@@ -58,6 +61,8 @@ template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::as()
     const
 {
+    if (!is<OtherPacket>())
+        throw WrapException<std::bad_cast>(std::bad_cast());
     return OtherPacket(ptr()->as<typename OtherPacket::type>());
 }
 
@@ -65,51 +70,46 @@ template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::next()
     const
 {
-    OtherPacket p (next<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
+    return next().as<OtherPacket>();
 }
 
-
 template <class OtherPacket>
 prefix_ OtherPacket senf::Packet::next(NoThrow_t)
     const
 {
-    Packet p (next());
-    return p ? p.findNext<OtherPacket>(nothrow) : OtherPacket();
+    Packet p (next(nothrow));
+    return p && p.is<OtherPacket>() ? p.as<OtherPacket>() : OtherPacket();
 }
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::prev()
+prefix_ OtherPacket senf::Packet::find()
     const
 {
-    OtherPacket p (prev<OtherPacket>(nothrow));
+    OtherPacket p (find<OtherPacket>(nothrow));
     if (!p) throw InvalidPacketChainException();
     return p;
 }
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
+prefix_ OtherPacket senf::Packet::prev()
     const
 {
-    Packet p (prev());
-    return p ? p.findPrev<OtherPacket>(nothrow) : OtherPacket();
+    return prev().as<OtherPacket>();
 }
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findNext()
+prefix_ OtherPacket senf::Packet::prev(NoThrow_t)
     const
 {
-    OtherPacket p (findNext<OtherPacket>(nothrow));
-    if (!p) throw InvalidPacketChainException();
-    return p;
+    Packet p (prev(nothrow));
+    return p && p.is<OtherPacket>() ? p.as<OtherPacket>() : OtherPacket();
 }
 
 template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::findPrev()
+prefix_ OtherPacket senf::Packet::rfind()
     const
 {
-    OtherPacket p (findPrev<OtherPacket>(nothrow));
+    OtherPacket p (rfind<OtherPacket>(nothrow));
     if (!p) throw InvalidPacketChainException();
     return p;
 }
@@ -118,28 +118,21 @@ 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>();
+    return first().as<OtherPacket>();
 }
 
-template <class OtherPacket>
-prefix_ OtherPacket senf::Packet::first(NoThrow_t)
-    const
+template <class Other>
+prefix_ void senf::Packet::finalizeTo()
 {
-    return first().findNext<OtherPacket>(nothrow);
+    Packet p (find<Other>(nothrow));
+    ptr()->finalizeTo(p ? p.ptr() : last().ptr());
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -169,9 +162,9 @@ senf::ConcretePacket<PacketType>::create()
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::create(NoInit_t)
+senf::ConcretePacket<PacketType>::create(senf::NoInit_t)
 {
-    return ConcretePacket(interpreter::create(interpreter::noinit));
+    return ConcretePacket(interpreter::create(senf::noinit));
 }
 
 template <class PacketType>
@@ -183,19 +176,24 @@ senf::ConcretePacket<PacketType>::create(size_type size)
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::create(size_type size, NoInit_t)
+senf::ConcretePacket<PacketType>::create(size_type size, senf::NoInit_t)
 {
-    return ConcretePacket(interpreter::create(size,interpreter::noinit));
+    return ConcretePacket(interpreter::create(size,senf::noinit));
 }
 
+#ifndef DOXYGEN
+
 template <class PacketType>
 template <class ForwardReadableRange>
-prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::create(ForwardReadableRange const & range)
+prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
+create(ForwardReadableRange const & range,
+       typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
 {
     return ConcretePacket(interpreter::create(range));
 }
 
+#endif
+
 // Create packet as new packet after a given packet
 
 template <class PacketType>
@@ -207,9 +205,9 @@ senf::ConcretePacket<PacketType>::createAfter(Packet packet)
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::createAfter(Packet packet, NoInit_t)
+senf::ConcretePacket<PacketType>::createAfter(Packet packet, senf::NoInit_t)
 {
-    return ConcretePacket(interpreter::createAfter(packet.ptr(),interpreter::noinit));
+    return ConcretePacket(interpreter::createAfter(packet.ptr(),senf::noinit));
 }
 
 template <class PacketType>
@@ -221,19 +219,24 @@ senf::ConcretePacket<PacketType>::createAfter(Packet packet, size_type size)
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::createAfter(Packet packet, size_type size, NoInit_t)
+senf::ConcretePacket<PacketType>::createAfter(Packet packet, size_type size, senf::NoInit_t)
 {
-    return ConcretePacket(interpreter::createAfter(packet.ptr(), size, interpreter::noinit));
+    return ConcretePacket(interpreter::createAfter(packet.ptr(), size, senf::noinit));
 }
 
+#ifndef DOXYGEN
+
 template <class PacketType>
 template <class ForwardReadableRange>
-prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::createAfter(Packet packet, ForwardReadableRange const & range)
+prefix_ senf::ConcretePacket<PacketType> senf::ConcretePacket<PacketType>::
+createAfter(Packet packet, ForwardReadableRange const & range,
+            typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type *)
 {
     return ConcretePacket(interpreter::createAfter(packet.ptr(), range));
 }
 
+#endif
+
 // Create packet as new packet (header) before a given packet
 
 template <class PacketType>
@@ -245,9 +248,9 @@ senf::ConcretePacket<PacketType>::createBefore(Packet packet)
 
 template <class PacketType>
 prefix_ senf::ConcretePacket<PacketType>
-senf::ConcretePacket<PacketType>::createBefore(Packet packet, NoInit_t)
+senf::ConcretePacket<PacketType>::createBefore(Packet packet, senf::NoInit_t)
 {
-    return ConcretePacket(interpreter::createBefore(packet.ptr(), interpreter::noinit));
+    return ConcretePacket(interpreter::createBefore(packet.ptr(), senf::noinit));
 }
 
 // Create a clone of the current packet
@@ -263,13 +266,21 @@ senf::ConcretePacket<PacketType>::clone()
 // Field access
 
 template <class PacketType>
-prefix_ typename senf::ConcretePacket<PacketType>::interpreter::parser *
+prefix_ typename senf::ConcretePacket<PacketType>::Parser *
 senf::ConcretePacket<PacketType>::operator->()
     const
 {
     return ptr()->fields_p();
 }
 
+template <class PacketType>
+prefix_ typename senf::ConcretePacket<PacketType>::Parser
+senf::ConcretePacket<PacketType>::parser()
+    const
+{
+    return ptr()->fields();
+}
+
 // private members
 
 template <class PacketType>