// @(#)root/meta:$Name: $:$Id: TStreamerInfo.cxx,v 1.170 2003/04/30 16:22:52 brun Exp $
// Author: Rene Brun 12/10/2000
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// //
//////////////////////////////////////////////////////////////////////////
#include "TROOT.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"
#include "TClass.h"
#include "TDataMember.h"
#include "TMethodCall.h"
#include "TDataType.h"
#include "TRealData.h"
#include "TBaseClass.h"
#include "TBuffer.h"
#include "TArrayC.h"
#include "TArrayI.h"
#include "TArrayF.h"
#include "TArrayD.h"
#include "TArrayS.h"
#include "TArrayL.h"
#include "TError.h"
#include "TRef.h"
#include "TProcessID.h"
Int_t TStreamerInfo::fgCount = 0;
Bool_t TStreamerInfo::fgCanDelete = kTRUE;
Bool_t TStreamerInfo::fgOptimize = kTRUE;
TStreamerElement *TStreamerInfo::fgElement = 0;
const Int_t kRegrouped = TStreamerInfo::kOffsetL;
const Int_t kMaxLen = 1024;
ClassImp(TStreamerInfo)
//______________________________________________________________________________
TStreamerInfo::TStreamerInfo()
{
// Default ctor.
fNumber = fgCount;
fClass = 0;
fElements = 0;
fType = 0;
fNewType = 0;
fOffset = 0;
fLength = 0;
fElem = 0;
fMethod = 0;
fCheckSum = 0;
fNdata = 0;
fSize = 0;
fClassVersion = 0;
fOptimized = kFALSE;
}
//______________________________________________________________________________
TStreamerInfo::TStreamerInfo(TClass *cl, const char *info)
: TNamed(cl->GetName(),info)
{
// Create a TStreamerInfo object.
fgCount++;
fNumber = fgCount;
fClass = cl;
fElements = new TObjArray();
fType = 0;
fNewType = 0;
fOffset = 0;
fLength = 0;
fElem = 0;
fMethod = 0;
fCheckSum = 0;
fNdata = 0;
fSize = 0;
fOptimized = kFALSE;
fClassVersion = fClass->GetClassVersion();
if (info) BuildUserInfo(info);
}
//______________________________________________________________________________
TStreamerInfo::~TStreamerInfo()
{
// TStreamerInfo dtor.
if (fNdata) {
delete [] fType;
delete [] fNewType;
delete [] fOffset;
delete [] fLength;
delete [] fElem;
delete [] fMethod;
}
if (!fElements) return;
fElements->Delete();
delete fElements;
}
//______________________________________________________________________________
void TStreamerInfo::Build()
{
// Build the I/O data structure for the current class version
// A list of TStreamerElement derived classes is built by scanning
// one by one the list of data members of the analyzed class.
TStreamerElement::Class()->IgnoreTObjectStreamer();
//if (!strcmp(fClass->GetName(),"TVector3")) fClass->IgnoreTObjectStreamer();
fClass->BuildRealData();
fCheckSum = fClass->GetCheckSum();
Int_t i, ndim, offset;
TClass *clm;
TDataType *dt;
TDataMember *dm;
TBaseClass *base;
TStreamerElement *element;
TIter nextb(fClass->GetListOfBases());
//iterate on list of base classes
while((base = (TBaseClass*)nextb())) {
// this case appears with STL collections as base class.
Streamer_t streamer = 0;
offset = base->GetDelta();
if (offset == kMissing) continue;
if (strcmp(base->GetName(),"string") == 0) {
TStreamerSTLstring *stls = new TStreamerSTLstring(base->GetName(),base->GetTitle(),offset,base->GetName());
fElements->Add(stls);
stls->SetStreamer(streamer);
continue;
}
if (base->IsSTLContainer()) {
TStreamerSTL *stl = new TStreamerSTL(base->GetName(),base->GetTitle(),offset,base->GetName(),0,0);
if (stl->GetSTLtype()) {
fElements->Add(stl);
stl->SetStreamer(streamer);
}
else delete stl;
continue;
}
clm = gROOT->GetClass(base->GetName());
if (!clm) {
Error("Build","%s, unknown type: %s %sn",GetName(),base->GetName(),base->GetTitle());
continue;
}
clm->GetStreamerInfo();
offset = fClass->GetBaseClassOffset(clm);
element = new TStreamerBase(base->GetName(),base->GetTitle(),offset);
if (clm == TObject::Class() && fClass->CanIgnoreTObjectStreamer()) {
SetBit(TClass::kIgnoreTObjectStreamer);
element->SetType(-1);
}
fElements->Add(element);
if (!clm->IsLoaded()) {
Warning("Build:","%s: base class %s has no streamer or dictionary it will not be saved",
GetName(), clm->GetName());
}
}
//iterate on list of data members
TIter nextd(fClass->GetListOfDataMembers());
while((dm=(TDataMember*)nextd())) {
if (fClass->GetClassVersion() == 0) continue;
if (!dm->IsPersistent()) continue;
Streamer_t streamer = 0;
offset = GetDataMemberOffset(dm,streamer);
if (offset == kMissing) continue;
//look for a data member with a counter in the comment string [n]
TRealData *refcount = 0;
TDataMember *dmref = 0;
if (dm->IsaPointer()) {
const char *title = (char*)dm->GetTitle();
const char *lbracket = strchr(title,'[');
const char *rbracket = strchr(title,']');
if (lbracket && rbracket) {
refcount = (TRealData*)fClass->GetListOfRealData()->FindObject(dm->GetArrayIndex());
if (!refcount) {
Error("Build","%s, discarding: %s %s, illegal %sn",GetName(),dm->GetFullTypeName(),dm->GetName(),title);
continue;
}
dmref = refcount->GetDataMember();
TDataType *reftype = dmref->GetDataType();
Bool_t isInteger = reftype->GetType() == 3 || reftype->GetType() == 13;
if (!reftype || !isInteger) {
Error("Build","%s, discarding: %s %s, illegal [%s] (must be Int_t)n",GetName(),dm->GetFullTypeName(),dm->GetName(),dm->GetArrayIndex());
continue;
}
TStreamerBasicType *bt = TStreamerInfo::GetElementCounter(dm->GetArrayIndex(),dmref->GetClass(),dmref->GetClass()->GetClassVersion());
if (!bt) {
if (dmref->GetClass()->Property() & kIsAbstract) continue;
Error("Build","%s, discarding: %s %s, illegal [%s] must be placed before n",GetName(),dm->GetFullTypeName(),dm->GetName(),dm->GetArrayIndex());
continue;
}
}
}
dt=dm->GetDataType();
ndim = dm->GetArrayDim();
if (dt) { // found a basic type
Int_t dtype = dt->GetType();
Int_t dsize = dt->Size();
if (!refcount && (strstr(dm->GetFullTypeName(),"char*")
|| strstr(dm->GetFullTypeName(),"Char_t*"))) {
dtype = kCharStar;
dsize = sizeof(char*);
}
if (dm->IsaPointer() && dtype != kCharStar) {
if (refcount) {
// data member is pointer to an array of basic types
element = new TStreamerBasicPointer(dm->GetName(),dm->GetTitle(),offset,dtype,
dm->GetArrayIndex(),
dmref->GetClass()->GetName(),
dmref->GetClass()->GetClassVersion(),
dm->GetFullTypeName());
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetSize(dsize);
fElements->Add(element);
continue;
} else {
if (fName == "TString" || fName == "TClass") continue;
Error("Build","%s, discarding: %s %s, no [dimension]n",GetName(),dm->GetFullTypeName(),dm->GetName());
continue;
}
}
// data member is a basic type
if (fClass == TObject::Class() && !strcmp(dm->GetName(),"fBits")) {
//printf("found fBits, changing dtype from %d to 15n",dtype);
dtype = kBits;
}
element = new TStreamerBasicType(dm->GetName(),dm->GetTitle(),offset,dtype,dm->GetFullTypeName());
Int_t ndim = dm->GetArrayDim();
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetSize(dsize);
fElements->Add(element);
continue;
} else {
// try STL container or string
static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
if (strcmp(dm->GetTypeName(),"string") == 0
||strcmp(dm->GetTypeName(),full_string_name)==0 ) {
TStreamerSTLstring *stls = new TStreamerSTLstring(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName());
fElements->Add(stls);
for (i=0;i<ndim;i++) stls->SetMaxIndex(i,dm->GetMaxIndex(i));
stls->SetArrayDim(ndim);
stls->SetStreamer(streamer);
continue;
}
if (dm->IsSTLContainer()) {
TStreamerSTL *stl = new TStreamerSTL(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName(),dm->GetTrueTypeName(),dm->IsaPointer());
if (stl->GetSTLtype()) {
fElements->Add(stl);
for (i=0;i<ndim;i++) stl->SetMaxIndex(i,dm->GetMaxIndex(i));
stl->SetArrayDim(ndim);
stl->SetStreamer(streamer);
}
else delete stl;
continue;
}
clm = gROOT->GetClass(dm->GetTypeName());
if (!clm) {
Error("Build","%s, unknow type: %s %sn",GetName(),dm->GetFullTypeName(),dm->GetName());
continue;
}
// a pointer to a class
if (dm->IsaPointer()) {
if(refcount) {
element = new TStreamerLoop(dm->GetName(),
dm->GetTitle(),offset,
dm->GetArrayIndex(),
dmref->GetClass()->GetName(),
dmref->GetClass()->GetClassVersion(),
dm->GetFullTypeName());
fElements->Add(element);
element->SetStreamer(streamer);
continue;
} else {
if (clm->InheritsFrom(TObject::Class())) {
element = new TStreamerObjectPointer(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName());
fElements->Add(element);
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetStreamer(streamer);
continue;
} else {
element = new TStreamerObjectAnyPointer(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName());
fElements->Add(element);
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetStreamer(streamer);
if (!streamer && !clm->IsLoaded()) {
Error("Build:","%s: %s has no streamer or dictionary, data member %s will not be saved",
GetName(), dm->GetFullTypeName(),dm->GetName());
}
continue;
}
}
}
// a class
if (clm->InheritsFrom(TObject::Class())) {
element = new TStreamerObject(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName());
fElements->Add(element);
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetStreamer(streamer);
continue;
} else if(clm == TString::Class() && !dm->IsaPointer()) {
element = new TStreamerString(dm->GetName(),dm->GetTitle(),offset);
fElements->Add(element);
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetStreamer(streamer);
continue;
} else {
element = new TStreamerObjectAny(dm->GetName(),dm->GetTitle(),offset,dm->GetFullTypeName());
if (!streamer && !clm->IsLoaded()) {
Warning("Build:","%s: %s has no streamer or dictionary, data member "%s" will not be saved",
GetName(), dm->GetFullTypeName(),dm->GetName());
}
fElements->Add(element);
for (i=0;i<ndim;i++) element->SetMaxIndex(i,dm->GetMaxIndex(i));
element->SetArrayDim(ndim);
element->SetStreamer(streamer);
continue;
}
}
}
Compile();
}
//______________________________________________________________________________
void TStreamerInfo::BuildCheck()
{
// check if the TStreamerInfo structure is already created
// called by TFile::ReadStreamerInfo
fClass = gROOT->GetClass(GetName());
TObjArray *array;
if (fClass) {
array = fClass->GetStreamerInfos();
TStreamerInfo *info = (TStreamerInfo *)array->At(fClassVersion);
// NOTE: Should we check if the already exsiting info is the same as
// the current one? Yes
// In case a class (eg Event.h) has a TClonesArray of Tracks, it could be
// that the old info does not have the class name (Track) in the data
// member title. Set old title to new title
if (info) {
SetBit(kCanDelete);
fNumber = info->GetNumber();
Int_t nel = fElements->GetEntriesFast();
TObjArray *elems = info->GetElements();
TStreamerElement *e1, *e2;
for (Int_t i=0;i<nel;i++) {
e1 = (TStreamerElement *)fElements->At(i);
e2 = (TStreamerElement *)elems->At(i);
if (!e1 || !e2) continue;
if (strlen(e1->GetTitle()) != strlen(e2->GetTitle())) {
e2->SetTitle(e1->GetTitle());
}
}
return;
}
if (fClass->GetListOfDataMembers()
&& (fClassVersion == fClass->GetClassVersion())
&& (fCheckSum != fClass->GetCheckSum())
&& (fClass->GetClassInfo()) ) {
//give a last chance. Due to a new CINT behaviour with enums
//verify the checksum ignoring members of type enum
if (fCheckSum != fClass->GetCheckSum(1)) {
Warning("BuildCheck","n\
The StreamerInfo of class %s read from file %sn\
has the same version (=%d) as the active class but a different checksum.n\
You should update the version to ClassDef(%s,%d).n\
Do not try to write objects with the current class definition,n\
the files will not be readable.n",GetName(),gDirectory->GetFile()->GetName()
,fClassVersion,GetName(),fClassVersion+1);
}
} else {
if (info) {
Error("BuildCheck","Wrong class info");
SetBit(kCanDelete);
return;
}
}
} else {
fClass = new TClass(GetName(),fClassVersion, 0, 0, -1, -1 );
fClass->SetBit(TClass::kIsEmulation);
array = fClass->GetStreamerInfos();
}
if (TestBit(TClass::kIgnoreTObjectStreamer)) fClass->IgnoreTObjectStreamer();
if (fClassVersion < 0 || fClassVersion > 65000) {
printf("ERROR reading TStreamerInfo: %s fClassVersion=%dn",GetName(),fClassVersion);
SetBit(kCanDelete);
fNumber = -1;
return;
}
array->AddAtAndExpand(this,fClassVersion);
fgCount++;
fNumber = fgCount;
//add to the global list of StreamerInfo
TObjArray *infos = (TObjArray*)gROOT->GetListOfStreamerInfo();
infos->AddAtAndExpand(this,fNumber);
}
//______________________________________________________________________________
void TStreamerInfo::BuildFake(TFile *file)
{
// Create a Fake TStreamerInfo object.
char duName[100];
Assert(file);
Int_t fv = file->GetVersion()%100000;
Assert(fv < 30000);
fClassVersion = -1;
fCheckSum = 2001;
TObjArray *elements = GetElements();
if (!elements) return;
Int_t ndata = elements->GetEntries();
if (ndata == 0) return;
TStreamerElement *element;
Int_t i;
for (i=0;i<ndata;i++) {
element = (TStreamerElement*)elements->At(i);
if (!element) break;
int ty = element->GetType();
if (ty < kChar || ty >kULong+kOffsetL) continue;
if (ty == kLong ) element->SetType(kInt );
if (ty == kULong) element->SetType(kUInt );
if (ty == kLong +kOffsetL) element->SetType(kInt +kOffsetL);
if (ty == kULong+kOffsetL) element->SetType(kUInt+kOffsetL);
if (ty <= kULong) continue;
strcpy(duName,element->GetName());
strcat(duName,"QWERTY");
TStreamerBasicType *bt = new TStreamerBasicType(duName, "", 0, kInt,"Int_t");
{for (int j=ndata-1;j>=i;j--) {elements->AddAtAndExpand(elements->At(j),j+1);}}
elements->AddAt(bt,i);
ndata++;
i++;
}
BuildOld();
}
//______________________________________________________________________________
void TStreamerInfo::BuildOld()
{
// rebuild the TStreamerInfo structure
if (gDebug > 0) printf("n====>Rebuilding TStreamerInfo for class: %s, version: %dn",GetName(),fClassVersion);
fClass->BuildRealData();
TIter next(fElements);
TStreamerElement *element;
Int_t offset = 0;
Streamer_t streamer = 0;
Int_t sp = sizeof(void *);
while ((element = (TStreamerElement*)next())) {
element->SetNewType(element->GetType());
if (element->IsA() == TStreamerBase::Class()) {
TStreamerBase *base = (TStreamerBase*)element;
TClass *baseclass = base->GetClassPointer();
if (!baseclass) {
Warning("BuildOld","Missing base class: %s skipped",base->GetName());
baseclass = new TClass(element->GetName(),1,0,0,-1,-1);
element->Update(0,baseclass);
}
baseclass->BuildRealData();
Int_t version = base->GetBaseVersion();
TStreamerInfo *infobase = baseclass->GetStreamerInfo(version);
if (infobase->GetTypes() == 0) infobase->BuildOld();
element->Init();
Int_t baseOffset = fClass->GetBaseClassOffset(baseclass);
if (baseOffset < 0) baseOffset = 0;
element->SetOffset(baseOffset);
offset += baseclass->Size();
continue;
}
TDataMember *dm = (TDataMember*)fClass->GetListOfDataMembers()->FindObject(element->GetName());
// may be a fake class
if (!dm && fClass->GetDeclFileLine() < 0) {
streamer = 0;
element->Init(fClass);
element->SetStreamer(streamer);
Int_t alength = element->GetArrayLength();
if (alength == 0) alength = 1;
Int_t asize = element->GetSize();
//align the non-basic data types (required on alpha and IRIX!!)
if (offset%sp != 0) offset = offset - offset%sp + sp;
element->SetOffset(offset);
offset += asize;
} else if (dm && dm->IsPersistent()) {
TDataType *dt = dm->GetDataType();
fClass->BuildRealData();
streamer = 0;
offset = GetDataMemberOffset(dm,streamer);
element->SetOffset(offset);
element->Init(fClass);
element->SetStreamer(streamer);
// in case, element is an array check array dimension(s)
// check if data type has been changed
if (strcmp(element->GetTypeName(),dm->GetFullTypeName())) {
//if (element->IsOldFormat(dm->GetFullTypeName())) continue;
if (dt) {
if (element->GetType() != dt->GetType()) {
Int_t newtype = dt->GetType();
if (dm->IsaPointer()) newtype += kOffsetP;
else if (element->GetArrayLength() > 1) newtype += kOffsetL;
element->SetNewType(newtype);
if (gDebug > 0) Warning("BuildOld","element: %s::%s %s has new type: %s/%d",GetName(),element->GetTypeName(),element->GetName(),dm->GetFullTypeName(),newtype);
}
} else {
element->SetNewType(-2);
Warning("BuildOld","Cannot convert %s::%s from type:%s to type:%s, skip element",
GetName(),element->GetName(),element->GetTypeName(),dm->GetFullTypeName());
}
}
} else {
//last attempt via TRealData in case the member has been moved to a base class
TRealData *rd = fClass->GetRealData(element->GetName());
if (rd && rd->GetDataMember() ) {
element->SetOffset(rd->GetThisOffset());
dm = rd->GetDataMember();
TDataType *dt = dm->GetDataType();
if (dt) {
if (element->GetType() != dt->GetType()) {
element->SetNewType(dt->GetType());
if (gDebug > 0) Warning("BuildOld","element: %s::%s %s has new type: %s",GetName(),element->GetTypeName(),element->GetName(),dm->GetFullTypeName());
}
}
} else {
element->SetNewType(-1);
element->SetOffset(kMissing);
}
}
}
Compile();
}
//______________________________________________________________________________
void TStreamerInfo::BuildUserInfo(const char * /*info*/)
{
// Build the I/O data structure for the current class version
#ifdef TOBEIMPLEMENTED
Int_t nch = strlen(title);
char *info = new char[nch+1];
strcpy(info,title);
char *pos = info;
TDataType *dt;
TDataMember *dm;
TRealData *rdm, *rdm1;
TIter nextrdm(rmembers);
// search tokens separated by a semicolon
//tokens can be of the following types
// -baseclass
// -class membername
// -basictype membername
// -classpointer membername
// -basictypepointer membername
while(1) {
Bool_t isPointer = kFALSE;
while (*pos == ' ') pos++;
if (*pos == 0) break;
char *colon = strchr(pos,';');
char *col = colon;
if (colon) {
*col = 0; col--;
while (*col == ' ') {*col = 0; col--;}
if (pos > col) break;
char *star = strchr(pos,'*');
if (star) {*star = ' '; isPointer = kTRUE;}
char *blank;
while(1) {
blank = strstr(pos," ");
if (blank == 0) break;
strcpy(blank,blank+1);
}
blank = strrchr(pos,' '); //start in reverse order (case like unsigned short xx)
if (blank) {
*blank = 0;
//check that this is a known data member
dm = (TDataMember*)members->FindObject(blank+1);
rdm1 = 0;
nextrdm.Reset();
while((rdm = (TRealData*)nextrdm())) {
if (rdm->GetDataMember() != dm) continue;
rdm1 = rdm;
break;
}
if (!dm || !rdm1) {
printf("Unknown data member:%s %s in class:%sn",pos,blank+1,fClass->GetName());
pos = colon+1;
continue;
}
// Is type a class name?
TClass *clt = gROOT->GetClass(pos);
if (clt) {
//checks that the class matches with the data member declaration
if (strcmp(pos,dm->GetTypeName()) == 0) {
newtype[fNdata] = 20;
fNdata++;
printf("class: %s member=%sn",pos,blank+1);
} else {
printf("Mismatch between class:%s %s and data member:%s %s in class:%sn",
pos,blank+1,dm->GetTypeName(),blank+1,fClass->GetName());
}
// Is type a basic type?
} else {
dt = (TDataType*)gROOT->GetListOfTypes()->FindObject(pos);
if (dt) {
Int_t dtype = dt->GetType();
//check that this is a valid data member and that the
//declared type matches with the data member type
if (dm->GetDataType()->GetType() == dtype) {
//store type and offset
newtype[fNdata] = dtype;
newoffset[fNdata] = rdm->GetThisOffset();
fNdata++;
printf("type=%s, basic type=%s dtype=%d, member=%sn",pos,dt->GetFullTypeName(),dtype,blank+1);
} else {
printf("Mismatch between type:%s %s and data member:%s %s in class:%sn",
pos,blank+1,dm->GetTypeName(),blank+1,fClass->GetName());
}
} else {
printf("found unknown type:%s, member=%sn",pos,blank+1);
}
}
} else {
// very likely a base class
TClass *base = gROOT->GetClass(pos);
if (base && fClass->GetBaseClass(pos)) {
printf("base class:%sn",pos);
//get pointer to method baseclass::Streamer
TMethodCall *methodcall = new TMethodCall(base,"Streamer","");
newtype[fNdata] = 0;
newmethod[fNdata] = (ULong_t)methodcall;
fNdata++;
}
}
pos = colon+1;
}
}
fType = new Int_t[fNdata+1];
fOffset = new Int_t[fNdata+1];
fMethod = new ULong_t[fNdata+1];
for (Int_t i=0;i<fNdata;i++) {
fType[i] = newtype[i];
fOffset[i] = newoffset[i];
fMethod[i] = newmethod[i];
}
delete [] info;
delete [] newtype;
delete [] newoffset;
delete [] newmethod;
#endif
}
//______________________________________________________________________________
Bool_t TStreamerInfo::CanDelete()
{
// static function returning true if ReadBuffer can delete object
return fgCanDelete;
}
//______________________________________________________________________________
Bool_t TStreamerInfo::CanOptimize()
{
// static function returning true if optimization can be on
return fgOptimize;
}
//______________________________________________________________________________
void TStreamerInfo::Compile()
{
// loop on the TStreamerElement list
// regroup members with same type
// Store predigested information into local arrays. This saves a huge amount
// of time compared to an explicit iteration on all elements.
TObjArray *infos = (TObjArray*)gROOT->GetListOfStreamerInfo();
if (fNumber >= infos->GetSize()) {
infos->AddAtAndExpand(this,fNumber);
} else {
if (!infos->At(fNumber)) {
infos->AddAt(this,fNumber);
}
}
if (fNdata) {
delete [] fType;
delete [] fNewType;
delete [] fOffset;
delete [] fLength;
delete [] fElem;
delete [] fMethod;
}
fOptimized = kFALSE;
fNdata = 0;
Int_t ndata = fElements->GetEntries();
fOffset = new Int_t[ndata+1];
fType = new Int_t[ndata+1];
if (ndata == 0) return; //this may be the case for empty classes(eg TAtt3D)
fNewType= new Int_t[ndata];
fLength = new Int_t[ndata];
fElem = new ULong_t[ndata];
fMethod = new ULong_t[ndata];
TStreamerElement *element;
Int_t keep = -1;
Int_t i;
if (!fgOptimize) SetBit(kCannotOptimize);
for (i=0;i<ndata;i++) {
element = (TStreamerElement*)fElements->At(i);
if (!element) break;
if (element->GetType() < 0) continue;
Int_t asize = element->GetSize();
if (element->GetArrayLength()) asize /= element->GetArrayLength();
fType[fNdata] = element->GetType();
fNewType[fNdata]= element->GetNewType();
fOffset[fNdata] = element->GetOffset();
fLength[fNdata] = element->GetArrayLength();
fElem[fNdata] = (ULong_t)element;
fMethod[fNdata] = element->GetMethod();
// try to group consecutive members of the same type
if (!TestBit(kCannotOptimize) && keep>=0 && (element->GetType() < 10)
&& (fType[fNdata] == fNewType[fNdata])
&& (fMethod[keep] == 0)
&& (element->GetType() > 0)
&& (element->GetArrayDim() == 0)
&& (element->GetType() == (fType[keep]%kRegrouped))
&& ((element->GetOffset()-fOffset[keep]) == (fLength[keep])*asize)) {
if (fLength[keep] == 0) fLength[keep]++;
fLength[keep]++;
fType[keep] = element->GetType() + kRegrouped;
fOptimized = kTRUE;
} else {
if (fType[fNdata] != kCounter) {
if (fNewType[fNdata] != fType[fNdata]) {
if (fNewType[fNdata] > 0) fType[fNdata] += kConv;
else fType[fNdata] += kSkip;
}
}
keep = fNdata;
if (fLength[keep] == 0) fLength[keep] = 1;
fNdata++;
}
}
ComputeSize();
if (gDebug > 0) ls();
}
//______________________________________________________________________________
void TStreamerInfo::ComputeSize()
{
// Compute total size of all persistent elements of the class
TIter next(fElements);
TStreamerElement *element = (TStreamerElement*)fElements->Last();
//faster and more precise to use last element offset +size
//on 64 bit machines, offset may be forced to be a multiple of 8 bytes
fSize = element->GetOffset() + element->GetSize();
//fSize = 0;
//while ((element = (TStreamerElement*)next())) {
// fSize += element->GetSize();
//}
}
//______________________________________________________________________________
void TStreamerInfo::ForceWriteInfo(TFile *file, Bool_t force)
{
// will force this TStreamerInfo to the file and also
// all the dependencies.
// This function is called when streaming a class that contains
// a null pointer. In this case, the TStreamerInfo for the class
// with the null pointer must be written to the file and also all the
// TStreamerInfo of all the classes referenced by the class.
//
// if argument force > 0 the loop on class dependencies is forced
// flag this class
if (!file) return;
TArrayC *cindex = file->GetClassIndex();
//the test below testing fArray[fNumber]>1 is to avoid a recursivity
//problem in some cases like:
// class aProblemChild: public TNamed {
// aProblemChild *canBeNull;
// };
if ((cindex->fArray[fNumber] && !force) || cindex->fArray[fNumber]>1) return;
cindex->fArray[fNumber] = 2;
cindex->fArray[0] = 1;
// flag all its dependencies
TIter next(fElements);
TStreamerElement *element;
while ((element = (TStreamerElement*)next())) {
TClass *cl = element->GetClassPointer();
if (cl) {
const char *name = cl->GetName();
static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
if (!strcmp(name, "string")||!strcmp(name,full_string_name)) continue; //reject string
if (strstr(name, "vector<") || strstr(name, "list<") ||
strstr(name, "set<") || strstr(name, "map<") ||
strstr(name, "deque<") || strstr(name, "multimap<") ||
strstr(name, "multiset<") || strstr(name, "::" ))
continue; //reject STL containers
cl->BuildRealData();
cl->GetStreamerInfo()->ForceWriteInfo(file, force);
}
}
}
//______________________________________________________________________________
Int_t TStreamerInfo::GenerateHeaderFile(const char *dirname)
{
// Generate header file for the class described by this TStreamerInfo
// the function is called by TFile::MakeProject for each class in the file
TClass *cl = gROOT->GetClass(GetName());
if (cl) {
if (cl->GetClassInfo()) return 0; // skip known classes
}
if (gDebug) printf("generating code for class %sn",GetName());
//open the file
Int_t nch = strlen(dirname) + strlen(GetName()) + 4;
char *filename = new char[nch];
sprintf(filename,"%s/%s.h",dirname,GetName());
FILE *fp = fopen(filename,"w");
if (!fp) {
printf("Cannot open output file:%sn",filename);
delete [] filename;
return 0;
}
// generate class header
TDatime td;
fprintf(fp,"//////////////////////////////////////////////////////////n");
fprintf(fp,"// This class has been generated by TFile::MakeProjectn");
fprintf(fp,"// (%s by ROOT version %s)n",td.AsString(),gROOT->GetVersion());
fprintf(fp,"// from the StreamerInfo in file %sn",gDirectory->GetFile()->GetName());
fprintf(fp,"//////////////////////////////////////////////////////////n");
fprintf(fp,"n");
fprintf(fp,"n");
fprintf(fp,"#ifndef %s_hn",GetName());
fprintf(fp,"#define %s_hn",GetName());
fprintf(fp,"n");
// compute longest typename and member name
// in the same loop, generate list of include files
Int_t ltype = 10;
Int_t ldata = 10;
Int_t i,lt,ld;
char *line = new char[kMaxLen];
char name[128];
char cdim[8];
char *inclist = new char[5000];
inclist[0] = 0;
TIter next(fElements);
TStreamerElement *element;
Int_t ninc = 0;
while ((element = (TStreamerElement*)next())) {
//if (element->IsA() == TStreamerBase::Class()) continue;
sprintf(name,element->GetName());
for (i=0;i<element->GetArrayDim();i++) {
sprintf(cdim,"[%d]",element->GetMaxIndex(i));
strcat(name,cdim);
}
ld = strlen(name);
lt = strlen(element->GetTypeName());
if (ltype < lt) ltype = lt;
if (ldata < ld) ldata = ld;
//get include file name if any
const char *include = element->GetInclude();
if (strlen(include) == 0) continue;
const char *slash = strrchr(include,'/');
if (slash) include = slash+1;
// do not generate the include if already done
if (strstr(inclist,include)) continue;
ninc++;
strcat(inclist,include);
if (strstr(include,"include/") || strstr(include,"include\"))
fprintf(fp,"#include "%sn",include+9);
else {
if (slash) fprintf(fp,"#include "%sn",include);
else fprintf(fp,"#include %sn",include);
}
}
ltype += 2;
ldata++; // to take into account the semi colon
if (ninc == 0) fprintf(fp,"#include "TNamed.h"n");
// generate class statement with base classes
fprintf(fp,"nclass %s",GetName());
next.Reset();
Int_t nbase = 0;
while ((element = (TStreamerElement*)next())) {
if (element->IsA() != TStreamerBase::Class()) continue;
nbase++;
if (nbase == 1) fprintf(fp," : public %s",element->GetName());
else fprintf(fp," , public %s",element->GetName());
}
fprintf(fp," {n");
// generate data members
fprintf(fp,"npublic:n");
next.Reset();
while ((element = (TStreamerElement*)next())) {
for (i=0;i<kMaxLen;i++) line[i] = ' ';
if (element->IsA() == TStreamerBase::Class()) continue;
sprintf(name,element->GetName());
for (Int_t i=0;i<element->GetArrayDim();i++) {
sprintf(cdim,"[%d]",element->GetMaxIndex(i));
strcat(name,cdim);
}
strcat(name,";");
ld = strlen(name);
lt = strlen(element->GetTypeNameBasic());
strncpy(line+3,element->GetTypeNameBasic(),lt);
strncpy(line+3+ltype,name,ld);
if (element->IsaPointer() && !strchr(line,'*')) line[2+ltype] = '*';
sprintf(line+3+ltype+ldata," //%s",element->GetTitle());
fprintf(fp,"%sn",line);
}
// generate default functions, ClassDef and trailer
fprintf(fp,"n %s();n",GetName());
fprintf(fp," virtual ~%s();n\n",GetName());
fprintf(fp," ClassDef(%s,%d) //n",GetName(),fClassVersion);
fprintf(fp,"};n");
//generate constructor code
fprintf(fp,"%s::%s() {n",GetName(),GetName());
next.Reset();
while ((element = (TStreamerElement*)next())) {
if (element->GetType() == kObjectp || element->GetType() == kObjectP ||
element->GetType() == kAnyp || element->GetType() == kAnyP) {
fprintf(fp," %s = 0;n",element->GetName());
}
}
fprintf(fp,"}n\n");
//generate destructor code
fprintf(fp,"%s::~%s() {n",GetName(),GetName());
next.Reset();
while ((element = (TStreamerElement*)next())) {
if (element->GetType() == kObjectp || element->GetType() == kObjectP||
element->GetType() == kAnyp || element->GetType() == kAnyP) {
fprintf(fp," delete %s; %s = 0;n",element->GetName(),element->GetName());
}
}
fprintf(fp,"}n\n");
fprintf(fp,"#endifn");
fclose(fp);
delete [] filename;
delete [] inclist;
delete [] line;
return 1;
}
//______________________________________________________________________________
TStreamerElement *TStreamerInfo::GetCurrentElement()
{
//static function returning a pointer to the current TStreamerElement
//fgElement points to the current TStreamerElement being read in ReadBuffer
return fgElement;
}
//______________________________________________________________________________
Int_t TStreamerInfo::GetDataMemberOffset(TDataMember *dm, Streamer_t &streamer) const
{
// Compute data member offset
// return pointer to the Streamer function if one exists
TIter nextr(fClass->GetListOfRealData());
char dmbracket[256];
sprintf(dmbracket,"%s[",dm->GetName());
Int_t offset = kMissing;
if (fClass->GetDeclFileLine() < 0) offset = dm->GetOffset();
TRealData *rdm;
while ((rdm = (TRealData*)nextr())) {
char *rdmc = (char*)rdm->GetName();
//next statement required in case a class and one of its parent class
//have data members with the same name
if (dm->IsaPointer() && rdmc[0] == '*') rdmc++;
if (rdm->GetDataMember() != dm) continue;
if (strcmp(rdmc,dm->GetName()) == 0) {
offset = rdm->GetThisOffset();
streamer = rdm->GetStreamer();
break;
}
if (strcmp(rdm->GetName(),dm->GetName()) == 0) {
if (rdm->IsObject()) {
offset = rdm->GetThisOffset();
streamer = rdm->GetStreamer();
break;
}
}
if (strstr(rdm->GetName(),dmbracket)) {
offset = rdm->GetThisOffset();
streamer = rdm->GetStreamer();
break;
}
}
return offset;
}
//______________________________________________________________________________
TStreamerBasicType *TStreamerInfo::GetElementCounter(const char *countName, TClass *cl, Int_t version)
{
// Get pointer to a TStreamerBasicType in TClass *cl
//static function
TObjArray *sinfos = cl->GetStreamerInfos();
TStreamerInfo *info = (TStreamerInfo *)sinfos->At(version);
if (!info) return 0;
TStreamerElement *element = (TStreamerElement *)info->fElements->FindObject(countName);
if (!element) return 0;
if (element->IsA() == TStreamerBasicType::Class()) return (TStreamerBasicType*)element;
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::GetOffset(const char *elementName) const
{
// return the offset of the data member as indicated by this StreamerInfo
if (elementName==0) return 0;
Int_t offset = 0;
TStreamerElement *elem = (TStreamerElement*)fElements->FindObject(elementName);
if (elem) offset = elem->GetOffset();
return offset;
}
//______________________________________________________________________________
Int_t TStreamerInfo::GetSize() const
{
// return total size of all persistent elements of the class (with offsets)
return fSize;
}
//______________________________________________________________________________
Int_t TStreamerInfo::GetSizeElements() const
{
// return total size of all persistent elements of the class
// use GetSize if you want to get the real size in memory
TIter next(fElements);
TStreamerElement *element;
Int_t asize = 0;
while ((element = (TStreamerElement*)next())) {
asize += element->GetSize();
}
return asize;
}
//______________________________________________________________________________
TStreamerElement* TStreamerInfo::GetStreamerElement(const char* datamember, Int_t &offset) const
{
// Return the StreamerElement of "datamember" inside this class of any of its
// base class. The offset information contained in the StreamerElement is related
// to its immediate containing class, so we return in 'offset' the offset inside
// the class of this streamerInfo.
if (!fElements) return 0;
TStreamerElement *element = (TStreamerElement*)fElements->FindObject(datamember);
if (element) {
offset = element->GetOffset();
return element;
}
TStreamerElement *base_element;
TBaseClass *base;
TClass *base_cl;
Int_t base_offset = 0;
Int_t local_offset = 0;
TIter nextb(fClass->GetListOfBases());
//iterate on list of base classes
while((base = (TBaseClass*)nextb())) {
base_cl = gROOT->GetClass(base->GetName());
base_element = (TStreamerElement*)fElements->FindObject(base->GetName());
if (!base_cl || !base_element) continue;
base_offset = base_element->GetOffset();
element = base_cl->GetStreamerInfo()->GetStreamerElement(datamember,local_offset);
if (element) {
offset = base_offset + local_offset;
return element;
}
}
return 0;
}
//______________________________________________________________________________
Double_t TStreamerInfo::GetValue(char *pointer, Int_t i, Int_t j, Int_t len) const
{
// return value of element i in object at pointer.
// The function may be called in two ways:
// -method1 len < 0
// i is assumed to be the TStreamerElement number i in StreamerInfo
// -method2 len >= 0
// i is the type
// address of variable is directly pointer.
char *ladd;
Int_t atype;
if (len >= 0) {
ladd = pointer;
atype = i;
} else {
if (i < 0) return 0;
ladd = pointer + fOffset[i];
atype = fType[i];
}
switch (atype) {
// basic types
case kChar: {Char_t *val = (Char_t*)ladd; return Double_t(*val);}
case kShort: {Short_t *val = (Short_t*)ladd; return Double_t(*val);}
case kInt: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
case kLong: {Long_t *val = (Long_t*)ladd; return Double_t(*val);}
case kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
case kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(*val);}
case kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(*val);}
case kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(*val);}
case kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(*val);}
case kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
case kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(*val);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
#else
case kULong64: {ULong64_t *val = (ULong64_t*)ladd; return Double_t(*val);}
#endif
case kBits: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
// array of basic types array[8]
case kOffsetL + kChar: {Char_t *val = (Char_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kShort: {Short_t *val = (Short_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kInt: {Int_t *val = (Int_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kLong: {Long_t *val = (Long_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(val[j]);}
case kOffsetL + kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(val[j]);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kOffsetL + kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[j]);}
#else
case kOffsetL + kULong64: {ULong64_t *val = (ULong64_t*)ladd; return Double_t(val[j]);}
#endif
// pointer to an array of basic types array[n]
case kOffsetP + kChar: {Char_t **val = (Char_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kShort: {Short_t **val = (Short_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kInt: {Int_t **val = (Int_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kLong: {Long_t **val = (Long_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kLong64: {Long64_t **val = (Long64_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kFloat: {Float_t **val = (Float_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kDouble: {Double_t **val = (Double_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kUChar: {UChar_t **val = (UChar_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kUShort: {UShort_t **val = (UShort_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kUInt: {UInt_t **val = (UInt_t**)ladd; return Double_t((*val)[j]);}
case kOffsetP + kULong: {ULong_t **val = (ULong_t**)ladd; return Double_t((*val)[j]);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kOffsetP + kULong64: {Long64_t **val = (Long64_t**)ladd; return Double_t((*val)[j]);}
#else
case kOffsetP + kULong64: {ULong64_t **val = (ULong64_t**)ladd; return Double_t((*val)[j]);}
#endif
// array counter //[n]
case kCounter: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
}
return 0;
}
//______________________________________________________________________________
Double_t TStreamerInfo::GetValueClones(TClonesArray *clones, Int_t i, Int_t j, int k, Int_t eoffset) const
{
// return value of element i in object number j in a TClonesArray and eventually
// element k in a sub-array.
Int_t nc = clones->GetEntriesFast();
if (j >= nc) return 0;
Int_t bOffset = clones->GetClass()->GetBaseClassOffset(fClass);
if (bOffset > 0) eoffset += bOffset;
char *pointer = (char*)clones->UncheckedAt(j);
char *ladd = pointer + eoffset + fOffset[i];
switch (fType[i]) {
// basic types
case kChar: {Char_t *val = (Char_t*)ladd; return Double_t(*val);}
case kShort: {Short_t *val = (Short_t*)ladd; return Double_t(*val);}
case kInt: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
case kLong: {Long_t *val = (Long_t*)ladd; return Double_t(*val);}
case kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
case kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(*val);}
case kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(*val);}
case kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(*val);}
case kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(*val);}
case kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
case kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(*val);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
#else
case kULong64: {ULong64_t *val = (ULong64_t*)ladd; return Double_t(*val);}
#endif
case kBits: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
// array of basic types array[8]
case kOffsetL + kChar: {Char_t *val = (Char_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kShort: {Short_t *val = (Short_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kInt: {Int_t *val = (Int_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kLong: {Long_t *val = (Long_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(val[k]);}
case kOffsetL + kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(val[k]);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kOffsetL + kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[k]);}
#else
case kOffsetL + kULong64: {ULong64_t *val = (ULong64_t*)ladd; return Double_t(val[k]);}
#endif
// pointer to an array of basic types array[n]
case kOffsetP + kChar: {Char_t **val = (Char_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kShort: {Short_t **val = (Short_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kInt: {Int_t **val = (Int_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kLong: {Long_t **val = (Long_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kLong64: {Long64_t **val = (Long64_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kFloat: {Float_t **val = (Float_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kDouble: {Double_t **val = (Double_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kUChar: {UChar_t **val = (UChar_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kUShort: {UShort_t **val = (UShort_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kUInt: {UInt_t **val = (UInt_t**)ladd; return Double_t((*val)[k]);}
case kOffsetP + kULong: {ULong_t **val = (ULong_t**)ladd; return Double_t((*val)[k]);}
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kOffsetP + kULong64: {Long64_t **val = (Long64_t**)ladd; return Double_t((*val)[k]);}
#else
case kOffsetP + kULong64: {ULong64_t **val = (ULong64_t**)ladd; return Double_t((*val)[k]);}
#endif
// array counter //[n]
case kCounter: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
}
return 0;
}
//______________________________________________________________________________
void TStreamerInfo::ls(Option_t *option) const
{
// List the TStreamerElement list and also the precomputed tables
printf("nStreamerInfo for class: %s, version=%dn",GetName(),fClassVersion);
if (fElements) fElements->ls(option);
for (Int_t i=0;i<fNdata;i++) {
TStreamerElement *element = (TStreamerElement*)fElem[i];
printf(" i=%2d, %-15s type=%3d, offset=%3d, len=%d, method=%ldn",i,element->GetName(),fType[i],fOffset[i],fLength[i],fMethod[i]);
}
}
//______________________________________________________________________________
Int_t TStreamerInfo::New(const char *p)
{
// fake constructor for this class.
// A fake object is created at address p
TIter next(fElements);
TStreamerElement *element;
while ((element = (TStreamerElement*)next())) {
Int_t etype = element->GetType();
if (element->GetOffset() == kMissing) continue;
//cle->GetStreamerInfo(); //necessary in case "->" is not specified
if (etype == kObjectp || etype == kAnyp) {
// if the option "->" is given in the data member comment field
// it is assumed that the object exist before reading data in.
// In this case an object must be created
if (strstr(element->GetTitle(),"->") == element->GetTitle()) {
char line[200];
char pname[100];
char clonesClass[40];
// in case of a TClonesArray, the class name of the contained objects
// must be specified
sprintf(clonesClass,"%s"," ");
if (element->GetClassPointer() == TClonesArray::Class()) {
char *bracket1 = (char*)strchr(element->GetTitle(),'(');
char *bracket2 = (char*)strchr(element->GetTitle(),')');
if (bracket1 && bracket2) {
clonesClass[0] = '"';
strncat(clonesClass,bracket1+1,bracket2-bracket1-1);
strcat(clonesClass,""");
}
}
// object is created via the interpreter
sprintf(pname,"R__%s_%s",GetName(),element->GetName());
sprintf(line,"%s* %s = (%s*)0x%lx; *%s = new %s(%s);",
element->GetTypeName(),pname,element->GetTypeName(),
(Long_t)((char*)p + element->GetOffset()),pname,
element->GetClassPointer()->GetName(),clonesClass);
gROOT->ProcessLine(line);
}
}
if (etype == kObject || etype == kAny || etype == kBase ||
etype == kTObject || etype == kTString || etype == kTNamed) {
TClass *cle = element->GetClassPointer();
if (!cle) continue;
cle->New((char*)p + element->GetOffset());
}
}
return 0;
}
//______________________________________________________________________________
void TStreamerInfo::Optimize(Bool_t opt)
{
// This is a static function.
// Set optimization option.
// When this option is activated (default), consecutive data members
// of the same type are merged into an array (faster).
// Optimization must be off in TTree split mode.
fgOptimize = opt;
}
//______________________________________________________________________________
void TStreamerInfo::PrintValue(const char *name, char *pointer, Int_t i, Int_t len) const
{
// print value of element i in object at pointer
// The function may be called in two ways:
// -method1 len < 0
// i is assumed to be the TStreamerElement number i in StreamerInfo
// -method2 len >= 0
// i is the type
// address of variable is directly pointer.
// len is the number of elements to be printed starting at pointer.
printf(" %-15s = ",name);
Int_t j;
char *ladd;
Int_t atype,aleng;
if (len >= 0) {
ladd = pointer;
atype = i;
aleng = len;
} else {
if (i < 0) {printf("NULLn"); return;}
ladd = pointer + fOffset[i];
atype = fType[i];
aleng = fLength[i];
}
TStreamerElement * aElement = (TStreamerElement*)fElem[i];
switch (atype) {
// basic types
case kChar: {Char_t *val = (Char_t*)ladd; printf("%d",*val); break;}
case kShort: {Short_t *val = (Short_t*)ladd; printf("%d",*val); break;}
case kInt: {Int_t *val = (Int_t*)ladd; printf("%d",*val); break;}
case kLong: {Long_t *val = (Long_t*)ladd; printf("%ld",*val); break;}
case kLong64: {Long64_t *val = (Long64_t*)ladd; printf("%lld",*val); break;}
case kFloat: {Float_t *val = (Float_t*)ladd; printf("%f",*val); break;}
case kDouble: {Double_t *val = (Double_t*)ladd; printf("%g",*val); break;}
case kUChar: {UChar_t *val = (UChar_t*)ladd; printf("%u",*val); break;}
case kUShort: {UShort_t *val = (UShort_t*)ladd; printf("%u",*val); break;}
case kUInt: {UInt_t *val = (UInt_t*)ladd; printf("%u",*val); break;}
case kULong: {ULong_t *val = (ULong_t*)ladd; printf("%lu",*val); break;}
case kULong64: {ULong64_t *val = (ULong64_t*)ladd; printf("%llu",*val); break;}
case kBits: {UInt_t *val = (UInt_t*)ladd; printf("%d",*val); break;}
// array of basic types array[8]
case kOffsetL + kChar: {Char_t *val = (Char_t*)ladd; for(j=0;j<aleng;j++) printf("%d", val[j]); break; }
case kOffsetL + kShort: {Short_t *val = (Short_t*)ladd; for(j=0;j<aleng;j++) printf("%d ",val[j]); break;}
case kOffsetL + kInt: {Int_t *val = (Int_t*)ladd; for(j=0;j<aleng;j++) printf("%d ",val[j]); break;}
case kOffsetL + kLong: {Long_t *val = (Long_t*)ladd; for(j=0;j<aleng;j++) printf("%ld ",val[j]); break;}
case kOffsetL + kLong64: {Long64_t *val = (Long64_t*)ladd; for(j=0;j<aleng;j++) printf("%lld ",val[j]); break;}
case kOffsetL + kFloat: {Float_t *val = (Float_t*)ladd; for(j=0;j<aleng;j++) printf("%f ",val[j]); break;}
case kOffsetL + kDouble: {Double_t *val = (Double_t*)ladd; for(j=0;j<aleng;j++) printf("%g ",val[j]); break;}
case kOffsetL + kUChar: {UChar_t *val = (UChar_t*)ladd; for(j=0;j<aleng;j++) printf("%u ",val[j]); break;}
case kOffsetL + kUShort: {UShort_t *val = (UShort_t*)ladd; for(j=0;j<aleng;j++) printf("%u ",val[j]); break;}
case kOffsetL + kUInt: {UInt_t *val = (UInt_t*)ladd; for(j=0;j<aleng;j++) printf("%u ",val[j]); break;}
case kOffsetL + kULong: {ULong_t *val = (ULong_t*)ladd; for(j=0;j<aleng;j++) printf("%lu ",val[j]); break;}
case kOffsetL + kULong64: {ULong64_t *val = (ULong64_t*)ladd; for(j=0;j<aleng;j++) printf("%llu ",val[j]); break;}
// pointer to an array of basic types array[n]
case kOffsetP + kChar: {Char_t **val = (Char_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kShort: {Short_t **val = (Short_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kInt: {Int_t **val = (Int_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kLong: {Long_t **val = (Long_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%ld ",(*val)[j]); break;}
case kOffsetP + kLong64: {Long64_t **val = (Long64_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%lld ",(*val)[j]); break;}
case kOffsetP + kFloat: {Float_t **val = (Float_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%f ",(*val)[j]); break;}
case kOffsetP + kDouble: {Double_t **val = (Double_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%g ",(*val)[j]); break;}
case kOffsetP + kUChar: {UChar_t **val = (UChar_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kUShort: {UShort_t **val = (UShort_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kUInt: {UInt_t **val = (UInt_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kULong: {ULong_t **val = (ULong_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%lu ",(*val)[j]); break;}
case kOffsetP + kULong64: {ULong64_t **val = (ULong64_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%llu ",(*val)[j]); break;}
// array counter //[n]
case kCounter: {Int_t *val = (Int_t*)ladd; printf("%d",*val); break;}
// char *
case kCharStar: {
char **val = (char**)ladd;
if (*val) printf("%s",*val);
break;
}
// Class * derived from TObject with comment field //->
case kObjectp: {
TObject **obj = (TObject**)(pointer+fOffset[i]);
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class* derived from TObject
case kObjectP: {
TObject **obj = (TObject**)(pointer+fOffset[i]);
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class derived from TObject
case kObject: {
char *temp = pointer+fOffset[i];
TObject *obj = (TObject*)(temp+aElement->GetTObjectOffset());
printf("%s",obj->GetName());
break;
}
// Special case for TString, TObject, TNamed
case kTString: {
TString *st = (TString*)(pointer+fOffset[i]);
printf("%s",st->Data());
break;
}
case kTObject: {
TObject *obj = (TObject*)(pointer+fOffset[i]);
printf("%s",obj->GetName());
break;
}
case kTNamed: {
TNamed *named = (TNamed*) (pointer+fOffset[i]);
printf("%s/%s",named->GetName(),named->GetTitle());
break;
}
// Class * not derived from TObject with comment field //->
case kAnyp: {
TObject **obj = (TObject**)(pointer+fOffset[i]);
TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class* not derived from TObject
case kAnyP: {
TObject **obj = (TObject**)(pointer+fOffset[i]);
TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Any Class not derived from TObject
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kAny: {
printf("printing kAny case (%d)",fType[i]);
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
break;
}
//(*pstreamer)(b,pointer+fOffset[i],0);
break;
}
// Base Class
case kBase: {
printf("printing kBase case (%d)",fType[i]);
//aElement->ReadBuffer(b,pointer);
break;
}
case kOffsetL + kObject:
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {
printf("printing kStreamer case (%d)",fType[i]);
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
break;
}
//UInt_t start,count;
//b.ReadVersion(&start, &count);
//(*pstreamer)(b,pointer+fOffset[i],0);
//b.CheckByteCount(start,count,IsA());
break;
}
case kStreamLoop: {
printf("printing kStreamLoop case (%d)",fType[i]);
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
break;
}
//Int_t *counter = (Int_t*)(pointer+fMethod[i]);
//UInt_t start,count;
///b.ReadVersion(&start, &count);
//(*pstreamer)(b,pointer+fOffset[i],*counter);
//b.CheckByteCount(start,count,IsA());
break;
}
}
printf("n");
}
//______________________________________________________________________________
void TStreamerInfo::PrintValueClones(const char *name, TClonesArray *clones, Int_t i, Int_t eoffset) const
{
// print value of element i in a TClonesArray
if (!clones) {printf(" %-15s = n",name); return;}
printf(" %-15s = ",name);
Int_t nc = clones->GetEntriesFast();
const Int_t kMaxPrint = 10;
if (nc > kMaxPrint) nc = kMaxPrint;
Int_t offset = eoffset + fOffset[i];
Int_t j;
TStreamerElement *aElement = (TStreamerElement*)fElem[i];
for (Int_t k=0;k<nc;k++) {
char *pointer = (char*)clones->UncheckedAt(k);
char *ladd = pointer+offset;
switch (fType[i]) {
// basic types
case kChar: {Char_t *val = (Char_t*)ladd; printf("%d",*val); break;}
case kShort: {Short_t *val = (Short_t*)ladd; printf("%d",*val); break;}
case kInt: {Int_t *val = (Int_t*)ladd; printf("%d",*val); break;}
case kLong: {Long_t *val = (Long_t*)ladd; printf("%ld",*val); break;}
case kLong64: {Long64_t *val = (Long64_t*)ladd; printf("%lld",*val); break;}
case kFloat: {Float_t *val = (Float_t*)ladd; printf("%f",*val); break;}
case kDouble: {Double_t *val = (Double_t*)ladd; printf("%g",*val); break;}
case kUChar: {UChar_t *val = (UChar_t*)ladd; printf("%u",*val); break;}
case kUShort: {UShort_t *val = (UShort_t*)ladd; printf("%u",*val); break;}
case kUInt: {UInt_t *val = (UInt_t*)ladd; printf("%u",*val); break;}
case kULong: {ULong_t *val = (ULong_t*)ladd; printf("%lu",*val); break;}
case kULong64: {ULong64_t *val = (ULong64_t*)ladd; printf("%llu",*val); break;}
case kBits: {UInt_t *val = (UInt_t*)ladd; printf("%d",*val); break;}
// array of basic types array[8]
case kOffsetL + kChar: {Char_t *val = (Char_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kShort: {Short_t *val = (Short_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kInt: {Int_t *val = (Int_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kLong: {Long_t *val = (Long_t*)ladd; for(j=0;j<fLength[i];j++) printf("%ld ",val[j]); break;}
case kOffsetL + kLong64: {Long64_t *val = (Long64_t*)ladd; for(j=0;j<fLength[i];j++) printf("%lld ",val[j]); break;}
case kOffsetL + kFloat: {Float_t *val = (Float_t*)ladd; for(j=0;j<fLength[i];j++) printf("%f ",val[j]); break;}
case kOffsetL + kDouble: {Double_t *val = (Double_t*)ladd; for(j=0;j<fLength[i];j++) printf("%g ",val[j]); break;}
case kOffsetL + kUChar: {UChar_t *val = (UChar_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kUShort: {UShort_t *val = (UShort_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kUInt: {UInt_t *val = (UInt_t*)ladd; for(j=0;j<fLength[i];j++) printf("%d ",val[j]); break;}
case kOffsetL + kULong: {ULong_t *val = (ULong_t*)ladd; for(j=0;j<fLength[i];j++) printf("%ld ",val[j]); break;}
case kOffsetL + kULong64: {ULong64_t *val = (ULong64_t*)ladd; for(j=0;j<fLength[i];j++) printf("%llu ",val[j]); break;}
// pointer to an array of basic types array[n]
case kOffsetP + kChar: {Char_t **val = (Char_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kShort: {Short_t **val = (Short_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kInt: {Int_t **val = (Int_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%d ",(*val)[j]); break;}
case kOffsetP + kLong: {Long_t **val = (Long_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%ld ",(*val)[j]); break;}
case kOffsetP + kLong64: {Long64_t **val = (Long64_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%lld ",(*val)[j]); break;}
case kOffsetP + kFloat: {Float_t **val = (Float_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%f ",(*val)[j]); break;}
case kOffsetP + kDouble: {Double_t **val = (Double_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%g ",(*val)[j]); break;}
case kOffsetP + kUChar: {UChar_t **val = (UChar_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kUShort: {UShort_t **val = (UShort_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kUInt: {UInt_t **val = (UInt_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%u ",(*val)[j]); break;}
case kOffsetP + kULong: {ULong_t **val = (ULong_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%lu ",(*val)[j]); break;}
case kOffsetP + kULong64: {ULong64_t **val = (ULong64_t**)ladd; Int_t *l = (Int_t*)(pointer+fMethod[i]); for(j=0;j<*l;j++) printf("%llu ",(*val)[j]); break;}
// array counter //[n]
case kCounter: {Int_t *val = (Int_t*)ladd; printf("%d",*val); break;}
// char *
case kCharStar: {
char **val = (char**)ladd;
if (*val) printf("%s",*val);
break;
}
// Class * derived from TObject with comment field //->
case kObjectp: {
TObject **obj = (TObject**)ladd;
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class* derived from TObject
case kObjectP: {
TObject **obj = (TObject**)ladd;
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class derived from TObject
case kObject: {
TObject *obj = (TObject*)( ((char*)ladd) + aElement->GetTObjectOffset() );
printf("%s",obj->GetName());
break;
}
// Special case for TString, TObject, TNamed
case kTString: {
TString *st = (TString*)ladd;
printf("%s",st->Data());
break;
}
case kTObject: {
TObject *obj = (TObject*)ladd;
printf("%s",obj->GetName());
break;
}
case kTNamed: {
TNamed *named = (TNamed*)ladd;
printf("%s/%s",named->GetName(),named->GetTitle());
break;
}
// Class * derived from TObject with comment field //->
case kAnyp: {
TObject **obj = (TObject**)ladd;
TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Class* derived from TObject
case kAnyP: {
TObject **obj = (TObject**)ladd;
TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
printf("(%s*)%lx",el->GetClass()->GetName(),(Long_t)(*obj));
break;
}
// Any Class not derived from TObject
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kAny: {
printf("%s",aElement->GetTypeName());
//TClass *clany = aElement->GetClassPointer();
//TStreamerInfo *infoany = clany->GetStreamerInfo();
//infoany->PrintValue();
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
break;
}
//(*pstreamer)(b,pointer+fOffset[i],0);
break;
}
// Base Class
case kBase: {
printf("printing kBase case");
//aElement->ReadBuffer(b,pointer);
break;
}
case kOffsetL + kObject:
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {
printf("printing kStreamer case");
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
aElement->ls();
break;
}
//UInt_t start,count;
//b.ReadVersion(&start, &count);
//(*pstreamer)(b,pointer+fOffset[i],0);
//b.CheckByteCount(start,count,IsA());
break;
}
case kStreamLoop: {
printf("printing kStreamLoop case");
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
break;
}
//Int_t *counter = (Int_t*)(pointer+fMethod[i]);
//UInt_t start,count;
///b.ReadVersion(&start, &count);
//(*pstreamer)(b,pointer+fOffset[i],*counter);
//b.CheckByteCount(start,count,IsA());
break;
}
}
if (k < nc-1) printf(", ");
}
printf("n");
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBuffer(TBuffer &b, char *pointer, Int_t first)
{
// Deserialize information from buffer b into object at pointer
//==========CPP macros
#define ReadBasicType(name) \
{ \
name *x=(name*)(pointer+fOffset[i]); \
b >> *x; \
break; \
}
#define ReadBasicArray(name) \
{ \
name *x=(name*)(pointer+fOffset[i]); \
b.ReadFastArray(x,fLength[i]); \
break; \
}
#define ReadBasicPointer(name) \
{ \
Char_t isArray; \
b >> isArray; \
Int_t *l = (Int_t*)(pointer+fMethod[i]); \
name **f = (name**)(pointer+fOffset[i]); \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int j; \
for(j=0;j<len;j++) { \
delete [] f[j]; \
f[j] = 0; if (*l <=0) continue; \
f[j] = new name[*l]; \
b.ReadFastArray(f[j],*l); \
} break; \
}
//============
if (!fType) {
fClass->BuildRealData(pointer);
BuildOld();
}
//loop on all active members
Int_t last;
if (first < 0) {first = 0; last = fNdata;}
else last = first+1;
for (Int_t i=first;i<last;i++) {
TStreamerElement * aElement = (TStreamerElement*)fElem[i];
fgElement = aElement;
if (gDebug > 1) {
printf("ReadBuffer, class:%s, name=%s, fType[%d]=%d, %s, bufpos=%d, pointer=%lx, offset=%dn",fClass->GetName(),aElement->GetName(),i,fType[i],aElement->ClassName(),b.Length(),(Long_t)pointer, fOffset[i]);
}
Int_t kase = fType[i];
SWIT: switch (kase) {
// read basic types
case kChar: ReadBasicType(Char_t)
case kShort: ReadBasicType(Short_t)
case kInt: ReadBasicType(Int_t)
case kLong: ReadBasicType(Long_t)
case kLong64: ReadBasicType(Long64_t)
case kFloat: ReadBasicType(Float_t)
case kDouble: ReadBasicType(Double_t)
case kUChar: ReadBasicType(UChar_t)
case kUShort: ReadBasicType(UShort_t)
case kUInt: ReadBasicType(UInt_t)
case kULong: ReadBasicType(ULong_t)
case kULong64: ReadBasicType(ULong64_t)
// read array of basic types array[8]
case kOffsetL + kChar: ReadBasicArray(Char_t)
case kOffsetL + kShort: ReadBasicArray(Short_t)
case kOffsetL + kInt: ReadBasicArray(Int_t)
case kOffsetL + kLong: ReadBasicArray(Long_t)
case kOffsetL + kLong64: ReadBasicArray(Long64_t)
case kOffsetL + kFloat: ReadBasicArray(Float_t)
case kOffsetL + kDouble: ReadBasicArray(Double_t)
case kOffsetL + kUChar: ReadBasicArray(UChar_t)
case kOffsetL + kUShort: ReadBasicArray(UShort_t)
case kOffsetL + kUInt: ReadBasicArray(UInt_t)
case kOffsetL + kULong: ReadBasicArray(ULong_t)
case kOffsetL + kULong64: ReadBasicArray(ULong64_t)
// read pointer to an array of basic types array[n]
case kOffsetP + kChar: ReadBasicPointer(Char_t)
case kOffsetP + kShort: ReadBasicPointer(Short_t)
case kOffsetP + kInt: ReadBasicPointer(Int_t)
case kOffsetP + kLong: ReadBasicPointer(Long_t)
case kOffsetP + kLong64: ReadBasicPointer(Long64_t)
case kOffsetP + kFloat: ReadBasicPointer(Float_t)
case kOffsetP + kDouble: ReadBasicPointer(Double_t)
case kOffsetP + kUChar: ReadBasicPointer(UChar_t)
case kOffsetP + kUShort: ReadBasicPointer(UShort_t)
case kOffsetP + kUInt: ReadBasicPointer(UInt_t)
case kOffsetP + kULong: ReadBasicPointer(ULong_t)
case kOffsetP + kULong64: ReadBasicPointer(ULong64_t)
// char*
case kCharStar: {
Int_t nch; b >> nch;
char **f = (char**)(pointer+fOffset[i]);
delete [] *f;
*f = 0; if (nch <=0) break;
*f = new char[nch+1];
b.ReadFastArray(*f,nch); (*f)[nch] = 0;
break;
}
// special case for TObject::fBits in case of a referenced object
case kBits: { UInt_t *x=(UInt_t*)(pointer+fOffset[i]); b >> *x;
if ((*x & kIsReferenced) != 0) {
UShort_t pidf;
b >> pidf;
TFile* file = (TFile*)b.GetParent();
TProcessID *pid = TProcessID::ReadProcessID(pidf,file);
TObject *obj = (TObject*)pointer;
UInt_t gpid = pid->GetUniqueID();
UInt_t uid = (obj->GetUniqueID() & 0xffffff) + (gpid<<24);
obj->SetUniqueID(uid);
if (pid) pid->PutObjectWithID(obj);
}
break;
}
// Class * derived from TObject with comment field //->
case kObjectp: {
char **obj = (char**)(pointer+fOffset[i]);
if (!(*obj)) {
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
*obj = (char*)el->GetClass()->New();
}
TObject *tobj = (TObject*) ( *obj + aElement->GetTObjectOffset() );
Bool_t old = gROOT->ReadingObject();
gROOT->SetReadingObject(kTRUE);
tobj->Streamer(b);
gROOT->SetReadingObject(old);
if (tobj->IsZombie()) {
delete tobj;
*obj = 0;
}
break;
}
// Class* derived from TObject
case kObjectP: { char **obj = (char**)(pointer+fOffset[i]);
TClass *cle = aElement->GetClassPointer();
for (Int_t j=0;j<fLength[i];j++) {
//delete the object or collection
if (fgCanDelete&&obj[j]) delete (TObject*)(obj[j]+aElement->GetTObjectOffset());
obj[j] = (char*) b.ReadObjectAny(cle);
}
break;
}
// array counter //[n]
case kCounter: { Int_t *x=(Int_t*)(pointer+fOffset[i]);
b >> *x;
break;
}
// Class derived from TObject
case kObject: {
TClass *cl = aElement->GetClassPointer();
if (cl->GetClassInfo()) {
TObject *tobj = (TObject*)(pointer+fOffset[i]+aElement->GetTObjectOffset());
tobj->Streamer(b);
break;
} else {
UInt_t start,count;
//We assume that the class was written with a standard streamer
//We attempt to recover if a version count was not written
Version_t v = b.ReadVersion(&start,&count);
if (count) {
cl->GetStreamerInfo(v)->ReadBuffer(b,pointer+fOffset[i],-1);
b.CheckByteCount(start,count,cl);
} else {
b.SetBufferOffset(start);
cl->GetStreamerInfo()->ReadBuffer(b,pointer+fOffset[i],-1);
}
}
break;
}
case kOffsetL + kObject: {
TFile *file = (TFile*)b.GetParent();
if (file && file->GetVersion() < 30208) {kase = kStreamer; goto SWIT;}
TClass *cl = aElement->GetClassPointer();
if (cl->GetClassInfo()) {
Int_t size = cl->Size();
TObject *obj = (TObject*)(pointer+fOffset[i]+aElement->GetTObjectOffset());
for (Int_t j=0;j<fLength[i];j++) {
obj->Streamer(b);
obj = (TObject*)((char*)obj+size);
}
break;
} else {
UInt_t start,count;
//We assume that the class was written with a standard streamer
//We attempt to recover if a version count was not written
Int_t size = cl->Size();
TObject *obj = (TObject*)(pointer+fOffset[i]);
for (Int_t j=0;j<fLength[i];j++) {
Version_t v = b.ReadVersion(&start,&count);
if (count) {
cl->GetStreamerInfo(v)->ReadBuffer(b,(char*)obj,-1);
b.CheckByteCount(start,count,cl);
} else {
b.SetBufferOffset(start);
cl->GetStreamerInfo()->ReadBuffer(b,(char*)obj,-1);
}
obj = (TObject*)((char*)obj+size);
}
}
break;
}
// Special case for TString, TObject, TNamed
case kTString: { ((TString*)(pointer+fOffset[i]))->Streamer(b); break;}
case kTObject: { ((TObject*)(pointer+fOffset[i]))->TObject::Streamer(b); break;}
case kTNamed: { ((TNamed*) (pointer+fOffset[i]))->TNamed::Streamer(b); break;}
// Any Class not derived from TObject
case kAnyp:// Class* Class not derived from TObject and with comment field //->
{
void **obj = (void**)(pointer+fOffset[i]);
if (!(*obj)) {
TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
*obj = (TObject*)el->GetClass()->New();
}
Bool_t old = gROOT->ReadingObject();
gROOT->SetReadingObject(kTRUE);
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//Note that this does not work if the class has a custom Streamer
//with no bytecount
TClass *cle = aElement->GetClassPointer();
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with ReadBuffer
// (no byte count)
if (cle == TArrayI::Class()) {TArrayI **ar = (TArrayI**)(obj); b >> *ar; break;}
if (cle == TArrayF::Class()) {TArrayF **ar = (TArrayF**)(obj); b >> *ar; break;}
if (cle == TArrayC::Class()) {TArrayC **ar = (TArrayC**)(obj); b >> *ar; break;}
if (cle == TArrayD::Class()) {TArrayD **ar = (TArrayD**)(obj); b >> *ar; break;}
if (cle == TArrayS::Class()) {TArrayS **ar = (TArrayS**)(obj); b >> *ar; break;}
if (cle == TArrayL::Class()) {TArrayL **ar = (TArrayL**)(obj); b >> *ar; break;}
}
// if (gDebug > 0) printf("WARNING, in ReadBuffer::kAnyp Streamer is nulln");
cle->ReadBuffer(b,*obj);
} else {
(*pstreamer)(b,obj,0);
}
gROOT->SetReadingObject(old);
break;
}
case kAnyP:// Class* Class not derived from TObject and with no comment field
{
char **obj = (char**)(pointer+fOffset[i]);
Streamer_t pstreamer = aElement->GetStreamer();
TClass *cle = aElement->GetClassPointer();
if (pstreamer == 0) {
//NOTE: Need a TClass::Delete ... if (fgCanDelete) delete obj[j];
if (cle->InheritsFrom(TArray::Class())) {
//Note that this does not work if the class has a custom Streamer
//with no bytecount
for (Int_t j=0;j<fLength[i];j++) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with ReadBuffer
// (no byte count)
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(obj[j]); b >> ar; break;}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(obj[j]); b >> ar; break;}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(obj[j]); b >> ar; break;}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(obj[j]); b >> ar; break;}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(obj[j]); b >> ar; break;}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(obj[j]); b >> ar; break;}
}
} else {
// if (gDebug >= 0) printf("WARNING, in ReadBuffer::kAnyP Streamer is null for %sn",cle->GetName());
for (Int_t j=0;j<fLength[i];j++) {
obj[j] = (char*)b.ReadObjectAny(cle);
}
}
} else {
// The streamer is written for the data member NOT the class
// so we do not need to worry about the loop.
//if (*obj==0) {
// NOTE should we allocated more?
//TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)fElem[i];
//*obj = (char*)el->GetClass()->New(); this is done by pstreamer
//}
(*pstreamer)(b,obj,0);
}
break;
}
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kOffsetL + kAny:
case kAny: {
char *obj = pointer+fOffset[i];
Streamer_t pstreamer = aElement->GetStreamer();
TClass *cle = aElement->GetClassPointer();
Int_t size = cle->Size();
if (pstreamer == 0) {
for(Int_t j=0; j<fLength[i]; j++) {
//Note that this does not work if the class has a custom Streamer
//with no bytecount
TClass *cle = aElement->GetClassPointer();
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with ReadBuffer
// (no byte count)
if (strchr(aElement->GetTypeName(),'*')) {
if (cle == TArrayI::Class()) {TArrayI **ar = (TArrayI**)(pointer+fOffset[i]); b >> *ar; break;}
if (cle == TArrayF::Class()) {TArrayF **ar = (TArrayF**)(pointer+fOffset[i]); b >> *ar; break;}
if (cle == TArrayC::Class()) {TArrayC **ar = (TArrayC**)(pointer+fOffset[i]); b >> *ar; break;}
if (cle == TArrayD::Class()) {TArrayD **ar = (TArrayD**)(pointer+fOffset[i]); b >> *ar; break;}
if (cle == TArrayS::Class()) {TArrayS **ar = (TArrayS**)(pointer+fOffset[i]); b >> *ar; break;}
if (cle == TArrayL::Class()) {TArrayL **ar = (TArrayL**)(pointer+fOffset[i]); b >> *ar; break;}
} else {
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(pointer+fOffset[i]); ar->Streamer(b); break;}
}
}
//if (gDebug > 0) printf("WARNING, Streamer is nulln");
cle->ReadBuffer(b,obj);
obj += size;
}
} else {
(*pstreamer)(b,obj,0);
}
break;
}
// Base Class
case kBase: { ((TStreamerBase*)aElement)->ReadBuffer(b,pointer);
break;
}
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {
Streamer_t pstreamer = aElement->GetStreamer();
UInt_t start,count;
if (fClassVersion != -1) b.ReadVersion(&start, &count);
if (pstreamer == 0) {
if (gDebug > 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
}
} else {
(*pstreamer)(b,pointer+fOffset[i],0);
}
if (fClassVersion != -1) b.CheckByteCount(start,count,IsA());
break;
}
case kStreamLoop: {
Streamer_t pstreamer = aElement->GetStreamer();
UInt_t start,count;
b.ReadVersion(&start, &count);
if (pstreamer == 0) {
if (gDebug > 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
}
} else {
Int_t *counter = (Int_t*)(pointer+fMethod[i]);
(*pstreamer)(b,pointer+fOffset[i],*counter);
}
b.CheckByteCount(start,count,IsA());
break;
}
default:
if (fType[i] >= kConv) {
ReadBufferConv(b,pointer,i,fType[i],aElement);
break;
}
if (fType[i] >= kSkip) {
ReadBufferSkip(b,pointer,i,fType[i],aElement);
break;
}
//Error("ReadBuffer","The element type %d is not supported yetn",fType[i]);
break;
}
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBufferSkip(TBuffer &b, char *pointer, Int_t i,Int_t kase, TStreamerElement *aElement)
{
// Skip elements of a class
//==========CPP macros
#define SkipBasicType(name) \
{ \
name dummy; \
b >> dummy; \
break; \
}
#define SkipBasicArray(name) \
{ \
name dummy; \
for (Int_t j=0;j<fLength[i];j++) b >> dummy; \
break; \
}
#define SkipBasicPointer(name) \
{ \
Int_t *n = (Int_t*)(pointer+fMethod[i]); \
Int_t l = b.Length(); \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
b.SetBufferOffset(l+1+(*n)*sizeof( name )*len); \
break; \
}
//============
switch (kase) {
// skip basic types
case kSkip + kChar: SkipBasicType(Char_t)
case kSkip + kShort: SkipBasicType(Short_t)
case kSkip + kInt: SkipBasicType(Int_t)
case kSkip + kLong: SkipBasicType(Long_t)
case kSkip + kLong64: SkipBasicType(Long64_t)
case kSkip + kFloat: SkipBasicType(Float_t)
case kSkip + kDouble: SkipBasicType(Double_t)
case kSkip + kUChar: SkipBasicType(UChar_t)
case kSkip + kUShort: SkipBasicType(UShort_t)
case kSkip + kUInt: SkipBasicType(UInt_t)
case kSkip + kULong: SkipBasicType(ULong_t)
case kSkip + kULong64: SkipBasicType(ULong64_t)
case kSkip + kBits: SkipBasicType(UInt_t)
// skip array of basic types array[8]
case kSkipL + kChar: SkipBasicArray(Char_t)
case kSkipL + kShort: SkipBasicArray(Short_t)
case kSkipL + kInt: SkipBasicArray(Int_t)
case kSkipL + kLong: SkipBasicArray(Long_t)
case kSkipL + kLong64: SkipBasicArray(Long64_t)
case kSkipL + kFloat: SkipBasicArray(Float_t)
case kSkipL + kDouble: SkipBasicArray(Double_t)
case kSkipL + kUChar: SkipBasicArray(UChar_t)
case kSkipL + kUShort: SkipBasicArray(UShort_t)
case kSkipL + kUInt: SkipBasicArray(UInt_t)
case kSkipL + kULong: SkipBasicArray(ULong_t)
case kSkipL + kULong64: SkipBasicArray(ULong64_t)
// skip pointer to an array of basic types array[n]
case kSkipP + kChar: SkipBasicPointer(Char_t)
case kSkipP + kShort: SkipBasicPointer(Short_t)
case kSkipP + kInt: SkipBasicPointer(Int_t)
case kSkipP + kLong: SkipBasicPointer(Long_t)
case kSkipP + kLong64: SkipBasicPointer(Long64_t)
case kSkipP + kFloat: SkipBasicPointer(Float_t)
case kSkipP + kDouble: SkipBasicPointer(Double_t)
case kSkipP + kUChar: SkipBasicPointer(UChar_t)
case kSkipP + kUShort: SkipBasicPointer(UShort_t)
case kSkipP + kUInt: SkipBasicPointer(UInt_t)
case kSkipP + kULong: SkipBasicPointer(ULong_t)
case kSkipP + kULong64: SkipBasicPointer(ULong64_t)
// skip char*
case kSkip + kCharStar: {
Int_t nch; b >> nch;
Int_t l = b.Length();
b.SetBufferOffset(l+4+nch);
break;
}
// skip Class * derived from TObject with comment field //->
case kSkip + kObjectp: {
UInt_t start, count;
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
break;
}
// skip Class* derived from TObject
case kSkip + kObjectP: {
UInt_t start, count;
for (Int_t j=0;j<fLength[i];j++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;
}
// skip array counter //[n]
case kSkip + kCounter: { Int_t dummy; b >> dummy; break;}
// skip Class derived from TObject
case kSkip + kObject: {
if (fClass == TRef::Class()) {
TRef refjunk;
refjunk.Streamer(b);
} else {
UInt_t start, count;
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;
}
// skip Special case for TString, TObject, TNamed
case kSkip + kTString: { TString s; s.Streamer(b); break;}
case kSkip + kTObject: { TObject x; x.Streamer(b); break;}
case kSkip + kTNamed: { TNamed n; n.Streamer(b); break;}
// skip Any Class not derived from TObject
case kSkip + kAnyp: {
UInt_t start, count;
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
break;
}
case kSkip + kAnyP: {
UInt_t start, count;
for (Int_t j=0;j<fLength[i];j++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;
}
case kSkip + kAny: {
UInt_t start, count;
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
break;
}
// skip Base Class
case kSkip + kBase: {
UInt_t start, count;
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
break;
}
case kSkip + kStreamLoop:
case kSkip + kStreamer: {
UInt_t start,count;
b.ReadVersion(&start,&count);
//printf("Skipping Streamer start=%d, count=%dn",start,count);
b.SetBufferOffset(start + count + sizeof(UInt_t));
break;
}
default:
//Error("ReadBuffer","The element type %d is not supported yetn",fType[i]);
break;
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBufferConv(TBuffer &b, char *pointer, Int_t i, Int_t kase, TStreamerElement *aElement)
{
// Convert elements of a class
//==========CPP macros
#define ConvBasicType(name) \
{ \
name dummy; b >> dummy; \
switch(fNewType[i]) { \
case kChar: {Char_t *x=(Char_t*)(pointer+fOffset[i]); *x = (Char_t)dummy; break;} \
case kShort: {Short_t *x=(Short_t*)(pointer+fOffset[i]); *x = (Short_t)dummy; break;} \
case kInt: {Int_t *x=(Int_t*)(pointer+fOffset[i]); *x = (Int_t)dummy; break;} \
case kLong: {Long_t *x=(Long_t*)(pointer+fOffset[i]); *x = (Long_t)dummy; break;} \
case kLong64: {Long64_t *x=(Long64_t*)(pointer+fOffset[i]); *x = (Long64_t)dummy; break;} \
case kFloat: {Float_t *x=(Float_t*)(pointer+fOffset[i]); *x = (Float_t)dummy; break;} \
case kDouble: {Double_t *x=(Double_t*)(pointer+fOffset[i]); *x = (Double_t)dummy; break;} \
case kUChar: {UChar_t *x=(UChar_t*)(pointer+fOffset[i]); *x = (UChar_t)dummy; break;} \
case kUShort: {UShort_t *x=(UShort_t*)(pointer+fOffset[i]); *x = (UShort_t)dummy; break;} \
case kUInt: {UInt_t *x=(UInt_t*)(pointer+fOffset[i]); *x = (UInt_t)dummy; break;} \
case kULong: {ULong_t *x=(ULong_t*)(pointer+fOffset[i]); *x = (ULong_t)dummy; break;} \
case kULong64: {ULong64_t *x=(ULong64_t*)(pointer+fOffset[i]); *x = (ULong64_t)dummy; break;} \
} break; \
}
#define ConvBasicArray(name) \
{ \
int len = fLength[i]; \
int newtype = fNewType[i]%20; \
switch(newtype) { \
case kChar: {Char_t **f=(Char_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Char_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kShort: {Short_t **f=(Short_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Short_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kInt: {Int_t **f=(Int_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Int_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kLong: {Long_t **f=(Long_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Long_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kLong64: {Long64_t **f=(Long64_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Long64_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kFloat: {Float_t **f=(Float_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (len <=0) printf("len=%d\n",len); \
if (fNewType[i] > 40 && len > 0) *f = new Float_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kDouble: {Double_t **f=(Double_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new Double_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUChar: {UChar_t **f=(UChar_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new UChar_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUShort: {UShort_t **f=(UShort_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new UShort_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUInt: {UInt_t **f=(UInt_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new UInt_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kULong: {ULong_t **f=(ULong_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new ULong_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kULong64: {ULong64_t **f=(ULong64_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0; \
if (fNewType[i] > 40 && len > 0) *f = new ULong64_t[len]; \
b.ReadFastArray(*f,len); break;} \
} break; \
}
#define ConvBasicPointer(name) \
{ \
Char_t isArray; \
b >> isArray; \
if (isArray == 0) break; \
Int_t *l = (Int_t*)(pointer+fMethod[i]); name dummy; \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int newtype = fNewType[i] %20; \
int j; \
switch(newtype) { \
case kChar: {Char_t **f=(Char_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Char_t[*l]; Char_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Char_t)dummy;} \
} break;} \
case kShort: {Short_t **f=(Short_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Short_t[*l]; Short_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Short_t)dummy;} \
} break;} \
case kInt: {Int_t **f=(Int_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Int_t[*l]; Int_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Int_t)dummy;} \
} break;} \
case kLong: {Long_t **f=(Long_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Long_t[*l]; Long_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Long_t)dummy;} \
} break;} \
case kLong64: {Long64_t **f=(Long64_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Long64_t[*l]; Long64_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Long64_t)dummy;} \
} break;} \
case kFloat: {Float_t **f=(Float_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Float_t[*l]; Float_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Float_t)dummy;} \
} break;} \
case kDouble: {Double_t **f=(Double_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Double_t[*l]; Double_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (Double_t)dummy;} \
} break;} \
case kUChar: {UChar_t **f=(UChar_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UChar_t[*l]; UChar_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (UChar_t)dummy;} \
} break;} \
case kUShort: {UShort_t **f=(UShort_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UShort_t[*l]; UShort_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (UShort_t)dummy;} \
} break;} \
case kUInt: {UInt_t **f=(UInt_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UInt_t[*l]; UInt_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (UInt_t)dummy;} \
} break;} \
case kULong: {ULong_t **f=(ULong_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new ULong_t[*l]; ULong_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (ULong_t)dummy;} \
} break;} \
case kULong64: {ULong64_t **f=(ULong64_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new ULong64_t[*l]; ULong64_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> dummy; af[j] = (ULong64_t)dummy;} \
} break;} \
} break; \
}
//============
switch (kase) {
// convert basic types
case kConv + kChar: ConvBasicType(Char_t)
case kConv + kShort: ConvBasicType(Short_t)
case kConv + kInt: ConvBasicType(Int_t)
case kConv + kLong: ConvBasicType(Long_t)
case kConv + kLong64: ConvBasicType(Long64_t)
case kConv + kFloat: ConvBasicType(Float_t)
case kConv + kDouble: ConvBasicType(Double_t)
case kConv + kUChar: ConvBasicType(UChar_t)
case kConv + kUShort: ConvBasicType(UShort_t)
case kConv + kUInt: ConvBasicType(UInt_t)
case kConv + kULong: ConvBasicType(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConv + kULong64: ConvBasicType(Long64_t)
#else
case kConv + kULong64: ConvBasicType(ULong64_t)
#endif
case kConv + kBits: ConvBasicType(UInt_t)
// convert array of basic types array[8]
case kConvL + kChar: ConvBasicArray(Char_t)
case kConvL + kShort: ConvBasicArray(Short_t)
case kConvL + kInt: ConvBasicArray(Int_t)
case kConvL + kLong: ConvBasicArray(Long_t)
case kConvL + kLong64: ConvBasicArray(Long64_t)
case kConvL + kFloat: ConvBasicArray(Float_t)
case kConvL + kDouble: ConvBasicArray(Double_t)
case kConvL + kUChar: ConvBasicArray(UChar_t)
case kConvL + kUShort: ConvBasicArray(UShort_t)
case kConvL + kUInt: ConvBasicArray(UInt_t)
case kConvL + kULong: ConvBasicArray(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConvL + kULong64: ConvBasicArray(Long64_t)
#else
case kConvL + kULong64: ConvBasicArray(ULong64_t)
#endif
// convert pointer to an array of basic types array[n]
case kConvP + kChar: ConvBasicPointer(Char_t)
case kConvP + kShort: ConvBasicPointer(Short_t)
case kConvP + kInt: ConvBasicPointer(Int_t)
case kConvP + kLong: ConvBasicPointer(Long_t)
case kConvP + kLong64: ConvBasicPointer(Long64_t)
case kConvP + kFloat: ConvBasicPointer(Float_t)
case kConvP + kDouble: ConvBasicPointer(Double_t)
case kConvP + kUChar: ConvBasicPointer(UChar_t)
case kConvP + kUShort: ConvBasicPointer(UShort_t)
case kConvP + kUInt: ConvBasicPointer(UInt_t)
case kConvP + kULong: ConvBasicPointer(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConvP + kULong64: ConvBasicPointer(Long64_t)
#else
case kConvP + kULong64: ConvBasicPointer(ULong64_t)
#endif
default:
//Error("ReadBuffer","The element type %d is not supported yetn",fType[i]);
break;
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBufferClones(TBuffer &b, TClonesArray *clones, Int_t nc, Int_t first, Int_t eoffset)
{
// The TClonesArray clones is deserialized from the buffer b
char *pointer=0;
UInt_t start, count;
Int_t leng,offset;
//==========CPP macros
#define ReadCBasicType(name) \
{ \
for (Int_t k=0;k<nc;k++) { \
name *x=(name*)((char*)clones->UncheckedAt(k)+offset); \
b >> *x; \
} break; \
}
#define ReadCBasicArray(name) \
{ \
for (Int_t k=0;k<nc;k++) { \
name *x=(name*)((char*)clones->UncheckedAt(k)+offset); \
b.ReadFastArray(x,leng); \
} break; \
}
#define ReadCBasicPointer(name) \
{ \
Char_t isArray; \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int j; \
for (Int_t k=0;k<nc;k++) { \
b >> isArray; \
pointer = (char*)clones->UncheckedAt(k)+eoffset; \
Int_t *l = (Int_t*)(pointer+fMethod[i]); \
name **f = (name**)(pointer+fOffset[i]); \
for(j=0;j<len;j++) { \
delete [] f[j]; \
f[j] = 0; if (*l <=0) continue; \
f[j] = new name[*l]; \
b.ReadFastArray(f[j],*l); \
} \
} break; \
}
//==========
if (!fType) {
fClass->BuildRealData();
BuildOld();
}
//loop on all active members
Int_t last;
if (first < 0) {first = 0; last = fNdata;}
else last = first+1;
for (Int_t i=first;i<last;i++) {
leng = fLength[i];
offset = eoffset + fOffset[i];
TStreamerElement *aElement = (TStreamerElement*)fElem[i];
fgElement = aElement;
if (gDebug > 1) {
printf("ReadBufferClones, class:%s, name=%s, fType[%d]=%d, offset=%d, %s, bufpos=%d, nc=%dn",fClass->GetName(),aElement->GetName(),i,fType[i],offset,aElement->ClassName(),b.Length(),nc);
}
switch (fType[i]) {
// read basic types
case kChar: ReadCBasicType(Char_t)
case kShort: ReadCBasicType(Short_t)
case kInt: ReadCBasicType(Int_t)
case kLong: ReadCBasicType(Long_t)
case kLong64: ReadCBasicType(Long64_t)
case kFloat: ReadCBasicType(Float_t)
case kDouble: ReadCBasicType(Double_t)
case kUChar: ReadCBasicType(UChar_t)
case kUShort: ReadCBasicType(UShort_t)
case kUInt: ReadCBasicType(UInt_t)
case kULong: ReadCBasicType(ULong_t)
case kULong64: ReadCBasicType(ULong64_t)
// read array of basic types array[8]
case kOffsetL + kChar: ReadCBasicArray(Char_t)
case kOffsetL + kShort: ReadCBasicArray(Short_t)
case kOffsetL + kInt: ReadCBasicArray(Int_t)
case kOffsetL + kLong: ReadCBasicArray(Long_t)
case kOffsetL + kLong64: ReadCBasicArray(Long64_t)
case kOffsetL + kFloat: ReadCBasicArray(Float_t)
case kOffsetL + kDouble: ReadCBasicArray(Double_t)
case kOffsetL + kUChar: ReadCBasicArray(UChar_t)
case kOffsetL + kUShort: ReadCBasicArray(UShort_t)
case kOffsetL + kUInt: ReadCBasicArray(UInt_t)
case kOffsetL + kULong: ReadCBasicArray(ULong_t)
case kOffsetL + kULong64: ReadCBasicArray(ULong64_t)
// read pointer to an array of basic types array[n]
case kOffsetP + kChar: ReadCBasicPointer(Char_t)
case kOffsetP + kShort: ReadCBasicPointer(Short_t)
case kOffsetP + kInt: ReadCBasicPointer(Int_t)
case kOffsetP + kLong: ReadCBasicPointer(Long_t)
case kOffsetP + kLong64: ReadCBasicPointer(Long64_t)
case kOffsetP + kFloat: ReadCBasicPointer(Float_t)
case kOffsetP + kDouble: ReadCBasicPointer(Double_t)
case kOffsetP + kUChar: ReadCBasicPointer(UChar_t)
case kOffsetP + kUShort: ReadCBasicPointer(UShort_t)
case kOffsetP + kUInt: ReadCBasicPointer(UInt_t)
case kOffsetP + kULong: ReadCBasicPointer(ULong_t)
case kOffsetP + kULong64: ReadCBasicPointer(ULong64_t)
// char*
case kCharStar: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+eoffset;
Int_t nch; b >> nch;
char **f = (char**)(pointer+fOffset[i]);
delete [] *f;
*f = 0; if (nch <=0) continue;
*f = new char[nch+1];
b.ReadFastArray(*f,nch); (*f)[nch] = 0;
}
break;
}
// special case for TObject::fBits in case of a referenced object
case kBits: {
for (Int_t k=0;k<nc;k++) {
UInt_t *x=(UInt_t*)((char*)clones->UncheckedAt(k)+offset); b >> *x;
pointer = (char*)clones->UncheckedAt(k);
if ((*x & kIsReferenced) != 0) {
UShort_t pidf;
b >> pidf;
TFile* file = (TFile*)b.GetParent();
TProcessID *pid = TProcessID::ReadProcessID(pidf,file);
if (pid) {
TObject *obj = (TObject*)pointer;
UInt_t gpid = pid->GetUniqueID();
UInt_t uid = (obj->GetUniqueID() & 0xffffff) + (gpid<<24);
obj->SetUniqueID(uid);
pid->PutObjectWithID((TObject*)pointer);
}
}
}
}
break;
// Class * Class derived from TObject and with comment field //->
case kObjectp: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
char **obj = (char**)(pointer+offset);
if (!(*obj)) {
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
*obj = (char*)el->GetClass()->New();
}
TObject *tobj = (TObject*) ( *obj + aElement->GetTObjectOffset() );
tobj->Streamer(b);
}
break;}
// Class* Class derived from TObject
case kObjectP: {
TClass *cle = aElement->GetClassPointer();
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
char **obj = (char**)(pointer+offset);
//delete the object or collection
for (Int_t j=0;j<fLength[i];j++) {
if (fgCanDelete&&obj[j]) delete (TObject*)(obj[j] + aElement->GetTObjectOffset());
obj[j] = (char*) b.ReadObjectAny(cle);
}
}
break;}
// array counter [n]
case kCounter: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
Int_t *x=(Int_t*)(pointer+offset);
b >> *x;
}
break;}
// Class derived from TObject
case kObject: {
TClass *cl = aElement->GetClassPointer();
if (cl->GetClassInfo()) {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
TObject *tobj = (TObject*)(pointer+offset + aElement->GetTObjectOffset());
tobj->Streamer(b);
}
} else {
Version_t v;
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
//We assume that the class was written with a standard streamer
//We attempt to recover if a version count was not written
v = b.ReadVersion(&start,&count);
if (count) {
cl->GetStreamerInfo(v)->ReadBuffer(b,pointer+fOffset[i],-1);
b.CheckByteCount(start,count,cl);
} else {
b.SetBufferOffset(start);
cl->GetStreamerInfo()->ReadBuffer(b,pointer+fOffset[i],-1);
}
}
}
break;}
case kOffsetL + kObject: {
TClass *cl = aElement->GetClassPointer();
Int_t size = cl->Size();
if (cl->GetClassInfo()) {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
pointer += offset;
pointer += aElement->GetTObjectOffset();
for (Int_t j=0;j<fLength[i];j++) {
((TObject*)pointer)->Streamer(b);
pointer += size;
}
}
} else {
Version_t v;
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
pointer += fOffset[i];
for (Int_t j=0;j<fLength[i];j++) {
//We assume that the class was written with a standard streamer
//We attempt to recover if a version count was not written
v = b.ReadVersion(&start,&count);
if (count) {
cl->GetStreamerInfo(v)->ReadBuffer(b,pointer,-1);
b.CheckByteCount(start,count,cl);
} else {
b.SetBufferOffset(start);
cl->GetStreamerInfo()->ReadBuffer(b,pointer,-1);
}
pointer += size;
}
}
}
break;}
// Special case for TString, TObject, TNamed
case kTString: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
((TString*)(pointer+offset))->Streamer(b);
}
break;}
case kTObject: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
((TObject*)(pointer+offset))->TObject::Streamer(b);
}
break;}
case kTNamed: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
((TNamed*) (pointer+offset))->TNamed::Streamer(b);
}
break;}
// Class * Class not derived from TObject and with comment field //->
case kAnyp: {
TClass *cle = aElement->GetClassPointer();
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer != 0) {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
void **obj = (void**)(pointer+offset);
if (!(*obj)) *obj = cle->New();
(*pstreamer)(b,obj,0);
}
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
void **obj = (void**)(pointer+offset);
if (!(*obj)) *obj = cle->New();
cle->ReadBuffer(b,*obj);
}
}
break;}
// Class* Class not derived from TObject
case kAnyP+kOffsetL:
case kAnyP: {
TClass *cle = aElement->GetClassPointer();
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer != 0) {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
void **obj = (void**)(pointer+offset);
//if (!(*obj)) *obj = cle->New(); this should be done by pstreamer!
(*pstreamer)(b,obj,0);
}
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
char **obj = (char**)(pointer+offset);
//delete the object or collection
//NOTE: Need a TClass::Delete ... if (fgCanDelete) delete obj[j];
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with ReadBuffer
for (Int_t j=0;j<fLength[i];j++) {
// (no byte count)
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(obj[j]); b >> ar; continue;}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(obj[j]); b >> ar; continue;}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(obj[j]); b >> ar; continue;}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(obj[j]); b >> ar; continue;}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(obj[j]); b >> ar; continue;}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(obj[j]); b >> ar; continue;}
}
} else {
for (Int_t j=0;j<fLength[i];j++) {
obj[j] = (char*)b.ReadObjectAny(cle);
}
}
}
}
break;}
// Any Class not derived from TObject
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kOffsetL + kAny:
case kAny: {Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
TClass *cle = aElement->GetClassPointer();
Int_t kk;
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with ReadBuffer
// (no byte count)
if (strchr(aElement->GetTypeName(),'*')) {
for (kk=0;kk<nc;kk++) {
pointer = (char*)clones->UncheckedAt(kk);
if (cle == TArrayI::Class()) {TArrayI **ar = (TArrayI**)(pointer+offset); b >> *ar;}
if (cle == TArrayF::Class()) {TArrayF **ar = (TArrayF**)(pointer+offset); b >> *ar;}
if (cle == TArrayC::Class()) {TArrayC **ar = (TArrayC**)(pointer+offset); b >> *ar;}
if (cle == TArrayD::Class()) {TArrayD **ar = (TArrayD**)(pointer+offset); b >> *ar;}
if (cle == TArrayS::Class()) {TArrayS **ar = (TArrayS**)(pointer+offset); b >> *ar;}
if (cle == TArrayL::Class()) {TArrayL **ar = (TArrayL**)(pointer+offset); b >> *ar;}
}
break;
} else {
for (kk=0;kk<nc;kk++) {
pointer = (char*)clones->UncheckedAt(kk);
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(pointer+offset); ar->Streamer(b);}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(pointer+offset); ar->Streamer(b);}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(pointer+offset); ar->Streamer(b);}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(pointer+offset); ar->Streamer(b);}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(pointer+offset); ar->Streamer(b);}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(pointer+offset); ar->Streamer(b);}
}
break;
}
}
Int_t size = cle->Size();
for (kk=0;kk<nc;kk++) {
pointer = (char*)clones->UncheckedAt(kk);
pointer += offset;
for (Int_t j=0;j<fLength[i];j++) {
cle->ReadBuffer(b,pointer);
pointer += size;
}
}
break;
}
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
(*pstreamer)(b,pointer+offset,0);
}
break;
}
// Base Class
case kBase: {
TClass *clbase = aElement->GetClassPointer();
Int_t clversion = ((TStreamerBase*)aElement)->GetBaseVersion();
clbase->GetStreamerInfo(clversion)->ReadBufferClones(b,clones,nc,-1,fOffset[i]);
//for (Int_t k=0;k<nc;k++) {
// pointer = (char*)clones->UncheckedAt(k)+baseOffset;
// aElement->ReadBuffer(b,pointer);
//}
break;}
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {Streamer_t pstreamer = aElement->GetStreamer();
UInt_t start,count;
b.ReadVersion(&start,&count);
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k);
(*pstreamer)(b,pointer+offset,0);
}
}
b.CheckByteCount(start,count,IsA());
break;
}
case kStreamLoop: {Streamer_t pstreamer = aElement->GetStreamer();
UInt_t start,count;
b.ReadVersion(&start,&count);
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+offset;
Int_t *counter = (Int_t*)(pointer+fMethod[i]);
(*pstreamer)(b,pointer+offset,*counter);
}
}
b.CheckByteCount(start,count,IsA());
break;
}
default:
if (fType[i] >= kConv) {
ReadBufferClonesConv(b,clones,nc,i,fType[i],eoffset,aElement);
break;
}
if (fType[i] >= kSkip) {
ReadBufferClonesSkip(b,clones,nc,i,fType[i],aElement);
break;
}
//Error("ReadBufferClones","The element type %d is not supported yetn",fType[i]);
break;
}
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBufferClonesSkip(TBuffer &b, TClonesArray * /*clones*/,
Int_t nc, Int_t i, Int_t kase, TStreamerElement *aElement)
{
// Skip elements in a TClonesArray
char *pointer=0;
UInt_t start, count;
//==========CPP macros
#define SkipCBasicType(name) \
{ \
name dummy; \
for (Int_t k=0;k<nc;k++) b >> dummy; \
break; \
}
#define SkipCBasicArray(name) \
{ name dummy; \
for (Int_t k=0;k<nc;k++) { \
for (Int_t j=0;j<fLength[i];j++) b >> dummy; \
} \
break; \
}
#define SkipCBasicPointer(name) \
{ \
Int_t *n = (Int_t*)(pointer+fMethod[i]); \
Int_t l = b.Length(); \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
b.SetBufferOffset(l+1+nc*(*n)*sizeof( name )*len); \
break; \
}
switch (kase) {
// skip basic types
case kSkip + kChar: SkipCBasicType(Char_t)
case kSkip + kShort: SkipCBasicType(Short_t)
case kSkip + kInt: SkipCBasicType(Int_t)
case kSkip + kLong: SkipCBasicType(Long_t)
case kSkip + kLong64: SkipCBasicType(Long64_t)
case kSkip + kFloat: SkipCBasicType(Float_t)
case kSkip + kDouble: SkipCBasicType(Double_t)
case kSkip + kUChar: SkipCBasicType(UChar_t)
case kSkip + kUShort: SkipCBasicType(UShort_t)
case kSkip + kUInt: SkipCBasicType(UInt_t)
case kSkip + kULong: SkipCBasicType(ULong_t)
case kSkip + kULong64: SkipCBasicType(ULong64_t)
case kSkip + kBits: SkipCBasicType(UInt_t)
// skip array of basic types array[8]
case kSkipL + kChar: SkipCBasicArray(Char_t)
case kSkipL + kShort: SkipCBasicArray(Short_t)
case kSkipL + kInt: SkipCBasicArray(Int_t)
case kSkipL + kLong: SkipCBasicArray(Long_t)
case kSkipL + kLong64: SkipCBasicArray(Long64_t)
case kSkipL + kFloat: SkipCBasicArray(Float_t)
case kSkipL + kDouble: SkipCBasicArray(Double_t)
case kSkipL + kUChar: SkipCBasicArray(UChar_t)
case kSkipL + kUShort: SkipCBasicArray(UShort_t)
case kSkipL + kUInt: SkipCBasicArray(UInt_t)
case kSkipL + kULong: SkipCBasicArray(ULong_t)
case kSkipL + kULong64: SkipCBasicArray(ULong64_t)
// skip pointer to an array of basic types array[n]
case kSkipP + kChar: SkipCBasicPointer(Char_t)
case kSkipP + kShort: SkipCBasicPointer(Short_t)
case kSkipP + kInt: SkipCBasicPointer(Int_t)
case kSkipP + kLong: SkipCBasicPointer(Long_t)
case kSkipP + kLong64: SkipCBasicPointer(Long64_t)
case kSkipP + kFloat: SkipCBasicPointer(Float_t)
case kSkipP + kDouble: SkipCBasicPointer(Double_t)
case kSkipP + kUChar: SkipCBasicPointer(UChar_t)
case kSkipP + kUShort: SkipCBasicPointer(UShort_t)
case kSkipP + kUInt: SkipCBasicPointer(UInt_t)
case kSkipP + kULong: SkipCBasicPointer(ULong_t)
case kSkipP + kULong64: SkipCBasicPointer(ULong64_t)
// skip char*
case kSkip + kCharStar: {
for (Int_t k=0;k<nc;k++) {
Int_t nch; b >> nch;
Int_t l = b.Length();
b.SetBufferOffset(l+4+nch);
}
break;
}
// skip Class * derived from TObject with comment field //->
case kSkip + kObjectp: {
for (Int_t k=0;k<nc;k++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;}
// skip Class* derived from TObject
case kSkip + kObjectP: {
for (Int_t k=0;k<nc;k++) {
for (Int_t j=0;j<fLength[i];j++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
}
break;}
// skip array counter //[n]
case kSkip + kCounter: {
for (Int_t k=0;k<nc;k++) {
//Int_t *counter = (Int_t*)fMethod[i];
//b >> *counter;
Int_t dummy; b >> dummy;
}
break;}
// skip Class derived from TObject
case kSkip + kObject: {
Int_t k;
if (fClass == TRef::Class()) {
TRef refjunk;
for (k=0;k<nc;k++) refjunk.Streamer(b);
} else {
for (k=0;k<nc;k++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
}
break;}
// skip Special case for TString, TObject, TNamed
case kSkip + kTString: {
TString s;
for (Int_t k=0;k<nc;k++) {
s.Streamer(b);
}
break;}
case kSkip + kTObject: {
TObject x;
for (Int_t k=0;k<nc;k++) {
x.Streamer(b);
}
break;}
case kSkip + kTNamed: {
TNamed n;
for (Int_t k=0;k<nc;k++) {
n.Streamer(b);
}
break;}
// skip Class * not derived from TObject with comment field //->
case kSkip + kAnyp: {
for (Int_t k=0;k<nc;k++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;}
// skip Class* not derived from TObject
case kSkip + kAnyP: {
for (Int_t k=0;k<nc;k++) {
for (Int_t j=0;j<fLength[i];j++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
}
break;}
// skip Any Class not derived from TObject
case kSkip + kAny: {
for (Int_t k=0;k<nc;k++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;}
// skip Base Class
case kSkip + kBase: {
for (Int_t k=0;k<nc;k++) {
b.ReadVersion(&start, &count);
b.SetBufferOffset(start+count+sizeof(UInt_t));
}
break;}
case kSkip + kStreamLoop:
case kSkip + kStreamer: {
UInt_t start,count;
b.ReadVersion(&start,&count);
b.SetBufferOffset(start + count + sizeof(UInt_t));
break;
}
default:
//Error("ReadBufferClones","The element type %d is not supported yetn",fType[i]);
break;
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::ReadBufferClonesConv(TBuffer &b, TClonesArray *clones, Int_t nc, Int_t i, Int_t kase, Int_t eoffset, TStreamerElement *aElement)
{
// Convert elements of a TClonesArray
char *pointer = 0;
#define ConvCBasicType(name) \
{ \
for (Int_t k=0;k<nc;k++) { \
pointer = (char*)clones->UncheckedAt(k)+eoffset; \
name u; \
b >> u; \
switch(fNewType[i]) { \
case kChar: {Char_t *x=(Char_t*)(pointer+fOffset[i]); *x = (Char_t)u; break;} \
case kShort: {Short_t *x=(Short_t*)(pointer+fOffset[i]); *x = (Short_t)u; break;} \
case kInt: {Int_t *x=(Int_t*)(pointer+fOffset[i]); *x = (Int_t)u; break;} \
case kLong: {Long_t *x=(Long_t*)(pointer+fOffset[i]); *x = (Long_t)u; break;} \
case kLong64: {Long64_t *x=(Long64_t*)(pointer+fOffset[i]); *x = (Long64_t)u; break;} \
case kFloat: {Float_t *x=(Float_t*)(pointer+fOffset[i]); *x = (Float_t)u; break;} \
case kDouble: {Double_t *x=(Double_t*)(pointer+fOffset[i]); *x = (Double_t)u; break;} \
case kUChar: {UChar_t *x=(UChar_t*)(pointer+fOffset[i]); *x = (UChar_t)u; break;} \
case kUShort: {UShort_t *x=(UShort_t*)(pointer+fOffset[i]); *x = (UShort_t)u; break;} \
case kUInt: {UInt_t *x=(UInt_t*)(pointer+fOffset[i]); *x = (UInt_t)u; break;} \
case kULong: {ULong_t *x=(ULong_t*)(pointer+fOffset[i]); *x = (ULong_t)u; break;} \
case kULong64: {ULong64_t *x=(ULong64_t*)(pointer+fOffset[i]); *x = (ULong64_t)u; break;} \
} \
} break; \
}
#define ConvCBasicArray(name) \
{ \
int len = fLength[i]; \
int newtype = fNewType[i] %20; \
for (Int_t k=0;k<nc;k++) { \
pointer = (char*)clones->UncheckedAt(k)+eoffset; \
switch(newtype) { \
case kChar: {Char_t **f=(Char_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Char_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kShort: {Short_t **f=(Short_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Short_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kInt: {Int_t **f=(Int_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Int_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kLong: {Long_t **f=(Long_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Long_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kLong64: {Long64_t **f=(Long64_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Long64_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kFloat: {Float_t **f=(Float_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Float_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kDouble: {Double_t **f=(Double_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new Double_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUChar: {UChar_t **f=(UChar_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new UChar_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUShort: {UShort_t **f=(UShort_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new UShort_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kUInt: {UInt_t **f=(UInt_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new UInt_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kULong: {ULong_t **f=(ULong_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new ULong_t[len]; \
b.ReadFastArray(*f,len); break;} \
case kULong64: {ULong64_t **f=(ULong64_t**)(pointer+fOffset[i]); \
delete [] *f; *f = 0;\
if (fNewType[i] > 40 && len > 0) *f = new ULong64_t[len]; \
b.ReadFastArray(*f,len); break;} \
} \
} break; \
}
#define ConvCBasicPointer(name) \
{ \
Char_t isArray; \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int j; \
name u; \
int newtype = fNewType[i] %20; \
for (Int_t k=0;k<nc;k++) { \
b >> isArray; \
pointer = (char*)clones->UncheckedAt(k)+eoffset; \
Int_t *l = (Int_t*)(pointer+fMethod[i]); \
switch(newtype) { \
case kChar: {Char_t **f=(Char_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Char_t[*l]; Char_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Char_t)u;} \
} break;} \
case kShort: {Short_t **f=(Short_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Short_t[*l]; Short_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Short_t)u;} \
} break;} \
case kInt: {Int_t **f=(Int_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Int_t[*l]; Int_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Int_t)u;} \
} break;} \
case kLong: {Long_t **f=(Long_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Long_t[*l]; Long_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Long_t)u;} \
} break;} \
case kLong64: {Long64_t **f=(Long64_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Long64_t[*l]; Long64_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Long64_t)u;} \
} break;} \
case kFloat: {Float_t **f=(Float_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Float_t[*l]; Float_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Float_t)u;} \
} break;} \
case kDouble: {Double_t **f=(Double_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new Double_t[*l]; Double_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (Double_t)u;} \
} break;} \
case kUChar: {UChar_t **f=(UChar_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UChar_t[*l]; UChar_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (UChar_t)u;} \
} break;} \
case kUShort: {UShort_t **f=(UShort_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UShort_t[*l]; UShort_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (UShort_t)u;} \
} break;} \
case kUInt: {UInt_t **f=(UInt_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new UInt_t[*l]; UInt_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (UInt_t)u;} \
} break;} \
case kULong: {ULong_t **f=(ULong_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new ULong_t[*l]; ULong_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (ULong_t)u;} \
} break;} \
case kULong64: {ULong64_t **f=(ULong64_t**)(pointer+fOffset[i]); \
for (j=0;j<len;j++) { \
delete [] f[j]; f[j] = 0; if (*l ==0) continue; \
f[j] = new ULong64_t[*l]; ULong64_t *af = f[j]; \
for (Int_t j=0;j<*l;j++) {b >> u; af[j] = (ULong64_t)u;} \
} break;} \
} \
} break; \
}
//============
switch (kase) {
// convert basic types
case kConv + kChar: ConvCBasicType(Char_t)
case kConv + kShort: ConvCBasicType(Short_t)
case kConv + kInt: ConvCBasicType(Int_t)
case kConv + kLong: ConvCBasicType(Long_t)
case kConv + kLong64: ConvCBasicType(Long64_t)
case kConv + kFloat: ConvCBasicType(Float_t)
case kConv + kDouble: ConvCBasicType(Double_t)
case kConv + kUChar: ConvCBasicType(UChar_t)
case kConv + kUShort: ConvCBasicType(UShort_t)
case kConv + kUInt: ConvCBasicType(UInt_t)
case kConv + kULong: ConvCBasicType(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConv + kULong64: ConvCBasicType(Long64_t)
#else
case kConv + kULong64: ConvCBasicType(ULong64_t)
#endif
case kConv + kBits: ConvCBasicType(UInt_t)
// convert array of basic types array[8]
case kConvL + kChar: ConvCBasicArray(Char_t)
case kConvL + kShort: ConvCBasicArray(Short_t)
case kConvL + kInt: ConvCBasicArray(Int_t)
case kConvL + kLong: ConvCBasicArray(Long_t)
case kConvL + kLong64: ConvCBasicArray(Long64_t)
case kConvL + kFloat: ConvCBasicArray(Float_t)
case kConvL + kDouble: ConvCBasicArray(Double_t)
case kConvL + kUChar: ConvCBasicArray(UChar_t)
case kConvL + kUShort: ConvCBasicArray(UShort_t)
case kConvL + kUInt: ConvCBasicArray(UInt_t)
case kConvL + kULong: ConvCBasicArray(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConvL + kULong64: ConvCBasicArray(Long64_t)
#else
case kConvL + kULong64: ConvCBasicArray(ULong64_t)
#endif
// convert pointer to an array of basic types array[n]
case kConvP + kChar: ConvCBasicPointer(Char_t)
case kConvP + kShort: ConvCBasicPointer(Short_t)
case kConvP + kInt: ConvCBasicPointer(Int_t)
case kConvP + kLong: ConvCBasicPointer(Long_t)
case kConvP + kLong64: ConvCBasicPointer(Long64_t)
case kConvP + kFloat: ConvCBasicPointer(Float_t)
case kConvP + kDouble: ConvCBasicPointer(Double_t)
case kConvP + kUChar: ConvCBasicPointer(UChar_t)
case kConvP + kUShort: ConvCBasicPointer(UShort_t)
case kConvP + kUInt: ConvCBasicPointer(UInt_t)
case kConvP + kULong: ConvCBasicPointer(ULong_t)
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
case kConvP + kULong64: ConvCBasicPointer(Long64_t)
#else
case kConvP + kULong64: ConvCBasicPointer(ULong64_t)
#endif
default:
//Error("ReadBufferClones","The element type %d is not supported yetn",fType[i]);
break;
}
return 0;
}
//______________________________________________________________________________
void TStreamerInfo::SetCanDelete(Bool_t opt)
{
// This is a static function.
// Set object delete option.
// When this option is activated (default), ReadBuffer automatically
// delete objects when a data member is a pointer to an object.
// If your constructor is not presetting pointers to 0, you must
// call this static function TStreamerInfo::SetCanDelete(kFALSE);
fgCanDelete = opt;
}
//______________________________________________________________________________
void TStreamerInfo::Streamer(TBuffer &R__b)
{
// Stream an object of class TStreamerInfo.
UInt_t R__s, R__c;
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 1) {
TStreamerInfo::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
return;
}
//====process old versions before automatic schema evolution
TNamed::Streamer(R__b);
R__b >> fCheckSum;
R__b >> fClassVersion;
R__b >> fElements;
R__b.CheckByteCount(R__s, R__c, TStreamerInfo::IsA());
} else {
TStreamerInfo::Class()->WriteBuffer(R__b,this);
}
}
//______________________________________________________________________________
void TStreamerInfo::TagFile(TFile *file)
{
// Mark the classindex of the current file as using this TStreamerInfo
if (file) {
TArrayC *cindex = file->GetClassIndex();
Int_t nindex = cindex->GetSize();
if (fNumber < 0 || fNumber >= nindex) {
Error("TagFile","StreamerInfo: %s number: %d out of range[0,%d] in file: %s",
GetName(),fNumber,nindex,file->GetName());
return;
}
if (cindex->fArray[0] > 1) return; //happens when TFile::WriteStreamerInfo is called
if (cindex->fArray[fNumber] == 0) {
cindex->fArray[0] = 1;
cindex->fArray[fNumber] = 1;
}
}
}
//______________________________________________________________________________
Int_t TStreamerInfo::WriteBuffer(TBuffer &b, char *pointer, Int_t first)
{
// The object at pointer is serialized to the buffer b
//mark this class as being used in the current file
TagFile((TFile *)b.GetParent());
//==========CPP macros
#define WriteBasicType(name) \
{ \
name *x=(name*)(pointer+fOffset[i]); \
b << *x; \
break; \
}
#define WriteBasicArray(name) \
{ \
name *x=(name*)(pointer+fOffset[i]); \
b.WriteFastArray(x,fLength[i]); \
break; \
}
#define WriteBasicPointer(name) \
{ \
Int_t *l = (Int_t*)(pointer+fMethod[i]); \
name **f = (name**)(pointer+fOffset[i]); \
name *af = *f; \
if (af && *l) b << Char_t(1); \
else {b << Char_t(0); break;}\
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int j; \
for(j=0;j<len;j++) { \
b.WriteFastArray(f[j],*l); \
} break; \
}
//==========
//loop on all active members
Int_t last;
if (first < 0) {first = 0; last = fNdata;}
else last = first+1;
for (Int_t i=first;i<last;i++) {
TStreamerElement *aElement = (TStreamerElement*)fElem[i];
if (gDebug > 1) {
printf("WriteBuffer, class:%s, name=%s, fType[%d]=%d, %s, bufpos=%d, pointer=%lx, offset=%dn",fClass->GetName(),aElement->GetName(),i,fType[i],aElement->ClassName(),b.Length(),(Long_t)pointer,fOffset[i]);
}
switch (fType[i]) {
// write basic types
case kChar: WriteBasicType(Char_t)
case kShort: WriteBasicType(Short_t)
case kInt: WriteBasicType(Int_t)
case kLong: WriteBasicType(Long_t)
case kLong64: WriteBasicType(Long64_t)
case kFloat: WriteBasicType(Float_t)
case kDouble: WriteBasicType(Double_t)
case kUChar: WriteBasicType(UChar_t)
case kUShort: WriteBasicType(UShort_t)
case kUInt: WriteBasicType(UInt_t)
case kULong: WriteBasicType(ULong_t)
case kULong64: WriteBasicType(ULong64_t)
// write array of basic types array[8]
case kOffsetL + kChar: WriteBasicArray(Char_t)
case kOffsetL + kShort: WriteBasicArray(Short_t)
case kOffsetL + kInt: WriteBasicArray(Int_t)
case kOffsetL + kLong: WriteBasicArray(Long_t)
case kOffsetL + kLong64: WriteBasicArray(Long64_t)
case kOffsetL + kFloat: WriteBasicArray(Float_t)
case kOffsetL + kDouble: WriteBasicArray(Double_t)
case kOffsetL + kUChar: WriteBasicArray(UChar_t)
case kOffsetL + kUShort: WriteBasicArray(UShort_t)
case kOffsetL + kUInt: WriteBasicArray(UInt_t)
case kOffsetL + kULong: WriteBasicArray(ULong_t)
case kOffsetL + kULong64: WriteBasicArray(ULong64_t)
// write pointer to an array of basic types array[n]
case kOffsetP + kChar: WriteBasicPointer(Char_t)
case kOffsetP + kShort: WriteBasicPointer(Short_t)
case kOffsetP + kInt: WriteBasicPointer(Int_t)
case kOffsetP + kLong: WriteBasicPointer(Long_t)
case kOffsetP + kLong64: WriteBasicPointer(Long64_t)
case kOffsetP + kFloat: WriteBasicPointer(Float_t)
case kOffsetP + kDouble: WriteBasicPointer(Double_t)
case kOffsetP + kUChar: WriteBasicPointer(UChar_t)
case kOffsetP + kUShort: WriteBasicPointer(UShort_t)
case kOffsetP + kUInt: WriteBasicPointer(UInt_t)
case kOffsetP + kULong: WriteBasicPointer(ULong_t)
case kOffsetP + kULong64: WriteBasicPointer(ULong64_t)
// char*
case kCharStar: {
Int_t nch = 0;
char **f = (char**)(pointer+fOffset[i]);
char *af = *f;
if (af) {
nch = strlen(af);
b << nch;
b.WriteFastArray(af,nch);
} else {
b << nch;
}
break;
}
// special case for TObject::fBits in case of a referenced object
case kBits: { UInt_t *x=(UInt_t*)(pointer+fOffset[i]); b << *x;
if ((*x & kIsReferenced) != 0) {
TObject *obj = (TObject*)pointer;
TProcessID *pid = TProcessID::GetProcessWithUID(obj->GetUniqueID());
UShort_t pidf = TProcessID::WriteProcessID(pid,(TFile *)b.GetParent());
b << pidf;
}
break;
}
// Class * Class derived from TObject and with comment field //->
case kObjectp: { char **obj = (char**)(pointer+fOffset[i]);
TObject *tobj;
if (!(*obj)) {
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
if (gDebug) {
Error("WriteBuffer","-> specified but pointer is null");
el->ls();
}
*obj = (char*)el->GetClass()->New();
tobj = (TObject*) ( *obj + aElement->GetTObjectOffset() );
tobj->SetBit(kZombie);
} else {
tobj = (TObject*) ( *obj + aElement->GetTObjectOffset() );
}
tobj->Streamer(b);
break;
}
// Class* Class derived from TObject
case kObjectP: { TObject **obj = (TObject**)(pointer+fOffset[i]);
TClass *cle = aElement->GetClassPointer();
//must write StreamerInfo if pointer is null
if (!(*obj)) {
TStreamerObjectPointer *elp = (TStreamerObjectPointer*)aElement;
TClass *cl = elp->GetClass();
cl->GetStreamerInfo()->ForceWriteInfo((TFile *)b.GetParent());
}
for (Int_t j=0;j<fLength[i];j++) {
b.WriteObjectAny(obj[j],cle);
}
break;
}
// array counter [n]
case kCounter: { Int_t *x=(Int_t*)(pointer+fOffset[i]);
b << x[0];
if ( i == last-1) return x[0]; // info used by TBranchElement::FillLeaves
//Int_t *counter = (Int_t*)fMethod[i];
//*counter = x[0];
break;
}
// Class derived from TObject
case kObject: { ((TObject*)(pointer+fOffset[i]+aElement->GetTObjectOffset()))->Streamer(b); break;}
case kOffsetL + kObject: {
TClass *cle = aElement->GetClassPointer();
Int_t size = cle->Size();
TObject *obj = (TObject*)(pointer+fOffset[i]+aElement->GetTObjectOffset());
for (Int_t j=0;j<fLength[i];j++) {
obj->Streamer(b);
obj = (TObject*)((char*)obj+size);
}
break;
}
// Special case for TString, TObject, TNamed
case kTString: { ((TString*)(pointer+fOffset[i]))->Streamer(b); break;}
case kTObject: { ((TObject*)(pointer+fOffset[i]))->TObject::Streamer(b); break;}
case kTNamed: { ((TNamed*) (pointer+fOffset[i]))->TNamed::Streamer(b); break;}
// Any Class not derived from TObject
case kAnyp:// Class* Class not derived from TObject and with comment field //->
{ void **obj = (void**)(pointer+fOffset[i]);
if (!(*obj)) {
TStreamerObjectPointer *el = (TStreamerObjectPointer*)fElem[i];
if (gDebug) {
Error("WriteBuffer","-> specified but pointer is null");
el->ls();
}
*obj = (TObject*)el->GetClass()->New();
}
Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//Note that this does not work if the class has a custom Streamer
//with no bytecount
TClass *cle = aElement->GetClassPointer();
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with WriteBuffer
// (no byte count)
if (cle == TArrayI::Class()) {TArrayI **ar = (TArrayI**)(obj); b << *ar; break;}
if (cle == TArrayF::Class()) {TArrayF **ar = (TArrayF**)(obj); b << *ar; break;}
if (cle == TArrayC::Class()) {TArrayC **ar = (TArrayC**)(obj); b << *ar; break;}
if (cle == TArrayD::Class()) {TArrayD **ar = (TArrayD**)(obj); b << *ar; break;}
if (cle == TArrayS::Class()) {TArrayS **ar = (TArrayS**)(obj); b << *ar; break;}
if (cle == TArrayL::Class()) {TArrayL **ar = (TArrayL**)(obj); b << *ar; break;}
}
// if (gDebug >= 0) printf("WARNING, Streamer is for Objectp nulln");
cle->WriteBuffer(b,*obj,"");
break;
}
(*pstreamer)(b,obj,0);
break;
}
case kAnyP:// Class* Class not derived from TObject and no comment
{
char **obj = (char**)(pointer+fOffset[i]);
Streamer_t pstreamer = aElement->GetStreamer();
//must write StreamerInfo if pointer is null
if (!(*obj)) {
TStreamerObjectAnyPointer *elp = (TStreamerObjectAnyPointer*)aElement;
TClass *cl = elp->GetClass();
cl->GetStreamerInfo()->ForceWriteInfo((TFile *)b.GetParent());
}
if (pstreamer != 0) {
// The streamer is written for the data member NOT the class
// so we do not need to worry about the loop.
(*pstreamer)(b,obj,0);
} else {
TClass *cle = aElement->GetClassPointer();
for (Int_t j=0;j<fLength[i];j++) {
TClass *cl_actual = cle->GetActualClass(obj[j]);
if (!cl_actual) cl_actual = cle;
//Note that this does not work if the class has a custom Streamer
//with no bytecount
if (cl_actual->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with WriteBuffer
// (no byte count)
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(obj[j]); b << ar; break;}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(obj[j]); b << ar; break;}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(obj[j]); b << ar; break;}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(obj[j]); b << ar; break;}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(obj[j]); b << ar; break;}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(obj[j]); b << ar; break;}
}
Int_t res = b.WriteObjectAny(obj[j],cle);
if (res==2) {
Warning("WriteBuffer","The actual class of %s::%s is not available. Only the "%s" part will be writtenn",
GetName(),aElement->GetName(),cle->GetName());
}
}
}
break;
}
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kOffsetL + kAny:
case kAny: {char *obj = pointer+fOffset[i];
Streamer_t pstreamer = aElement->GetStreamer();
TClass *cle = aElement->GetClassPointer();
Int_t size = cle->Size();
if (pstreamer == 0) {
for(Int_t j=0; j<fLength[i]; j++) {
//Note that this does not work if the class has a custom Streamer
//with no bytecount
if (cle->InheritsFrom(TArray::Class())) {
//special case (frequent) with TArray classes
//The TArray Streamers not compatible with WriteBuffer
// (no byte count)
if (strchr(aElement->GetTypeName(),'*')) {
if (cle == TArrayI::Class()) {TArrayI **ar = (TArrayI**)(pointer+fOffset[i]); b << *ar; break;}
if (cle == TArrayF::Class()) {TArrayF **ar = (TArrayF**)(pointer+fOffset[i]); b << *ar; break;}
if (cle == TArrayC::Class()) {TArrayC **ar = (TArrayC**)(pointer+fOffset[i]); b << *ar; break;}
if (cle == TArrayD::Class()) {TArrayD **ar = (TArrayD**)(pointer+fOffset[i]); b << *ar; break;}
if (cle == TArrayS::Class()) {TArrayS **ar = (TArrayS**)(pointer+fOffset[i]); b << *ar; break;}
if (cle == TArrayL::Class()) {TArrayL **ar = (TArrayL**)(pointer+fOffset[i]); b << *ar; break;}
} else {
if (cle == TArrayI::Class()) {TArrayI *ar = (TArrayI*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayF::Class()) {TArrayF *ar = (TArrayF*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayC::Class()) {TArrayC *ar = (TArrayC*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayD::Class()) {TArrayD *ar = (TArrayD*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayS::Class()) {TArrayS *ar = (TArrayS*)(pointer+fOffset[i]); ar->Streamer(b); break;}
if (cle == TArrayL::Class()) {TArrayL *ar = (TArrayL*)(pointer+fOffset[i]); ar->Streamer(b); break;}
}
}
if (gDebug > 0) printf("WARNING, Streamer is nulln");
cle->WriteBuffer(b,obj,"");
obj += size;
}
// if (gDebug >= 0) printf("WARNING, Streamer is null for %sn",cle->GetName());
//cle->WriteBuffer(b,pointer+fOffset[i],"");
//break;
} else {
(*pstreamer)(b,obj,0);
}
break;
}
// Base Class
case kBase: { ((TStreamerBase*)aElement)->WriteBuffer(b,pointer);
break;
}
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {Streamer_t pstreamer = aElement->GetStreamer();
UInt_t pos = b.WriteVersion(IsA(),kTRUE);
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
} else {
(*pstreamer)(b,pointer+fOffset[i],0);
}
b.SetByteCount(pos,kTRUE);
break;
}
case kStreamLoop: {
Streamer_t pstreamer = aElement->GetStreamer();
UInt_t pos = b.WriteVersion(IsA(),kTRUE);
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
} else {
Int_t *counter = (Int_t*)(pointer+fMethod[i]);
(*pstreamer)(b,pointer+fOffset[i],*counter);
}
b.SetByteCount(pos,kTRUE);
break;
}
default:
//Error("WriteBuffer","The element type %d is not supported yetn",fType[i]);
break;
}
}
return 0;
}
//______________________________________________________________________________
Int_t TStreamerInfo::WriteBufferClones(TBuffer &b, TClonesArray *clones, Int_t nc, Int_t first, Int_t eoffset)
{
// The TClonesArray clones is serialized to the buffer b
//mark this class as being used in the current file
TagFile((TFile *)b.GetParent());
char *pointer;
//==========CPP macros
#define WriteCBasicType(name) \
{ \
for (Int_t k=0;k<nc;k++) { \
pointer = (char*)clones->UncheckedAt(k)+baseOffset; \
name *x = (name*)(pointer+fOffset[i]); \
b << *x; \
} \
break; \
}
#define WriteCBasicArray(name) \
{ \
for (Int_t k=0;k<nc;k++) { \
pointer = (char*)clones->UncheckedAt(k)+baseOffset; \
name *x = (name*)(pointer+fOffset[i]); \
b.WriteFastArray(x,fLength[i]); \
} \
break; \
}
#define WriteCBasicPointer(name) \
{ \
int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
int j; \
for (Int_t k=0;k<nc;k++) { \
pointer = (char*)clones->UncheckedAt(k)+baseOffset; \
Int_t *l = (Int_t*)(pointer+fMethod[i]); \
name **f = (name**)(pointer+fOffset[i]); \
name *af = *f; \
if (af && *l) b << Char_t(1); \
else {b << Char_t(0); continue;} \
for(j=0;j<len;j++) { \
b.WriteFastArray(f[j],*l); \
} \
} \
break; \
}
//==========
//loop on all active members
Int_t baseOffset = eoffset;
Int_t last;
if (first < 0) {first = 0; last = fNdata;}
else last = first+1;
for (Int_t i=first;i<last;i++) {
TStreamerElement* aElement = (TStreamerElement*)fElem[i];
if (gDebug > 1) {
printf("WriteBufferClones, class:%s, name=%s, fType[%d]=%d, %s, bufpos=%d, offset=%dn",fClass->GetName(),aElement->GetName(),i,fType[i],aElement->ClassName(),b.Length(),fOffset[i]);
}
switch (fType[i]) {
// write basic types
case kChar: WriteCBasicType(Char_t)
case kShort: WriteCBasicType(Short_t)
case kInt: WriteCBasicType(Int_t)
case kLong: WriteCBasicType(Long_t)
case kLong64: WriteCBasicType(Long64_t)
case kFloat: WriteCBasicType(Float_t)
case kDouble: WriteCBasicType(Double_t)
case kUChar: WriteCBasicType(UChar_t)
case kUShort: WriteCBasicType(UShort_t)
case kUInt: WriteCBasicType(UInt_t)
case kULong: WriteCBasicType(ULong_t)
case kULong64: WriteCBasicType(ULong64_t)
// write array of basic types array[8]
case kOffsetL + kChar: WriteCBasicArray(Char_t)
case kOffsetL + kShort: WriteCBasicArray(Short_t)
case kOffsetL + kInt: WriteCBasicArray(Int_t)
case kOffsetL + kLong: WriteCBasicArray(Long_t)
case kOffsetL + kLong64: WriteCBasicArray(Long64_t)
case kOffsetL + kFloat: WriteCBasicArray(Float_t)
case kOffsetL + kDouble: WriteCBasicArray(Double_t)
case kOffsetL + kUChar: WriteCBasicArray(UChar_t)
case kOffsetL + kUShort: WriteCBasicArray(UShort_t)
case kOffsetL + kUInt: WriteCBasicArray(UInt_t)
case kOffsetL + kULong: WriteCBasicArray(ULong_t)
case kOffsetL + kULong64: WriteCBasicArray(ULong64_t)
// write pointer to an array of basic types array[n]
case kOffsetP + kChar: WriteCBasicPointer(Char_t)
case kOffsetP + kShort: WriteCBasicPointer(Short_t)
case kOffsetP + kInt: WriteCBasicPointer(Int_t)
case kOffsetP + kLong: WriteCBasicPointer(Long_t)
case kOffsetP + kLong64: WriteCBasicPointer(Long64_t)
case kOffsetP + kFloat: WriteCBasicPointer(Float_t)
case kOffsetP + kDouble: WriteCBasicPointer(Double_t)
case kOffsetP + kUChar: WriteCBasicPointer(UChar_t)
case kOffsetP + kUShort: WriteCBasicPointer(UShort_t)
case kOffsetP + kUInt: WriteCBasicPointer(UInt_t)
case kOffsetP + kULong: WriteCBasicPointer(ULong_t)
case kOffsetP + kULong64: WriteCBasicPointer(ULong64_t)
// char*
case kCharStar: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
Int_t nch = 0;
char **f = (char**)(pointer+fOffset[i]);
char *af = *f;
if (af) {
nch = strlen(af);
b << nch;
b.WriteFastArray(af,nch);
} else {
b << nch;
}
}
break;
}
// special case for TObject::fBits in case of a referenced object
case kBits: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
UInt_t *x=(UInt_t*)(pointer+fOffset[i]); b << *x;
if ((*x & kIsReferenced) != 0) {
TObject *obj = (TObject*)pointer;
TProcessID *pid = TProcessID::GetProcessWithUID(obj->GetUniqueID());
UShort_t pidf = TProcessID::WriteProcessID(pid,(TFile *)b.GetParent());
b << pidf;
}
}
}
break;
// Class * Class derived from TObject and with comment field //->
case kObjectp: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
char **obj = (char**)(pointer+fOffset[i]);
if (*obj) {
TObject *tobj = (TObject*)( *obj + aElement->GetTObjectOffset() );
tobj->Streamer(b);
} else {
Error("WriteBufferClones","-> specified but pointer is null");
aElement->ls();
}
}
break;}
// Class* Class derived from TObject
case kObjectP: {
TClass *cle = aElement->GetClassPointer();
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
void **obj = (void**)(pointer+fOffset[i]);
for (Int_t j=0;j<fLength[i];j++) {
b.WriteObjectAny(obj[j],cle);
}
}
break;}
// array counter [n]
case kCounter: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
Int_t *x=(Int_t*)(pointer+fOffset[i]);
b << x[0];
//*counter = x[0];
}
break;}
// Class derived from TObject
case kObject: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
((TObject*)(pointer+fOffset[i]+aElement->GetTObjectOffset()))->Streamer(b);
}
break;}
case kOffsetL + kObject: {
TClass *cl = aElement->GetClassPointer();
Int_t size = cl->Size();
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
pointer += fOffset[i] + aElement->GetTObjectOffset();
for (Int_t j=0;j<fLength[i];j++) {
((TObject*)pointer)->Streamer(b);
pointer += size;
}
}
break;}
// Special case for TString, TObject, TNamed
case kTString: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
((TString*)(pointer+fOffset[i]))->Streamer(b);
}
break;}
case kTObject: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
((TObject*)(pointer+fOffset[i]))->TObject::Streamer(b);
}
break;}
case kTNamed: {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
((TNamed*) (pointer+fOffset[i]))->TNamed::Streamer(b);
}
break;}
// Class * Class not derived from TObject and with comment field //->
case kAnyp: {
TClass *cle = aElement->GetClassPointer();
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
TObject **obj = (TObject**)(pointer+fOffset[i]);
if (*obj) cle->WriteBuffer(b,*obj,"");
else {
Error("WriteBufferClones","-> specified but pointer is null");
aElement->ls();
}
}
break;}
// Class* Class not derived from TObject
case kAnyP+kOffsetL:
case kAnyP: {
Streamer_t pstreamer = aElement->GetStreamer();
TClass *cle = aElement->GetClassPointer();
if (pstreamer != 0) {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
void **obj = (void**)(pointer+fOffset[i]);
(*pstreamer)(b,obj,0);
}
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
char **obj = (char**)(pointer+fOffset[i]);
for (Int_t j=0;j<fLength[i];j++) {
Int_t res = b.WriteObjectAny(obj[j],cle);
if (res==2) {
Warning("WriteBuffer","The actual class of %s::%s is not available. Only the "%s" part will be writtenn",
GetName(),aElement->GetName(),cle->GetName());
}
}
}
}
break;}
// Any Class not derived from TObject
case kOffsetL + kObjectp:
case kOffsetL + kObjectP:
case kOffsetL + kAny:
case kAny: {Streamer_t pstreamer = aElement->GetStreamer();
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
TClass *cle = aElement->GetClassPointer();
Int_t size = cle->Size();
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
pointer += fOffset[i];
for (Int_t j=0;j<fLength[i];j++) {
cle->WriteBuffer(b,pointer,"");
pointer += size;
}
}
break;
}
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
(*pstreamer)(b,pointer+fOffset[i],0);
}
break;
}
// Base Class
case kBase: { TClass *clbase = aElement->GetClassPointer();
clbase->GetStreamerInfo()->WriteBufferClones(b,clones,nc,-1,fOffset[i]);
break;
}
case kOffsetL + kTString:
case kOffsetL + kTObject:
case kOffsetL + kTNamed:
case kStreamer: {
Streamer_t pstreamer = aElement->GetStreamer();
UInt_t pos = b.WriteVersion(IsA(),kTRUE);
if (pstreamer == 0) {
//printf("ERROR, Streamer is nulln");
//aElement->ls();
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
(*pstreamer)(b,pointer+fOffset[i],0);
}
}
b.SetByteCount(pos,kTRUE);
break;
}
case kStreamLoop: {
Streamer_t pstreamer = aElement->GetStreamer();
UInt_t pos = b.WriteVersion(IsA(),kTRUE);
if (pstreamer == 0) {
printf("ERROR, Streamer is nulln");
aElement->ls();
} else {
for (Int_t k=0;k<nc;k++) {
pointer = (char*)clones->UncheckedAt(k)+baseOffset;
Int_t *counter = (Int_t*)(pointer+fMethod[i]);
(*pstreamer)(b,pointer+fOffset[i],*counter);
}
}
b.SetByteCount(pos,kTRUE);
break;
}
default:
//Error("WriteBufferClones","The element type %d is not supported yetn",fType[i]);
break;
}
}
return 0;
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.