Utils/Termlib: Extend the completion API
[senf.git] / Packets / PacketType.ct
index d3cc085..caec158 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2008 
+// Copyright (C) 2008
 // Fraunhofer Institute for Open Communication Systems (FOKUS)
 // Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 
 template <class Self>
 prefix_ senf::PacketInterpreterBase::optional_range
-senf::PacketTypeMixin<Self,void>::nextPacketRange(Packet p)
+senf::PacketTypeMixin<Self,void>::nextPacketRange(Packet const & p)
 {
-    if (p.data().size() < Self::initSize())
-        return PacketTypeBase::no_range();
     typename Self::size_type sz (Self::initHeadSize());
     ///\idea This if condition could be replaced with a compile time switch by checking, wether
     /// (the function address) Self::initHeadSize is different from PacketTypeBase::initHeadSize
-    if (sz == PacketTypeBase::size_type(-1))
-        return PacketTypeBase::range(boost::next(p.data().begin(),Self::initSize()),
-                                     p.data().end());
+    if (sz == PacketTypeBase::size_type(-1)) {
+        typename Self::size_type headsz (bytes(p.as< ConcretePacket<Self> >().parser()));
+        return p.data().size() < headsz ? 
+            PacketTypeBase::no_range() : 
+            PacketInterpreterBase::optional_range(
+                PacketTypeBase::range(boost::next(p.data().begin(), headsz),
+                                      p.data().end()));
+    }
     else
-        return PacketTypeBase::range(boost::next(p.data().begin(),sz),
-                                     boost::prior(p.data().end(),Self::initSize()-sz));
+        // If we have a trailer, we do *not* use the 'bytes' value but initSize/initHeadSize, this
+        // is much safer since the bytes() value will probably not be very correct anyways (what
+        // should it return ? the size of the header only, the combined size of header and trailer
+        // or the size of the packet from header to trailer including payload?).
+        //
+        // So, the helper only works with fixed-size parsers if the packet has a trailer.
+        return p.data().size() < Self::initSize() ?
+            PacketTypeBase::no_range() : 
+            PacketInterpreterBase::optional_range(
+                PacketTypeBase::range(boost::next(p.data().begin(),sz),
+                                      boost::prior(p.data().end(),Self::initSize()-sz)));
 }
 
 ///////////////////////////////ct.e////////////////////////////////////////