Utils: Implement Tags.hh and move 'senf::noinit' and 'senf::nothrow' there
[senf.git] / Packets / Mainpage.dox
index 0a0bc02..56f68c5 100644 (file)
@@ -57,7 +57,7 @@
 
     \code
     senf::EthernetPacket eth      (senf::EthernetPacket::create());
-    senf::IPv4Packet     ip       (senf::IPv4Packet    ::createAfter(ethernet));
+    senf::IPv4Packet     ip       (senf::IPv4Packet    ::createAfter(eth));
     senf::UDPPacket      udp      (senf::UDPPacket     ::createAfter(ip));
     senf::DataPacket     payload  (senf::DataPacket    ::createAfter(udp, 
                                                                      std::string("Hello, world!")));
     eth.next().is<IPv4Packet>();        // true
     eth.next().next() == udp;           // true
     eth.next().is<UDPPacket>();         // false
-    eth.next<UDPPacket>() == udp;       // true
+    eth.find<UDPPacket>() == udp;       // true
 
-    udp.next<UDPPacket>();              // throws InvalidPacketChainException
-    udp.next<UDPPacket>(senf::nothrow); // a senf::Packet testing as false
-    udp.findNext<UDPPacket()> == udp;   // true
-    udp.first<IPv4Packet>() == ip;      // true
+    udp.find<EthernetPacket>();         // throws InvalidPacketChainException
+    udp.find<EthernetPacket>(senf::nothrow); // An in-valid() senf::Packet which tests as 'false'
+    udp.find<UDPPacket()> == udp;       // true
+    udp.first<IPv4Packet>();            // throws InvalidPacketChainException
 
     udp.prev() == ip;                   // true
-    udp.prev<EthernetPacket>() == eth   // true
+    udp.prev<EthernetPacket>();         // throws Inv
     \endcode
 
-    ... and so on. It is therefore not necessary to stash away a reference for every interpreter (as
-    each of the sub-packets are called) as long as at least one reference is available.
+    ... and so on. See the senf::Packet documentation for more. Using these members, the complete
+    chain of packet interpreters (as these sub-packets or headers are called) may be traversed from
+    any packet handle.
 
     These chain navigation functions are also used to parse a packet. Let's read an Ethernet packet
     from a packet socket handle:
     
     \code
     senf::PacketSocketHandle sock ("eth0");
-    senf::EthernetPacket packet (senf::EthernetPacket::create(senf::Packet::noinit));
+    senf::EthernetPacket packet (senf::EthernetPacket::create(senf::noinit));
     sock.read(packet.data(),0u);
     \endcode
 
 
     \code
     try {
-        senf::UDPPacket udp (packet.findNext<UDPPacket>(senf::nothrow));
-        if (udp && udp->destination() == 2001u) {
+        senf::UDPPacket udp (packet.find<UDPPacket>());
+        if (udp->destination() == 2001u) {
             // Voila ...
         }
-    } catch (senf::TruncatedPacketException const &) {
-        std::cerr << "Ooops !! Broken packet received ...\n"
+    } catch (senf::TruncatedPacketException &) {
+        std::cerr << "Ooops !! Broken packet received\n";
+    } catch (senf::InvalidPacketChainException &) {
+        std::cerr << "Not a udp packet\n";
     }
     \endcode
 
     TruncatedPacketException is thrown by <tt>udp->destination()</tt> if that field cannot be
-    accessed. More generally, whenever a field cannot be accessed because it would be out of bounds
+    accessed (that is it would be beyond the data read which means we have read a truncated
+    packet). More generally, whenever a field cannot be accessed because it would be out of bounds
     of the data read, this exception is generated.
 
     This is only a very short introduction to the library to give a feel for the implementation. For