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