From 4ade9be43178f117ecf3e94fed9249e5341620ec Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 18 Nov 2009 21:06:12 +0000
Subject: [PATCH] From Axel and Philippe: When streaming a base class without
 StreamerNVirtual() use an external streamer if it was set. Fixes Savannah
 #59093.

git-svn-id: http://root.cern.ch/svn/root/trunk@31298 27541ba8-7e3a-0410-8455-c3a389f83636
---
 core/meta/src/TStreamerElement.cxx | 59 ++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 11 deletions(-)

diff --git a/core/meta/src/TStreamerElement.cxx b/core/meta/src/TStreamerElement.cxx
index af0bbc37191..d4403e8c398 100644
--- a/core/meta/src/TStreamerElement.cxx
+++ b/core/meta/src/TStreamerElement.cxx
@@ -20,6 +20,7 @@
 #include "TVirtualStreamerInfo.h"
 #include "TClass.h"
 #include "TClassEdit.h"
+#include "TClassStreamer.h"
 #include "TBaseClass.h"
 #include "TDataMember.h"
 #include "TDataType.h"
@@ -593,12 +594,28 @@ Int_t TStreamerBase::ReadBuffer (TBuffer &b, char *pointer)
       fMethod->SetParamPtrs(args);
       fMethod->Execute((void*)(pointer+fOffset));
    } else {
-     // printf("Reading baseclass:%s via ReadBuffer\n",fBaseClass->GetName());
-      //fBaseClass->ReadBuffer(b,pointer+fOffset);
-      if( fNewBaseClass )
-         b.ReadClassBuffer( fNewBaseClass, pointer+fOffset, fBaseClass );
-      else
-         b.ReadClassBuffer( fBaseClass, pointer+fOffset );
+      // We don't have a StreamerNVirtual(). That still doesn't mean
+      // that there is no streamer - it could be an external one:
+      // If the old base class has an adopted streamer we take that
+      // one instead of the new base class:
+      if( fNewBaseClass ) {
+         TClassStreamer* extstrm = fNewBaseClass->GetStreamer();                  
+         if (extstrm) {
+            // The new base class has an adopted streamer:
+            extstrm->SetOnFileClass(fBaseClass);
+            (*extstrm)(b, pointer);
+         } else {
+            b.ReadClassBuffer( fNewBaseClass, pointer+fOffset, fBaseClass ); 
+         }
+      } else {
+         TClassStreamer* extstrm = fBaseClass->GetStreamer();         
+         if (extstrm) {
+            // The class has an adopted streamer:
+            (*extstrm)(b, pointer);
+         } else {
+            b.ReadClassBuffer( fBaseClass, pointer+fOffset );
+         }
+      }
    }
    return 0;
 }
@@ -665,11 +682,31 @@ Int_t TStreamerBase::WriteBuffer (TBuffer &b, char *pointer)
    // Write the base class into the buffer.
 
    if (!fMethod) {
-      //      if (fBaseClass->GetClassInfo()) fBaseClass->WriteBuffer(b,pointer);
-      // now always write ... the previous implementation did not even match
-      // the ReadBuffer?
-      fBaseClass->WriteBuffer(b,pointer+fOffset);
-      return 0;
+      // We don't have a StreamerNVirtual(). That still doesn't mean
+      // that there is no streamer - it could be an external one:
+      // If the old base class has an adopted streamer we take that
+      // one instead of the new base class:
+      if (fNewBaseClass) {
+         TClassStreamer* extstrm = fNewBaseClass->GetStreamer();
+         if (extstrm) {
+            // The new base class has an adopted streamer:
+            extstrm->SetOnFileClass(fBaseClass);
+            (*extstrm)(b, pointer);
+            return 0;
+         } else {
+            fNewBaseClass->WriteBuffer(b,pointer+fOffset);
+            return 0;
+         }
+      } else {
+         TClassStreamer* extstrm = fBaseClass->GetStreamer();
+         if (extstrm) {
+            (*extstrm)(b, pointer);
+            return 0;
+         } else {
+            fBaseClass->WriteBuffer(b,pointer+fOffset);
+            return 0;
+         }
+      }
    }
    ULong_t args[1];
    args[0] = (ULong_t)&b;
-- 
GitLab