Adjustment and fixes for boost-1.36 support
[senf.git] / Packets / Packet.test.cc
index e79f172..bb0c7b0 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
-// Copyright (C) 2007 
-// Fraunhofer Institute for Open Communication Systems (FOKUS) 
-// Competence Center NETwork research (NET), St. Augustin, GERMANY 
+// 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
@@ -28,6 +28,7 @@
 
 // Custom includes
 #include <sstream>
+#include <boost/static_assert.hpp>
 #include "Packets.hh"
 
 #include "../Utils/auto_unit_test.hh"
@@ -49,9 +50,15 @@ namespace {
         using senf::PacketTypeMixin<FooPacketType>::nextPacketRange;
         using senf::PacketTypeMixin<FooPacketType>::initSize;
         using senf::PacketTypeMixin<FooPacketType>::init;
-        typedef senf::PacketInterpreter<FooPacketType> interpreter;
-        static interpreter::size_type initSize()
+        static size_type initSize()
             { return 4u; }
+
+        // We need to implement initHeadSize() to force the mixin to switch into 'fixed-size'
+        // mode. Otherwise, mixin::nextPacketRange() would query the parser for it's size to find
+        // the header size. Since the parser is VoidPacketParser, the header size would therefore be
+        // 0
+        static size_type initHeadSize() 
+            { return initSize(); }
     };
     typedef senf::ConcretePacket<FooPacketType> FooPacket;
 
@@ -63,6 +70,10 @@ namespace {
         SENF_PARSER_FIELD( length,   senf::Int32Parser  );
         SENF_PARSER_FIELD( reserved, senf::UInt16Parser );
 
+        SENF_PARSER_INIT() {
+            reserved() << 0xA0A0u;
+        }
+
         SENF_PARSER_FINALIZE(BarPacketParser);
     };
 
@@ -77,11 +88,6 @@ namespace {
         using mixin::nextPacketType;
         using mixin::initSize;
         using mixin::init;
-        static size_type initSize() 
-            { return 8u; }
-        static void init(packet p) {
-            p->reserved() = 0xA0A0u;
-        }
         static void dump(packet p, std::ostream & os) {
             os << "BarPacket:\n"
                << "type: " << p->type() << "\n"
@@ -93,7 +99,7 @@ namespace {
             else
                 p->type() = -1;
         }
-        static registry_key_t nextPacketKey(packet p) {
+        static key_t nextPacketKey(packet p) {
             return p->type();
         }
     };
@@ -104,6 +110,28 @@ namespace {
         senf::PacketRegistry<RegTag>::RegistrationProxy<BarPacket> registerBar(2u);
     }
 
+    struct IntAnnotation {
+        unsigned value;
+    };
+    
+    struct LargeAnnotation {
+        char value[32];
+    };
+
+    struct ComplexAnnotation : senf::ComplexAnnotation
+    {
+        std::string s;
+        int i;
+    };
+
+    struct ComplexEmptyAnnotation : senf::ComplexAnnotation
+    {};
+
+    struct InvalidAnnotation
+    {
+        std::string value;
+    };
+
 }
 
 BOOST_AUTO_UNIT_TEST(packet)
@@ -117,6 +145,10 @@ BOOST_AUTO_UNIT_TEST(packet)
     BOOST_CHECK( ! packet.prev(senf::nothrow) );
     BOOST_CHECK( packet.next().prev() == packet );
     BOOST_CHECK( packet.next() != packet );
+    BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.next().data().begin()), 4 );
+    BOOST_CHECK_EQUAL( std::distance(packet.data().begin(), packet.data().end()), 12 );
+    BOOST_CHECK_EQUAL( std::distance(packet.next().data().begin(), packet.next().data().end()), 8 );
+    BOOST_CHECK( packet.data().end() == packet.next().data().end() );
     BOOST_CHECK_EQUAL( packet.size(), 12u );
     BOOST_CHECK_EQUAL( packet.next().size(), 8u );
     BOOST_CHECK( packet.is<FooPacket>() );
@@ -150,11 +182,14 @@ BOOST_AUTO_UNIT_TEST(packet)
     packet.dump(s);
     BOOST_CHECK_EQUAL( s.str(), "BarPacket:\ntype: 0\nlength: 0\n" );
     
-    packet.finalize();
+    packet.finalizeAll();
     BOOST_CHECK_EQUAL( packet.last().as<BarPacket>()->type(), 
-                       BarPacket::type::parser::type_t::value_type(-1) );
+                       BarPacket::Parser::type_t::value_type(-1) );
     packet.last().append(FooPacket::create());
-    packet.finalize();
+    packet.finalizeThis();
+    packet.finalizeTo<BarPacket>();
+    packet.finalizeTo(packet.find<BarPacket>());
+    packet.finalizeAll();
     BOOST_CHECK_EQUAL( packet.find<BarPacket>()->type(), 1u );
 
     BOOST_CHECK( packet.factory() == FooPacket::factory() );
@@ -186,10 +221,11 @@ BOOST_AUTO_UNIT_TEST(concretePacket)
     senf::PacketData::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
 
     BOOST_CHECK_EQUAL( FooPacket::create().size(), 4u );
-    BOOST_CHECK_EQUAL( FooPacket::create(FooPacket::noinit).size(), 0u );
+    BOOST_CHECK_EQUAL( FooPacket::create(senf::noinit).size(), 0u );
     BOOST_CHECK_THROW( FooPacket::create(2u), senf::TruncatedPacketException );
-    BOOST_CHECK_EQUAL( FooPacket::create(10u).size(), 10u );
-    BOOST_CHECK_EQUAL( FooPacket::create(2u,FooPacket::noinit).size(), 2u );
+    // No 'u' suffix here to check, that the disable_if works ...
+    BOOST_CHECK_EQUAL( FooPacket::create(10).size(), 10u );
+    BOOST_CHECK_EQUAL( FooPacket::create(2u,senf::noinit).size(), 2u );
     BOOST_CHECK_EQUAL( FooPacket::create(data).size(), 6u );
 
     senf::Packet packet (FooPacket::create());
@@ -197,14 +233,15 @@ BOOST_AUTO_UNIT_TEST(concretePacket)
     BOOST_CHECK_EQUAL( FooPacket::createAfter(packet).size(), 4u );
     BOOST_CHECK_EQUAL( packet.size(), 8u );
 
-    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,FooPacket::noinit).size(), 0u );
+    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,senf::noinit).size(), 0u );
     BOOST_CHECK_EQUAL( packet.size(), 4u );
 
     BOOST_CHECK_THROW( FooPacket::createAfter(packet,2u), senf::TruncatedPacketException );
-    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,10u).size(), 10u );
+    // No 'u' suffix here to check, that the disable_if works ...
+    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,10).size(), 10u );
     BOOST_CHECK_EQUAL( packet.size(), 14u );
     
-    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,2u,FooPacket::noinit).size(), 2u );
+    BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,2u,senf::noinit).size(), 2u );
     BOOST_CHECK_EQUAL( packet.size(), 6u );
     
     BOOST_CHECK_EQUAL( FooPacket::createAfter(packet,data).size(), 6u );
@@ -213,13 +250,55 @@ BOOST_AUTO_UNIT_TEST(concretePacket)
     BOOST_CHECK_EQUAL( FooPacket::createBefore(packet).size(), 14u );
     BOOST_CHECK_EQUAL( packet.size(), 10u );
 
-    BOOST_CHECK_EQUAL( FooPacket::createBefore(packet,FooPacket::noinit).size(), 10u );
+    BOOST_CHECK_EQUAL( FooPacket::createBefore(packet,senf::noinit).size(), 10u );
     BOOST_CHECK_EQUAL( packet.size(), 10u );
 
     BOOST_CHECK( packet.clone() != packet );
     BOOST_CHECK_EQUAL( BarPacket::create()->reserved(), 0xA0A0u );
 }
 
+BOOST_AUTO_UNIT_TEST(packetAnnotation)
+{
+    senf::Packet packet (FooPacket::create());
+    BarPacket::createAfter(packet);
+
+    ComplexAnnotation & ca (packet.annotation<ComplexAnnotation>());
+    ca.s = "dead beef";
+    ca.i = 0x12345678;
+    SENF_CHECK_NO_THROW( packet.annotation<IntAnnotation>().value = 0xDEADBEEF );
+
+    senf::Packet p2 (packet.next());
+
+    BOOST_CHECK_EQUAL( p2.annotation<IntAnnotation>().value, 0xDEADBEEFu );
+    BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().s, "dead beef" );
+    BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().i, 0x12345678 );
+
+    BOOST_CHECK( senf::detail::AnnotationIndexer<IntAnnotation>::Small );
+    BOOST_CHECK( ! senf::detail::AnnotationIndexer<LargeAnnotation>::Small );
+    BOOST_CHECK( ! senf::detail::AnnotationIndexer<ComplexAnnotation>::Small );
+    BOOST_CHECK( ! senf::detail::AnnotationIndexer<ComplexEmptyAnnotation>::Small );
+}
+
+#ifdef COMPILE_CHECK
+
+COMPILE_FAIL(invalidAnnotation)
+{
+#if 0 // The traits check fails for user defined but trivial constructors so ...
+#   ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
+
+    senf::Packet packet (FooPacket::create());
+    (void) packet.annotation<InvalidAnnotation>();
+
+#   else
+#   endif
+#endif
+
+    invalid_annotation_check_disabled();
+
+}
+
+#endif
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_