Packets: Packet::clone() clones now also annotations
tho [Wed, 15 Sep 2010 13:44:15 +0000 (13:44 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1715 270642c3-0616-0410-b53a-bc976706d245

senf/Packets/Packet.hh
senf/Packets/Packet.test.cc
senf/Packets/PacketImpl.cc
senf/Packets/PacketImpl.hh
senf/Packets/PacketImpl.ih
senf/Packets/PacketInterpreter.cc

index cc9c9f2..8b116e6 100644 (file)
@@ -164,9 +164,9 @@ namespace senf {
                                              validity. */
         Packet clone() const;           ///< Create copy 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. */
+                                             packet. The returned packet will have the same data,
+                                             annotations and packet chain. It does however not
+                                             share any data with the original packet. */
 
         // conversion constructors
 
index 1684a88..62b22c4 100644 (file)
@@ -349,11 +349,17 @@ SENF_AUTO_UNIT_TEST(packetAnnotation)
     BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().s, "dead beef" );
     BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().i, 0x12345678 );
 
+    senf::Packet pClone (packet.clone());
+
     p2.clearAnnotations();
     BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().s, "empty" );
     BOOST_CHECK_EQUAL( p2.annotation<ComplexAnnotation>().i, -1 );
     BOOST_CHECK_EQUAL( p2.annotation<IntAnnotation>().value, 0 );
 
+    BOOST_CHECK_EQUAL( pClone.annotation<IntAnnotation>().value, 0xDEADBEEFu );
+    BOOST_CHECK_EQUAL( pClone.annotation<ComplexAnnotation>().s, "dead beef" );
+    BOOST_CHECK_EQUAL( pClone.annotation<ComplexAnnotation>().i, 0x12345678 );
+
     BOOST_CHECK( Reg::lookup<IntAnnotation>() >= 0 );
     BOOST_CHECK( Reg::lookup<LargeAnnotation>() < 0 );
     BOOST_CHECK( Reg::lookup<ComplexAnnotation>() < 0 );
index c374e6d..c958d44 100644 (file)
@@ -162,6 +162,14 @@ prefix_ void senf::detail::PacketImpl::clearAnnotations()
     complexAnnotations_.clear();
 }
 
+prefix_ void senf::detail::PacketImpl::assignAnnotations(PacketImpl const & other)
+{
+    std::copy(&other.simpleAnnotations_[0], &other.simpleAnnotations_[0] +
+            sizeof(simpleAnnotations_)/sizeof(simpleAnnotations_[0]), simpleAnnotations_);
+    complexAnnotations_.assign(
+            other.complexAnnotations_.begin(), other.complexAnnotations_.end());
+}
+
 prefix_ void * senf::detail::PacketImpl::complexAnnotation(AnnotationRegistry::key_type key)
 {
     SENF_ASSERT( key < 0, "complexAnnotation called with invalid key");
index 32b2acf..b41fe23 100644 (file)
@@ -172,6 +172,7 @@ namespace detail {
         Annotation & annotation();
 
         void clearAnnotations();
+        void assignAnnotations(PacketImpl const & other);
         void dumpAnnotations(std::ostream & os);
 
         /** \brief Internal: Keep PacketImpl instance alive
index e6b7bfe..c04e136 100644 (file)
@@ -154,8 +154,16 @@ namespace detail {
         virtual ~EntryBase() {}
 
         virtual void * get() = 0;
+
+        typedef EntryBase * ptr;
+        virtual ptr clone() const = 0;
     };
 
+    inline AnnotationRegistry::EntryBase::ptr new_clone( AnnotationRegistry::EntryBase const & entry)
+    {
+        return entry.clone();
+    }
+
     template <class Annotation>
     class AnnotationRegistry::Entry
         : public AnnotationRegistry::EntryBase
@@ -168,6 +176,7 @@ namespace detail {
             { senf::IGNORE(&proxy_); return key_; }
 
         virtual void * get() { return & annotation_; }
+        virtual EntryBase::ptr clone() const { return new Entry<Annotation>( *this); }
 
     private:
         Annotation annotation_;
index 3b03742..be6c63d 100644 (file)
@@ -46,6 +46,7 @@ prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::clone()
     ptr pi (appendClone(p.p,begin(),p.p->begin()));
     for (ptr i (next()); i; i = i->next())
         i->appendClone(p.p,begin(),p.p->begin());
+    pi->impl().assignAnnotations( impl());
     return pi;
 }